int &SPAdj);
void scavengeFrameVirtualRegs(MachineFunction &Fn);
void insertPrologEpilogCode(MachineFunction &Fn);
-
- // Convenience for recognizing return blocks.
- bool isReturnBlock(const MachineBasicBlock *MBB) const;
};
} // namespace
MachineFunctionPass::getAnalysisUsage(AU);
}
-bool PEI::isReturnBlock(const MachineBasicBlock* MBB) const {
- return (MBB && !MBB->empty() && MBB->back().isReturn());
-}
-
/// Compute the set of return blocks
void PEI::calculateSets(MachineFunction &Fn) {
const MachineFrameInfo *MFI = Fn.getFrameInfo();
// If RestoreBlock does not have any successor and is not a return block
// then the end point is unreachable and we do not need to insert any
// epilogue.
- if (!RestoreBlock->succ_empty() || isReturnBlock(RestoreBlock))
+ if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
RestoreBlocks.push_back(RestoreBlock);
return;
}
// Save refs to entry and return blocks.
- SaveBlocks.push_back(Fn.begin());
+ SaveBlocks.push_back(&Fn.front());
for (MachineBasicBlock &MBB : Fn) {
if (MBB.isEHFuncletEntry())
SaveBlocks.push_back(&MBB);
- if (isReturnBlock(&MBB))
+ if (MBB.isReturnBlock())
RestoreBlocks.push_back(&MBB);
}
}
// place all spills in the entry block, all restores in return blocks.
calculateSets(Fn);
- // Add the code to save and restore the callee saved registers
+ // Add the code to save and restore the callee saved registers.
if (!F->hasFnAttribute(Attribute::Naked))
insertCSRSpillsAndRestores(Fn);
const MachineBasicBlock *CurBB = WorkList.pop_back_val();
// By construction, the region that is after the save point is
// dominated by the Save and post-dominated by the Restore.
- if (CurBB == Save)
+ if (CurBB == Save && Save != Restore)
continue;
// Enqueue all the successors not already visited.
// Those are by construction either before Save or after Restore.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
- for (MachineBasicBlock *MBB : Visited)
+ for (MachineBasicBlock *MBB : Visited) {
+ MCPhysReg Reg = CSI[i].getReg();
// Add the callee-saved register as live-in.
// It's killed at the spill.
- MBB->addLiveIn(CSI[i].getReg());
+ if (!MBB->isLiveIn(Reg))
+ MBB->addLiveIn(Reg);
+ }
}
}
static inline void
AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx,
bool StackGrowsDown, int64_t &Offset,
- unsigned &MaxAlign) {
+ unsigned &MaxAlign, unsigned Skew) {
// If the stack grows down, add the object size to find the lowest address.
if (StackGrowsDown)
Offset += MFI->getObjectSize(FrameIdx);
MaxAlign = std::max(MaxAlign, Align);
// Adjust to alignment boundary.
- Offset = (Offset + Align - 1) / Align * Align;
+ Offset = RoundUpToAlignment(Offset, Align, Skew);
if (StackGrowsDown) {
DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n");
AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
SmallSet<int, 16> &ProtectedObjs,
MachineFrameInfo *MFI, bool StackGrowsDown,
- int64_t &Offset, unsigned &MaxAlign) {
+ int64_t &Offset, unsigned &MaxAlign, unsigned Skew) {
for (StackObjSet::const_iterator I = UnassignedObjs.begin(),
E = UnassignedObjs.end(); I != E; ++I) {
int i = *I;
- AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
+ AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign, Skew);
ProtectedObjs.insert(i);
}
}
&& "Local area offset should be in direction of stack growth");
int64_t Offset = LocalAreaOffset;
+ // Skew to be applied to alignment.
+ unsigned Skew = TFI.getStackAlignmentSkew(Fn);
+
// If there are fixed sized objects that are preallocated in the local area,
// non-fixed objects can't be allocated right at the start of local area.
// We currently don't support filling in holes in between fixed sized
unsigned Align = MFI->getObjectAlignment(i);
// Adjust to alignment boundary
- Offset = RoundUpToAlignment(Offset, Align);
+ Offset = RoundUpToAlignment(Offset, Align, Skew);
MFI->setObjectOffset(i, -Offset); // Set the computed offset
}
for (int i = MaxCSFI; i >= MinCSFI ; --i) {
unsigned Align = MFI->getObjectAlignment(i);
// Adjust to alignment boundary
- Offset = RoundUpToAlignment(Offset, Align);
+ Offset = RoundUpToAlignment(Offset, Align, Skew);
MFI->setObjectOffset(i, Offset);
Offset += MFI->getObjectSize(i);
RS->getScavengingFrameIndices(SFIs);
for (SmallVectorImpl<int>::iterator I = SFIs.begin(),
IE = SFIs.end(); I != IE; ++I)
- AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign);
+ AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign, Skew);
}
// FIXME: Once this is working, then enable flag will change to a target
unsigned Align = MFI->getLocalFrameMaxAlign();
// Adjust to alignment boundary.
- Offset = RoundUpToAlignment(Offset, Align);
+ Offset = RoundUpToAlignment(Offset, Align, Skew);
DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
StackObjSet AddrOfObjs;
AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown,
- Offset, MaxAlign);
+ Offset, MaxAlign, Skew);
// Assign large stack objects first.
for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
}
AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
- Offset, MaxAlign);
+ Offset, MaxAlign, Skew);
AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
- Offset, MaxAlign);
+ Offset, MaxAlign, Skew);
AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown,
- Offset, MaxAlign);
+ Offset, MaxAlign, Skew);
}
// Then assign frame offsets to stack objects that are not used to spill
if (ProtectedObjs.count(i))
continue;
- AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
+ AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign, Skew);
}
// Make sure the special register scavenging spill slot is closest to the
RS->getScavengingFrameIndices(SFIs);
for (SmallVectorImpl<int>::iterator I = SFIs.begin(),
IE = SFIs.end(); I != IE; ++I)
- AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign);
+ AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign, Skew);
}
if (!TFI.targetHandlesStackFrameRounding()) {
// If the frame pointer is eliminated, all frame offsets will be relative to
// SP not FP. Align to MaxAlign so this works.
StackAlign = std::max(StackAlign, MaxAlign);
- Offset = RoundUpToAlignment(Offset, StackAlign);
+ Offset = RoundUpToAlignment(Offset, StackAlign, Skew);
}
// Update frame info to pretend that this is part of the stack...
for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
TFI.emitEpilogue(Fn, *RestoreBlock);
+ for (MachineBasicBlock *SaveBlock : SaveBlocks)
+ TFI.inlineStackProbe(Fn, *SaveBlock);
+
// Emit additional code that is required to support segmented stacks, if
// we've been asked for it. This, when linked with a runtime with support
// for segmented stacks (libgcc is one), will result in allocating stack
const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering();
if (!TFI.needsFrameIndexResolution(Fn)) return;
- MachineModuleInfo &MMI = Fn.getMMI();
- const Function *F = Fn.getFunction();
- const Function *ParentF = MMI.getWinEHParent(F);
- unsigned FrameReg;
- if (F == ParentF) {
- WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn.getFunction());
- // FIXME: This should be unconditional but we have bugs in the preparation
- // pass.
- if (FuncInfo.UnwindHelpFrameIdx != INT_MAX)
- FuncInfo.UnwindHelpFrameOffset = TFI.getFrameIndexReferenceFromSP(
- Fn, FuncInfo.UnwindHelpFrameIdx, FrameReg);
- for (WinEHTryBlockMapEntry &TBME : FuncInfo.TryBlockMap) {
- for (WinEHHandlerType &H : TBME.HandlerArray) {
- unsigned UnusedReg;
- if (H.CatchObj.FrameIndex == INT_MAX)
- H.CatchObj.FrameOffset = INT_MAX;
- else
- H.CatchObj.FrameOffset =
- TFI.getFrameIndexReference(Fn, H.CatchObj.FrameIndex, UnusedReg);
- }
- }
- }
-
// Store SPAdj at exit of a basic block.
SmallVector<int, 8> SPState;
SPState.resize(Fn.getNumBlockIDs());
}
// Handle the unreachable blocks.
- for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
- if (Reachable.count(BB))
+ for (auto &BB : Fn) {
+ if (Reachable.count(&BB))
// Already handled in DFS traversal.
continue;
int SPAdj = 0;
- replaceFrameIndices(BB, Fn, SPAdj);
+ replaceFrameIndices(&BB, Fn, SPAdj);
}
}
// Run through the instructions and find any virtual registers.
for (MachineFunction::iterator BB = Fn.begin(),
E = Fn.end(); BB != E; ++BB) {
- RS->enterBasicBlock(BB);
+ RS->enterBasicBlock(&*BB);
int SPAdj = 0;
// problem because we need the spill code before I: Move I to just
// prior to J.
if (I != std::prev(J)) {
- BB->splice(J, BB, I);
+ BB->splice(J, &*BB, I);
// Before we move I, we need to prepare the RS to visit I again.
// Specifically, RS will assert if it sees uses of registers that