1*e4e14ae5SMatthias Braun //===-- MachineFrameInfo.cpp ---------------------------------------------===// 2*e4e14ae5SMatthias Braun // 3*e4e14ae5SMatthias Braun // The LLVM Compiler Infrastructure 4*e4e14ae5SMatthias Braun // 5*e4e14ae5SMatthias Braun // This file is distributed under the University of Illinois Open Source 6*e4e14ae5SMatthias Braun // License. See LICENSE.TXT for details. 7*e4e14ae5SMatthias Braun // 8*e4e14ae5SMatthias Braun //===----------------------------------------------------------------------===// 9*e4e14ae5SMatthias Braun // 10*e4e14ae5SMatthias Braun /// \file Implements MachineFrameInfo that manages the stack frame. 11*e4e14ae5SMatthias Braun // 12*e4e14ae5SMatthias Braun //===----------------------------------------------------------------------===// 13*e4e14ae5SMatthias Braun 14*e4e14ae5SMatthias Braun #include "llvm/CodeGen/MachineFrameInfo.h" 15*e4e14ae5SMatthias Braun 16*e4e14ae5SMatthias Braun #include "llvm/ADT/BitVector.h" 17*e4e14ae5SMatthias Braun #include "llvm/CodeGen/MachineFunction.h" 18*e4e14ae5SMatthias Braun #include "llvm/CodeGen/MachineRegisterInfo.h" 19*e4e14ae5SMatthias Braun #include "llvm/Support/Debug.h" 20*e4e14ae5SMatthias Braun #include "llvm/Support/raw_ostream.h" 21*e4e14ae5SMatthias Braun #include "llvm/Target/TargetFrameLowering.h" 22*e4e14ae5SMatthias Braun #include "llvm/Target/TargetRegisterInfo.h" 23*e4e14ae5SMatthias Braun #include "llvm/Target/TargetSubtargetInfo.h" 24*e4e14ae5SMatthias Braun #include <cassert> 25*e4e14ae5SMatthias Braun 26*e4e14ae5SMatthias Braun #define DEBUG_TYPE "codegen" 27*e4e14ae5SMatthias Braun 28*e4e14ae5SMatthias Braun using namespace llvm; 29*e4e14ae5SMatthias Braun 30*e4e14ae5SMatthias Braun void MachineFrameInfo::ensureMaxAlignment(unsigned Align) { 31*e4e14ae5SMatthias Braun if (!StackRealignable) 32*e4e14ae5SMatthias Braun assert(Align <= StackAlignment && 33*e4e14ae5SMatthias Braun "For targets without stack realignment, Align is out of limit!"); 34*e4e14ae5SMatthias Braun if (MaxAlignment < Align) MaxAlignment = Align; 35*e4e14ae5SMatthias Braun } 36*e4e14ae5SMatthias Braun 37*e4e14ae5SMatthias Braun /// Clamp the alignment if requested and emit a warning. 38*e4e14ae5SMatthias Braun static inline unsigned clampStackAlignment(bool ShouldClamp, unsigned Align, 39*e4e14ae5SMatthias Braun unsigned StackAlign) { 40*e4e14ae5SMatthias Braun if (!ShouldClamp || Align <= StackAlign) 41*e4e14ae5SMatthias Braun return Align; 42*e4e14ae5SMatthias Braun DEBUG(dbgs() << "Warning: requested alignment " << Align 43*e4e14ae5SMatthias Braun << " exceeds the stack alignment " << StackAlign 44*e4e14ae5SMatthias Braun << " when stack realignment is off" << '\n'); 45*e4e14ae5SMatthias Braun return StackAlign; 46*e4e14ae5SMatthias Braun } 47*e4e14ae5SMatthias Braun 48*e4e14ae5SMatthias Braun int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment, 49*e4e14ae5SMatthias Braun bool isSS, const AllocaInst *Alloca) { 50*e4e14ae5SMatthias Braun assert(Size != 0 && "Cannot allocate zero size stack objects!"); 51*e4e14ae5SMatthias Braun Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment); 52*e4e14ae5SMatthias Braun Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, Alloca, 53*e4e14ae5SMatthias Braun !isSS)); 54*e4e14ae5SMatthias Braun int Index = (int)Objects.size() - NumFixedObjects - 1; 55*e4e14ae5SMatthias Braun assert(Index >= 0 && "Bad frame index!"); 56*e4e14ae5SMatthias Braun ensureMaxAlignment(Alignment); 57*e4e14ae5SMatthias Braun return Index; 58*e4e14ae5SMatthias Braun } 59*e4e14ae5SMatthias Braun 60*e4e14ae5SMatthias Braun int MachineFrameInfo::CreateSpillStackObject(uint64_t Size, 61*e4e14ae5SMatthias Braun unsigned Alignment) { 62*e4e14ae5SMatthias Braun Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment); 63*e4e14ae5SMatthias Braun CreateStackObject(Size, Alignment, true); 64*e4e14ae5SMatthias Braun int Index = (int)Objects.size() - NumFixedObjects - 1; 65*e4e14ae5SMatthias Braun ensureMaxAlignment(Alignment); 66*e4e14ae5SMatthias Braun return Index; 67*e4e14ae5SMatthias Braun } 68*e4e14ae5SMatthias Braun 69*e4e14ae5SMatthias Braun int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment, 70*e4e14ae5SMatthias Braun const AllocaInst *Alloca) { 71*e4e14ae5SMatthias Braun HasVarSizedObjects = true; 72*e4e14ae5SMatthias Braun Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment); 73*e4e14ae5SMatthias Braun Objects.push_back(StackObject(0, Alignment, 0, false, false, Alloca, true)); 74*e4e14ae5SMatthias Braun ensureMaxAlignment(Alignment); 75*e4e14ae5SMatthias Braun return (int)Objects.size()-NumFixedObjects-1; 76*e4e14ae5SMatthias Braun } 77*e4e14ae5SMatthias Braun 78*e4e14ae5SMatthias Braun int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset, 79*e4e14ae5SMatthias Braun bool Immutable, bool isAliased) { 80*e4e14ae5SMatthias Braun assert(Size != 0 && "Cannot allocate zero size fixed stack objects!"); 81*e4e14ae5SMatthias Braun // The alignment of the frame index can be determined from its offset from 82*e4e14ae5SMatthias Braun // the incoming frame position. If the frame object is at offset 32 and 83*e4e14ae5SMatthias Braun // the stack is guaranteed to be 16-byte aligned, then we know that the 84*e4e14ae5SMatthias Braun // object is 16-byte aligned. Note that unlike the non-fixed case, if the 85*e4e14ae5SMatthias Braun // stack needs realignment, we can't assume that the stack will in fact be 86*e4e14ae5SMatthias Braun // aligned. 87*e4e14ae5SMatthias Braun unsigned Align = MinAlign(SPOffset, ForcedRealign ? 1 : StackAlignment); 88*e4e14ae5SMatthias Braun Align = clampStackAlignment(!StackRealignable, Align, StackAlignment); 89*e4e14ae5SMatthias Braun Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable, 90*e4e14ae5SMatthias Braun /*isSS*/ false, 91*e4e14ae5SMatthias Braun /*Alloca*/ nullptr, isAliased)); 92*e4e14ae5SMatthias Braun return -++NumFixedObjects; 93*e4e14ae5SMatthias Braun } 94*e4e14ae5SMatthias Braun 95*e4e14ae5SMatthias Braun int MachineFrameInfo::CreateFixedSpillStackObject(uint64_t Size, 96*e4e14ae5SMatthias Braun int64_t SPOffset, 97*e4e14ae5SMatthias Braun bool Immutable) { 98*e4e14ae5SMatthias Braun unsigned Align = MinAlign(SPOffset, ForcedRealign ? 1 : StackAlignment); 99*e4e14ae5SMatthias Braun Align = clampStackAlignment(!StackRealignable, Align, StackAlignment); 100*e4e14ae5SMatthias Braun Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable, 101*e4e14ae5SMatthias Braun /*isSS*/ true, 102*e4e14ae5SMatthias Braun /*Alloca*/ nullptr, 103*e4e14ae5SMatthias Braun /*isAliased*/ false)); 104*e4e14ae5SMatthias Braun return -++NumFixedObjects; 105*e4e14ae5SMatthias Braun } 106*e4e14ae5SMatthias Braun 107*e4e14ae5SMatthias Braun BitVector MachineFrameInfo::getPristineRegs(const MachineFunction &MF) const { 108*e4e14ae5SMatthias Braun const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 109*e4e14ae5SMatthias Braun BitVector BV(TRI->getNumRegs()); 110*e4e14ae5SMatthias Braun 111*e4e14ae5SMatthias Braun // Before CSI is calculated, no registers are considered pristine. They can be 112*e4e14ae5SMatthias Braun // freely used and PEI will make sure they are saved. 113*e4e14ae5SMatthias Braun if (!isCalleeSavedInfoValid()) 114*e4e14ae5SMatthias Braun return BV; 115*e4e14ae5SMatthias Braun 116*e4e14ae5SMatthias Braun const MachineRegisterInfo &MRI = MF.getRegInfo(); 117*e4e14ae5SMatthias Braun for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; 118*e4e14ae5SMatthias Braun ++CSR) 119*e4e14ae5SMatthias Braun BV.set(*CSR); 120*e4e14ae5SMatthias Braun 121*e4e14ae5SMatthias Braun // Saved CSRs are not pristine. 122*e4e14ae5SMatthias Braun for (auto &I : getCalleeSavedInfo()) 123*e4e14ae5SMatthias Braun for (MCSubRegIterator S(I.getReg(), TRI, true); S.isValid(); ++S) 124*e4e14ae5SMatthias Braun BV.reset(*S); 125*e4e14ae5SMatthias Braun 126*e4e14ae5SMatthias Braun return BV; 127*e4e14ae5SMatthias Braun } 128*e4e14ae5SMatthias Braun 129*e4e14ae5SMatthias Braun unsigned MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const { 130*e4e14ae5SMatthias Braun const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 131*e4e14ae5SMatthias Braun const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 132*e4e14ae5SMatthias Braun unsigned MaxAlign = getMaxAlignment(); 133*e4e14ae5SMatthias Braun int Offset = 0; 134*e4e14ae5SMatthias Braun 135*e4e14ae5SMatthias Braun // This code is very, very similar to PEI::calculateFrameObjectOffsets(). 136*e4e14ae5SMatthias Braun // It really should be refactored to share code. Until then, changes 137*e4e14ae5SMatthias Braun // should keep in mind that there's tight coupling between the two. 138*e4e14ae5SMatthias Braun 139*e4e14ae5SMatthias Braun for (int i = getObjectIndexBegin(); i != 0; ++i) { 140*e4e14ae5SMatthias Braun int FixedOff = -getObjectOffset(i); 141*e4e14ae5SMatthias Braun if (FixedOff > Offset) Offset = FixedOff; 142*e4e14ae5SMatthias Braun } 143*e4e14ae5SMatthias Braun for (unsigned i = 0, e = getObjectIndexEnd(); i != e; ++i) { 144*e4e14ae5SMatthias Braun if (isDeadObjectIndex(i)) 145*e4e14ae5SMatthias Braun continue; 146*e4e14ae5SMatthias Braun Offset += getObjectSize(i); 147*e4e14ae5SMatthias Braun unsigned Align = getObjectAlignment(i); 148*e4e14ae5SMatthias Braun // Adjust to alignment boundary 149*e4e14ae5SMatthias Braun Offset = (Offset+Align-1)/Align*Align; 150*e4e14ae5SMatthias Braun 151*e4e14ae5SMatthias Braun MaxAlign = std::max(Align, MaxAlign); 152*e4e14ae5SMatthias Braun } 153*e4e14ae5SMatthias Braun 154*e4e14ae5SMatthias Braun if (adjustsStack() && TFI->hasReservedCallFrame(MF)) 155*e4e14ae5SMatthias Braun Offset += getMaxCallFrameSize(); 156*e4e14ae5SMatthias Braun 157*e4e14ae5SMatthias Braun // Round up the size to a multiple of the alignment. If the function has 158*e4e14ae5SMatthias Braun // any calls or alloca's, align to the target's StackAlignment value to 159*e4e14ae5SMatthias Braun // ensure that the callee's frame or the alloca data is suitably aligned; 160*e4e14ae5SMatthias Braun // otherwise, for leaf functions, align to the TransientStackAlignment 161*e4e14ae5SMatthias Braun // value. 162*e4e14ae5SMatthias Braun unsigned StackAlign; 163*e4e14ae5SMatthias Braun if (adjustsStack() || hasVarSizedObjects() || 164*e4e14ae5SMatthias Braun (RegInfo->needsStackRealignment(MF) && getObjectIndexEnd() != 0)) 165*e4e14ae5SMatthias Braun StackAlign = TFI->getStackAlignment(); 166*e4e14ae5SMatthias Braun else 167*e4e14ae5SMatthias Braun StackAlign = TFI->getTransientStackAlignment(); 168*e4e14ae5SMatthias Braun 169*e4e14ae5SMatthias Braun // If the frame pointer is eliminated, all frame offsets will be relative to 170*e4e14ae5SMatthias Braun // SP not FP. Align to MaxAlign so this works. 171*e4e14ae5SMatthias Braun StackAlign = std::max(StackAlign, MaxAlign); 172*e4e14ae5SMatthias Braun unsigned AlignMask = StackAlign - 1; 173*e4e14ae5SMatthias Braun Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 174*e4e14ae5SMatthias Braun 175*e4e14ae5SMatthias Braun return (unsigned)Offset; 176*e4e14ae5SMatthias Braun } 177*e4e14ae5SMatthias Braun 178*e4e14ae5SMatthias Braun void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{ 179*e4e14ae5SMatthias Braun if (Objects.empty()) return; 180*e4e14ae5SMatthias Braun 181*e4e14ae5SMatthias Braun const TargetFrameLowering *FI = MF.getSubtarget().getFrameLowering(); 182*e4e14ae5SMatthias Braun int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0); 183*e4e14ae5SMatthias Braun 184*e4e14ae5SMatthias Braun OS << "Frame Objects:\n"; 185*e4e14ae5SMatthias Braun 186*e4e14ae5SMatthias Braun for (unsigned i = 0, e = Objects.size(); i != e; ++i) { 187*e4e14ae5SMatthias Braun const StackObject &SO = Objects[i]; 188*e4e14ae5SMatthias Braun OS << " fi#" << (int)(i-NumFixedObjects) << ": "; 189*e4e14ae5SMatthias Braun if (SO.Size == ~0ULL) { 190*e4e14ae5SMatthias Braun OS << "dead\n"; 191*e4e14ae5SMatthias Braun continue; 192*e4e14ae5SMatthias Braun } 193*e4e14ae5SMatthias Braun if (SO.Size == 0) 194*e4e14ae5SMatthias Braun OS << "variable sized"; 195*e4e14ae5SMatthias Braun else 196*e4e14ae5SMatthias Braun OS << "size=" << SO.Size; 197*e4e14ae5SMatthias Braun OS << ", align=" << SO.Alignment; 198*e4e14ae5SMatthias Braun 199*e4e14ae5SMatthias Braun if (i < NumFixedObjects) 200*e4e14ae5SMatthias Braun OS << ", fixed"; 201*e4e14ae5SMatthias Braun if (i < NumFixedObjects || SO.SPOffset != -1) { 202*e4e14ae5SMatthias Braun int64_t Off = SO.SPOffset - ValOffset; 203*e4e14ae5SMatthias Braun OS << ", at location [SP"; 204*e4e14ae5SMatthias Braun if (Off > 0) 205*e4e14ae5SMatthias Braun OS << "+" << Off; 206*e4e14ae5SMatthias Braun else if (Off < 0) 207*e4e14ae5SMatthias Braun OS << Off; 208*e4e14ae5SMatthias Braun OS << "]"; 209*e4e14ae5SMatthias Braun } 210*e4e14ae5SMatthias Braun OS << "\n"; 211*e4e14ae5SMatthias Braun } 212*e4e14ae5SMatthias Braun } 213*e4e14ae5SMatthias Braun 214*e4e14ae5SMatthias Braun #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 215*e4e14ae5SMatthias Braun LLVM_DUMP_METHOD void MachineFrameInfo::dump(const MachineFunction &MF) const { 216*e4e14ae5SMatthias Braun print(MF, dbgs()); 217*e4e14ae5SMatthias Braun } 218*e4e14ae5SMatthias Braun #endif 219