19 #define DEBUG_TYPE "pei"
50 cl::desc(
"Warn for stack size bigger than the given"
54 "Prologue/Epilogue Insertion",
false,
false)
62 STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
81 const std::vector<CalleeSavedInfo> &CSI =
89 EntryBlock = Fn.
begin();
92 if (isReturnBlock(MBB))
93 ReturnBlocks.push_back(MBB);
114 calculateCallsInformation(Fn);
122 calculateCalleeSavedRegisters(Fn);
130 insertCSRSpillsAndRestores(Fn);
137 calculateFrameObjectOffsets(Fn);
145 insertPrologEpilogCode(Fn);
150 replaceFrameIndices(Fn);
156 scavengeFrameVirtualRegs(Fn);
166 <<
") in " << Fn.
getName() <<
".\n";
169 ReturnBlocks.clear();
181 unsigned MaxCallFrameSize = 0;
190 if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1)
193 std::vector<MachineBasicBlock::iterator> FrameSDOps;
196 if (
I->getOpcode() == FrameSetupOpcode ||
197 I->getOpcode() == FrameDestroyOpcode) {
198 assert(
I->getNumOperands() >= 1 &&
"Call Frame Setup/Destroy Pseudo"
199 " instructions should have a single immediate argument!");
200 unsigned Size =
I->getOperand(0).getImm();
201 if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
203 FrameSDOps.push_back(
I);
204 }
else if (
I->isInlineAsm()) {
206 unsigned ExtraInfo =
I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
207 if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
214 for (std::vector<MachineBasicBlock::iterator>::iterator
215 i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) {
239 MinCSFrameIndex = INT_MAX;
243 if (CSRegs == 0 || CSRegs[0] == 0)
250 std::vector<CalleeSavedInfo> CSI;
251 for (
unsigned i = 0; CSRegs[i]; ++i) {
252 unsigned Reg = CSRegs[i];
263 unsigned NumFixedSpillSlots;
269 for (std::vector<CalleeSavedInfo>::iterator
270 I = CSI.begin(), E = CSI.end();
I != E; ++
I) {
271 unsigned Reg =
I->getReg();
276 I->setFrameIdx(FrameIdx);
283 while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots &&
284 FixedSlot->
Reg != Reg)
287 if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
295 Align = std::min(Align, StackAlign);
297 if ((
unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
298 if ((
unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
304 I->setFrameIdx(FrameIdx);
330 I = EntryBlock->
begin();
332 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
338 unsigned Reg = CSI[i].getReg();
346 for (
unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) {
354 while (I2 != MBB->
begin() && (--I2)->isTerminator())
357 bool AtStart = I == MBB->
begin();
365 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
366 unsigned Reg = CSI[i].getReg();
369 assert(I != MBB->
begin() &&
370 "loadRegFromStackSlot didn't insert any code!");
387 bool StackGrowsDown, int64_t &Offset,
388 unsigned &MaxAlign) {
397 MaxAlign = std::max(MaxAlign, Align);
400 Offset = (Offset + Align - 1) / Align * Align;
402 if (StackGrowsDown) {
403 DEBUG(
dbgs() <<
"alloc FI(" << FrameIdx <<
") at SP[" << -Offset <<
"]\n");
406 DEBUG(
dbgs() <<
"alloc FI(" << FrameIdx <<
") at SP[" << Offset <<
"]\n");
418 bool StackGrowsDown =
429 LocalAreaOffset = -LocalAreaOffset;
430 assert(LocalAreaOffset >= 0
431 &&
"Local area offset should be in direction of stack growth");
432 int64_t Offset = LocalAreaOffset;
441 if (StackGrowsDown) {
451 if (FixedOff > Offset) Offset = FixedOff;
456 if (StackGrowsDown) {
457 for (
unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) {
464 Offset = (Offset+Align-1)/Align*Align;
469 int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;
470 for (
int i = MaxCSFI; i >= MinCSFI ; --i) {
473 Offset = (Offset+Align-1)/Align*Align;
486 bool EarlyScavengingSlots = (TFI.
hasFP(Fn) &&
490 if (RS && EarlyScavengingSlots) {
506 Offset = (Offset + Align - 1) / Align * Align;
508 DEBUG(
dbgs() <<
"Local frame base offset: " << Offset <<
"\n");
513 int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
514 DEBUG(
dbgs() <<
"alloc FI(" << Entry.first <<
") at SP[" <<
521 MaxAlign = std::max(Align, MaxAlign);
536 if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
558 if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
566 if (LargeStackObjs.
count(i))
574 if (RS && !EarlyScavengingSlots) {
603 StackAlign = std::max(StackAlign, MaxAlign);
604 unsigned AlignMask = StackAlign - 1;
605 Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
609 int64_t StackSize = Offset - LocalAreaOffset;
611 NumBytesStackSpace += StackSize;
627 if (!I->empty() && I->back().isReturn())
664 if (DFI.getPathLength() >= 2) {
666 assert(Reachable.
count(StackPred) &&
667 "DFS stack predecessor is already visited.\n");
671 replaceFrameIndices(BB, Fn, SPAdj);
677 if (Reachable.
count(BB))
681 replaceFrameIndices(BB, Fn, SPAdj);
688 assert(TM.
getRegisterInfo() &&
"TM::getRegisterInfo() must be implemented!");
692 bool StackGrowsDown =
694 int FrameSetupOpcode = TII.getCallFrameSetupOpcode();
695 int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
701 if (I->getOpcode() == FrameSetupOpcode ||
702 I->getOpcode() == FrameDestroyOpcode) {
705 int Size = I->getOperand(0).getImm();
707 if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
708 (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
718 if (PrevI == BB->
end())
735 assert(i == 0 &&
"Frame indicies can only appear as the first "
736 "operand of a DBG_VALUE machine instruction");
753 bool AtBeginning = (I == BB->
begin());
754 if (!AtBeginning) --
I;
760 FrameIndexVirtualScavenging ? NULL : RS);
772 if (DoIncr && I != BB->
end()) ++I;
775 if (RS && !FrameIndexVirtualScavenging && MI) RS->forward(MI);
789 E = Fn.
end(); BB != E; ++BB) {
790 RS->enterBasicBlock(BB);
817 unsigned Reg = MO.
getReg();
826 "frame index virtual missing def!");
829 unsigned ScratchReg = RS->scavengeRegister(RC, J, SPAdj);
835 assert (ScratchReg &&
"Missing scratch register!");
841 RS->setUsed(ScratchReg);
858 assert(RS->getCurrentPosition() == I &&
859 "The register scavenger has an unexpected position");
unsigned getStackAlignment() const
virtual bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg, int &FrameIdx) const
virtual void adjustForHiPEPrologue(MachineFunction &MF) const
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, EVT VT=MVT::Other) const
void setCalleeSavedInfoValid(bool v)
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
static bool isVirtualRegister(unsigned Reg)
bool adjustsStack() const
void addLiveIn(unsigned Reg)
int getCallFrameSetupOpcode() const
const Function * getFunction() const
virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const
virtual const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const
bool isObjectPreAllocated(int ObjectIdx) const
void clearVirtRegs()
clearVirtRegs - Remove all virtual registers (after physreg assignment).
CallingConv::ID getCallingConv() const
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF=0) const =0
unsigned getMaxAlignment() const
Prologue Epilogue Insertion &Frame false
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
uint64_t getStackSize() const
virtual bool targetHandlesStackFrameRounding() const
int64_t getLocalFrameSize() const
getLocalFrameSize - Get the size of the local object blob.
unsigned getNumVirtRegs() const
#define INITIALIZE_PASS_DEPENDENCY(depName)
unsigned getNumBlockIDs() const
const HexagonInstrInfo * TII
bool callsUnwindInit() const
virtual bool hasFP(const MachineFunction &MF) const =0
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Abstract Stack Frame Information.
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
unsigned getNumOperands() const
int getObjectIndexBegin() const
bool count(PtrType Ptr) const
count - Return true if the specified pointer is in the set.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool hasStackObjects() const
unsigned getLocalFrameMaxAlign() const
void enterBasicBlock(MachineBasicBlock *mbb)
virtual bool useFPForScavengingIndex(const MachineFunction &MF) const
static cl::opt< unsigned > WarnStackSize("warn-stack-size", cl::Hidden, cl::init((unsigned)-1), cl::desc("Warn for stack size bigger than the given"" number"))
virtual int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const
unsigned getTransientStackAlignment() const
virtual void adjustForSegmentedStacks(MachineFunction &MF) const
virtual bool requiresRegisterScavenging(const MachineFunction &MF) const
bool isDebugValue() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
bool isReturn(QueryType Type=AnyInBundle) const
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
virtual bool needsStackRealignment(const MachineFunction &MF) const
unsigned getAlignment() const
bool getUseLocalStackAllocationBlock()
df_ext_iterator< T, SetTy > df_ext_end(const T &G, SetTy &S)
void setStackSize(uint64_t Size)
const MachineOperand & getOperand(unsigned i) const
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
df_ext_iterator< T, SetTy > df_ext_begin(const T &G, SetTy &S)
ItTy next(ItTy it, Dist n)
Prologue Epilogue Insertion &Frame false STATISTIC(NumScavengedRegs,"Number of frame index regs scavenged")
void setImm(int64_t immVal)
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
virtual void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
INITIALIZE_PASS_BEGIN(PEI,"prologepilog","Prologue/Epilogue Insertion", false, false) INITIALIZE_PASS_END(PEI
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
virtual const TargetFrameLowering * getFrameLowering() const
void getScavengingFrameIndices(SmallVectorImpl< int > &A) const
Get an array of scavenging frame indices.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
int64_t getObjectOffset(int ObjectIdx) const
bool isDeadObjectIndex(int ObjectIdx) const
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
virtual const TargetInstrInfo * getInstrInfo() const
int64_t getLocalFrameObjectCount()
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
int getOffsetOfLocalArea() const
Prologue Epilogue Insertion &Frame Finalization
unsigned getMaxCallFrameSize() const
virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const
MachineFrameInfo * getFrameInfo()
void setAdjustsStack(bool V)
bool runOnMachineFunction(MachineFunction &Fn)
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS=NULL) const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
static void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
void replaceRegWith(unsigned FromReg, unsigned ToReg)
int getStackProtectorIndex() const
char & PrologEpilogCodeInserterID
bool count(const T &V) const
count - Return true if the element is in the set.
void setCalleeSavedInfo(const std::vector< CalleeSavedInfo > &CSI)
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, bool MayNeedSP=false, const AllocaInst *Alloca=0)
StackDirection getStackGrowthDirection() const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
MachineRegisterInfo & getRegInfo()
virtual void emitPrologue(MachineFunction &MF) const =0
virtual void getAnalysisUsage(AnalysisUsage &AU) const
void setMaxCallFrameSize(unsigned S)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
bool hasVarSizedObjects() const
unsigned EnableSegmentedStacks
unsigned getReg() const
getReg - Returns the register number.
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const =0
bool isPhysRegUsed(unsigned Reg) const
BasicBlockListType::iterator iterator
ItTy prior(ItTy it, Dist n)
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=NULL) const
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
MachineModuleInfo & getMMI() const
std::pair< int, int64_t > getLocalFrameObjectMap(int i)
getLocalFrameObjectMap - Get the local offset mapping for a for an object
int getObjectIndexEnd() const
StringRef getName() const
int getCallFrameDestroyOpcode() const
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable)
always Inliner for always_inline functions
int64_t getObjectSize(int ObjectIdx) const
bool MayNeedStackProtector(int ObjectIdx) const
virtual bool isFPCloseToIncomingSP() const