12cab237bSDimitry Andric //===- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function ---===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This pass is responsible for finalizing the functions frame layout, saving
11f22ef01cSRoman Divacky // callee saved registers, and for emitting prolog & epilog code for the
12f22ef01cSRoman Divacky // function.
13f22ef01cSRoman Divacky //
14f22ef01cSRoman Divacky // This pass must be run after register allocation. After this pass is
15f22ef01cSRoman Divacky // executed, it is illegal to construct MO_FrameIndex operands.
16f22ef01cSRoman Divacky //
17f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
18f22ef01cSRoman Divacky
192cab237bSDimitry Andric #include "llvm/ADT/ArrayRef.h"
202cab237bSDimitry Andric #include "llvm/ADT/BitVector.h"
212cab237bSDimitry Andric #include "llvm/ADT/DepthFirstIterator.h"
22139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
2391bc56edSDimitry Andric #include "llvm/ADT/SetVector.h"
242cab237bSDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
25139f7f9bSDimitry Andric #include "llvm/ADT/SmallSet.h"
262cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
27139f7f9bSDimitry Andric #include "llvm/ADT/Statistic.h"
282cab237bSDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h"
292cab237bSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
30f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineDominators.h"
31f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFrameInfo.h"
322cab237bSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
332cab237bSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
34139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
35139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
36707d0cefSDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
372cab237bSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
382cab237bSDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
39f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h"
40f22ef01cSRoman Divacky #include "llvm/CodeGen/RegisterScavenging.h"
412cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
422cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
432cab237bSDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
442cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
452cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
46ff0cc061SDimitry Andric #include "llvm/CodeGen/WinEHFuncInfo.h"
472cab237bSDimitry Andric #include "llvm/IR/Attributes.h"
482cab237bSDimitry Andric #include "llvm/IR/CallingConv.h"
492cab237bSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
5091bc56edSDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
512cab237bSDimitry Andric #include "llvm/IR/Function.h"
52139f7f9bSDimitry Andric #include "llvm/IR/InlineAsm.h"
5391bc56edSDimitry Andric #include "llvm/IR/LLVMContext.h"
542cab237bSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
552cab237bSDimitry Andric #include "llvm/Pass.h"
562cab237bSDimitry Andric #include "llvm/Support/CodeGen.h"
57f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h"
58e580952dSDimitry Andric #include "llvm/Support/Debug.h"
592cab237bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
602cab237bSDimitry Andric #include "llvm/Support/MathExtras.h"
61f785676fSDimitry Andric #include "llvm/Support/raw_ostream.h"
62139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
632cab237bSDimitry Andric #include "llvm/Target/TargetOptions.h"
642cab237bSDimitry Andric #include <algorithm>
652cab237bSDimitry Andric #include <cassert>
662cab237bSDimitry Andric #include <cstdint>
672cab237bSDimitry Andric #include <functional>
682cab237bSDimitry Andric #include <limits>
692cab237bSDimitry Andric #include <utility>
702cab237bSDimitry Andric #include <vector>
71f22ef01cSRoman Divacky
72f22ef01cSRoman Divacky using namespace llvm;
73f22ef01cSRoman Divacky
74302affcbSDimitry Andric #define DEBUG_TYPE "prologepilog"
7591bc56edSDimitry Andric
762cab237bSDimitry Andric using MBBVector = SmallVector<MachineBasicBlock *, 4>;
773ca95b02SDimitry Andric
78b5893f02SDimitry Andric STATISTIC(NumLeafFuncWithSpills, "Number of leaf functions with CSRs");
79b5893f02SDimitry Andric STATISTIC(NumFuncSeen, "Number of functions seen in PEI");
80b5893f02SDimitry Andric
81b5893f02SDimitry Andric
82ff0cc061SDimitry Andric namespace {
832cab237bSDimitry Andric
84ff0cc061SDimitry Andric class PEI : public MachineFunctionPass {
85ff0cc061SDimitry Andric public:
86ff0cc061SDimitry Andric static char ID;
872cab237bSDimitry Andric
PEI()88d8866befSDimitry Andric PEI() : MachineFunctionPass(ID) {
89ff0cc061SDimitry Andric initializePEIPass(*PassRegistry::getPassRegistry());
90ff0cc061SDimitry Andric }
91ff0cc061SDimitry Andric
92ff0cc061SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override;
93ff0cc061SDimitry Andric
94ff0cc061SDimitry Andric /// runOnMachineFunction - Insert prolog/epilog code and replace abstract
95ff0cc061SDimitry Andric /// frame indexes with appropriate references.
964ba319b5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
97ff0cc061SDimitry Andric
98ff0cc061SDimitry Andric private:
99ff0cc061SDimitry Andric RegScavenger *RS;
100ff0cc061SDimitry Andric
101ff0cc061SDimitry Andric // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved
102ff0cc061SDimitry Andric // stack frame indexes.
1033ca95b02SDimitry Andric unsigned MinCSFrameIndex = std::numeric_limits<unsigned>::max();
1043ca95b02SDimitry Andric unsigned MaxCSFrameIndex = 0;
105ff0cc061SDimitry Andric
1067d523365SDimitry Andric // Save and Restore blocks of the current function. Typically there is a
1077d523365SDimitry Andric // single save block, unless Windows EH funclets are involved.
1083ca95b02SDimitry Andric MBBVector SaveBlocks;
1093ca95b02SDimitry Andric MBBVector RestoreBlocks;
110ff0cc061SDimitry Andric
111ff0cc061SDimitry Andric // Flag to control whether to use the register scavenger to resolve
112ff0cc061SDimitry Andric // frame index materialization registers. Set according to
113ff0cc061SDimitry Andric // TRI->requiresFrameIndexScavenging() for the current function.
114ff0cc061SDimitry Andric bool FrameIndexVirtualScavenging;
115ff0cc061SDimitry Andric
116d88c1a5aSDimitry Andric // Flag to control whether the scavenger should be passed even though
117d88c1a5aSDimitry Andric // FrameIndexVirtualScavenging is used.
118d88c1a5aSDimitry Andric bool FrameIndexEliminationScavenging;
119d88c1a5aSDimitry Andric
1202cab237bSDimitry Andric // Emit remarks.
1212cab237bSDimitry Andric MachineOptimizationRemarkEmitter *ORE = nullptr;
1222cab237bSDimitry Andric
1234ba319b5SDimitry Andric void calculateCallFrameInfo(MachineFunction &MF);
1244ba319b5SDimitry Andric void calculateSaveRestoreBlocks(MachineFunction &MF);
1252cab237bSDimitry Andric void spillCalleeSavedRegs(MachineFunction &MF);
1263ca95b02SDimitry Andric
1274ba319b5SDimitry Andric void calculateFrameObjectOffsets(MachineFunction &MF);
1284ba319b5SDimitry Andric void replaceFrameIndices(MachineFunction &MF);
1294ba319b5SDimitry Andric void replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
130ff0cc061SDimitry Andric int &SPAdj);
1314ba319b5SDimitry Andric void insertPrologEpilogCode(MachineFunction &MF);
132ff0cc061SDimitry Andric };
1332cab237bSDimitry Andric
1342cab237bSDimitry Andric } // end anonymous namespace
135ff0cc061SDimitry Andric
136f22ef01cSRoman Divacky char PEI::ID = 0;
1372cab237bSDimitry Andric
138dff0c46cSDimitry Andric char &llvm::PrologEpilogCodeInserterID = PEI::ID;
139f22ef01cSRoman Divacky
140f785676fSDimitry Andric static cl::opt<unsigned>
141f785676fSDimitry Andric WarnStackSize("warn-stack-size", cl::Hidden, cl::init((unsigned)-1),
142f785676fSDimitry Andric cl::desc("Warn for stack size bigger than the given"
143f785676fSDimitry Andric " number"));
144f785676fSDimitry Andric
145302affcbSDimitry Andric INITIALIZE_PASS_BEGIN(PEI, DEBUG_TYPE, "Prologue/Epilogue Insertion", false,
146d8866befSDimitry Andric false)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)1472754fe60SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
1482754fe60SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
1492cab237bSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
150302affcbSDimitry Andric INITIALIZE_PASS_END(PEI, DEBUG_TYPE,
151d8866befSDimitry Andric "Prologue/Epilogue Insertion & Frame Finalization", false,
152d8866befSDimitry Andric false)
153e580952dSDimitry Andric
154d8866befSDimitry Andric MachineFunctionPass *llvm::createPrologEpilogInserterPass() {
155d8866befSDimitry Andric return new PEI();
1563ca95b02SDimitry Andric }
1573ca95b02SDimitry Andric
1586122f3e6SDimitry Andric STATISTIC(NumBytesStackSpace,
1596122f3e6SDimitry Andric "Number of bytes used for stack in all functions");
160f22ef01cSRoman Divacky
getAnalysisUsage(AnalysisUsage & AU) const161f785676fSDimitry Andric void PEI::getAnalysisUsage(AnalysisUsage &AU) const {
162f785676fSDimitry Andric AU.setPreservesCFG();
163f785676fSDimitry Andric AU.addPreserved<MachineLoopInfo>();
164f785676fSDimitry Andric AU.addPreserved<MachineDominatorTree>();
1652cab237bSDimitry Andric AU.addRequired<MachineOptimizationRemarkEmitterPass>();
166f785676fSDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
167f785676fSDimitry Andric }
168f785676fSDimitry Andric
16991bc56edSDimitry Andric /// StackObjSet - A set of stack object indexes
1702cab237bSDimitry Andric using StackObjSet = SmallSetVector<int, 8>;
17191bc56edSDimitry Andric
172f22ef01cSRoman Divacky /// runOnMachineFunction - Insert prolog/epilog code and replace abstract
173f22ef01cSRoman Divacky /// frame indexes with appropriate references.
runOnMachineFunction(MachineFunction & MF)1744ba319b5SDimitry Andric bool PEI::runOnMachineFunction(MachineFunction &MF) {
175b5893f02SDimitry Andric NumFuncSeen++;
1764ba319b5SDimitry Andric const Function &F = MF.getFunction();
1774ba319b5SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
1784ba319b5SDimitry Andric const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
1792754fe60SDimitry Andric
1804ba319b5SDimitry Andric RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr;
1814ba319b5SDimitry Andric FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(MF);
182d88c1a5aSDimitry Andric FrameIndexEliminationScavenging = (RS && !FrameIndexVirtualScavenging) ||
1834ba319b5SDimitry Andric TRI->requiresFrameIndexReplacementScavenging(MF);
1842cab237bSDimitry Andric ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
185f22ef01cSRoman Divacky
186f22ef01cSRoman Divacky // Calculate the MaxCallFrameSize and AdjustsStack variables for the
187f22ef01cSRoman Divacky // function's frame information. Also eliminates call frame pseudo
188f22ef01cSRoman Divacky // instructions.
1894ba319b5SDimitry Andric calculateCallFrameInfo(MF);
190f22ef01cSRoman Divacky
1913ca95b02SDimitry Andric // Determine placement of CSR spill/restore code and prolog/epilog code:
192f785676fSDimitry Andric // place all spills in the entry block, all restores in return blocks.
1934ba319b5SDimitry Andric calculateSaveRestoreBlocks(MF);
194f22ef01cSRoman Divacky
1953ca95b02SDimitry Andric // Handle CSR spilling and restoring, for targets that need it.
1964ba319b5SDimitry Andric if (MF.getTarget().usesPhysRegsForPEI())
1974ba319b5SDimitry Andric spillCalleeSavedRegs(MF);
198f22ef01cSRoman Divacky
199f22ef01cSRoman Divacky // Allow the target machine to make final modifications to the function
200f22ef01cSRoman Divacky // before the frame layout is finalized.
2014ba319b5SDimitry Andric TFI->processFunctionBeforeFrameFinalized(MF, RS);
202f22ef01cSRoman Divacky
203f22ef01cSRoman Divacky // Calculate actual frame offsets for all abstract stack objects...
2044ba319b5SDimitry Andric calculateFrameObjectOffsets(MF);
205f22ef01cSRoman Divacky
206f22ef01cSRoman Divacky // Add prolog and epilog code to the function. This function is required
207f22ef01cSRoman Divacky // to align the stack frame as necessary for any stack variables or
208f22ef01cSRoman Divacky // called functions. Because of this, calculateCalleeSavedRegisters()
209f22ef01cSRoman Divacky // must be called before this function in order to set the AdjustsStack
210f22ef01cSRoman Divacky // and MaxCallFrameSize variables.
2112cab237bSDimitry Andric if (!F.hasFnAttribute(Attribute::Naked))
2124ba319b5SDimitry Andric insertPrologEpilogCode(MF);
213f22ef01cSRoman Divacky
214f22ef01cSRoman Divacky // Replace all MO_FrameIndex operands with physical register references
215f22ef01cSRoman Divacky // and actual offsets.
216f22ef01cSRoman Divacky //
2174ba319b5SDimitry Andric replaceFrameIndices(MF);
218f22ef01cSRoman Divacky
219f22ef01cSRoman Divacky // If register scavenging is needed, as we've enabled doing it as a
22091bc56edSDimitry Andric // post-pass, scavenge the virtual registers that frame index elimination
221f22ef01cSRoman Divacky // inserted.
2224ba319b5SDimitry Andric if (TRI->requiresRegisterScavenging(MF) && FrameIndexVirtualScavenging)
2234ba319b5SDimitry Andric scavengeFrameVirtualRegs(MF, *RS);
224dff0c46cSDimitry Andric
225f785676fSDimitry Andric // Warn on stack size when we exceeds the given limit.
2264ba319b5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
227d88c1a5aSDimitry Andric uint64_t StackSize = MFI.getStackSize();
22891bc56edSDimitry Andric if (WarnStackSize.getNumOccurrences() > 0 && WarnStackSize < StackSize) {
2292cab237bSDimitry Andric DiagnosticInfoStackSize DiagStackSize(F, StackSize);
2302cab237bSDimitry Andric F.getContext().diagnose(DiagStackSize);
23191bc56edSDimitry Andric }
2324ba319b5SDimitry Andric ORE->emit([&]() {
2334ba319b5SDimitry Andric return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "StackSize",
2344ba319b5SDimitry Andric MF.getFunction().getSubprogram(),
2354ba319b5SDimitry Andric &MF.front())
2364ba319b5SDimitry Andric << ore::NV("NumStackBytes", StackSize) << " stack bytes in function";
2374ba319b5SDimitry Andric });
238f785676fSDimitry Andric
239f22ef01cSRoman Divacky delete RS;
2407d523365SDimitry Andric SaveBlocks.clear();
241ff0cc061SDimitry Andric RestoreBlocks.clear();
242d88c1a5aSDimitry Andric MFI.setSavePoint(nullptr);
243d88c1a5aSDimitry Andric MFI.setRestorePoint(nullptr);
244f22ef01cSRoman Divacky return true;
245f22ef01cSRoman Divacky }
246f22ef01cSRoman Divacky
2473ca95b02SDimitry Andric /// Calculate the MaxCallFrameSize and AdjustsStack
248f22ef01cSRoman Divacky /// variables for the function's frame information and eliminate call frame
249f22ef01cSRoman Divacky /// pseudo instructions.
calculateCallFrameInfo(MachineFunction & MF)2504ba319b5SDimitry Andric void PEI::calculateCallFrameInfo(MachineFunction &MF) {
2514ba319b5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
2524ba319b5SDimitry Andric const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
2534ba319b5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
254f22ef01cSRoman Divacky
255f22ef01cSRoman Divacky unsigned MaxCallFrameSize = 0;
256d88c1a5aSDimitry Andric bool AdjustsStack = MFI.adjustsStack();
257f22ef01cSRoman Divacky
258f22ef01cSRoman Divacky // Get the function call frame set-up and tear-down instruction opcode
259ff0cc061SDimitry Andric unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
260ff0cc061SDimitry Andric unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
261f22ef01cSRoman Divacky
262f22ef01cSRoman Divacky // Early exit for targets which have no call frame setup/destroy pseudo
263f22ef01cSRoman Divacky // instructions.
264ff0cc061SDimitry Andric if (FrameSetupOpcode == ~0u && FrameDestroyOpcode == ~0u)
265f22ef01cSRoman Divacky return;
266f22ef01cSRoman Divacky
267f22ef01cSRoman Divacky std::vector<MachineBasicBlock::iterator> FrameSDOps;
2684ba319b5SDimitry Andric for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
269f22ef01cSRoman Divacky for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
2707a7e6055SDimitry Andric if (TII.isFrameInstr(*I)) {
2717a7e6055SDimitry Andric unsigned Size = TII.getFrameSize(*I);
272f22ef01cSRoman Divacky if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
273f22ef01cSRoman Divacky AdjustsStack = true;
274f22ef01cSRoman Divacky FrameSDOps.push_back(I);
275f22ef01cSRoman Divacky } else if (I->isInlineAsm()) {
276ffd1746dSEd Schouten // Some inline asm's need a stack frame, as indicated by operand 1.
2772754fe60SDimitry Andric unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
2782754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
279f22ef01cSRoman Divacky AdjustsStack = true;
280f22ef01cSRoman Divacky }
281f22ef01cSRoman Divacky
2820f5676f4SDimitry Andric assert(!MFI.isMaxCallFrameSizeComputed() ||
2830f5676f4SDimitry Andric (MFI.getMaxCallFrameSize() == MaxCallFrameSize &&
2840f5676f4SDimitry Andric MFI.adjustsStack() == AdjustsStack));
285d88c1a5aSDimitry Andric MFI.setAdjustsStack(AdjustsStack);
286d88c1a5aSDimitry Andric MFI.setMaxCallFrameSize(MaxCallFrameSize);
287f22ef01cSRoman Divacky
288f22ef01cSRoman Divacky for (std::vector<MachineBasicBlock::iterator>::iterator
289f22ef01cSRoman Divacky i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) {
290f22ef01cSRoman Divacky MachineBasicBlock::iterator I = *i;
291f22ef01cSRoman Divacky
292f22ef01cSRoman Divacky // If call frames are not being included as part of the stack frame, and
293f22ef01cSRoman Divacky // the target doesn't indicate otherwise, remove the call frame pseudos
294f22ef01cSRoman Divacky // here. The sub/add sp instruction pairs are still inserted, but we don't
295f22ef01cSRoman Divacky // need to track the SP adjustment for frame index elimination.
2964ba319b5SDimitry Andric if (TFI->canSimplifyCallFramePseudos(MF))
2974ba319b5SDimitry Andric TFI->eliminateCallFramePseudoInstr(MF, *I->getParent(), I);
298f22ef01cSRoman Divacky }
299f22ef01cSRoman Divacky }
300f22ef01cSRoman Divacky
3013ca95b02SDimitry Andric /// Compute the sets of entry and return blocks for saving and restoring
3023ca95b02SDimitry Andric /// callee-saved registers, and placing prolog and epilog code.
calculateSaveRestoreBlocks(MachineFunction & MF)3034ba319b5SDimitry Andric void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) {
3044ba319b5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
305f22ef01cSRoman Divacky
3063ca95b02SDimitry Andric // Even when we do not change any CSR, we still want to insert the
3073ca95b02SDimitry Andric // prologue and epilogue of the function.
3083ca95b02SDimitry Andric // So set the save points for those.
3093ca95b02SDimitry Andric
3103ca95b02SDimitry Andric // Use the points found by shrink-wrapping, if any.
311d88c1a5aSDimitry Andric if (MFI.getSavePoint()) {
312d88c1a5aSDimitry Andric SaveBlocks.push_back(MFI.getSavePoint());
313d88c1a5aSDimitry Andric assert(MFI.getRestorePoint() && "Both restore and save must be set");
314d88c1a5aSDimitry Andric MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
3153ca95b02SDimitry Andric // If RestoreBlock does not have any successor and is not a return block
3163ca95b02SDimitry Andric // then the end point is unreachable and we do not need to insert any
3173ca95b02SDimitry Andric // epilogue.
3183ca95b02SDimitry Andric if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
3193ca95b02SDimitry Andric RestoreBlocks.push_back(RestoreBlock);
3203ca95b02SDimitry Andric return;
3213ca95b02SDimitry Andric }
3223ca95b02SDimitry Andric
3233ca95b02SDimitry Andric // Save refs to entry and return blocks.
3244ba319b5SDimitry Andric SaveBlocks.push_back(&MF.front());
3254ba319b5SDimitry Andric for (MachineBasicBlock &MBB : MF) {
3263ca95b02SDimitry Andric if (MBB.isEHFuncletEntry())
3273ca95b02SDimitry Andric SaveBlocks.push_back(&MBB);
3283ca95b02SDimitry Andric if (MBB.isReturnBlock())
3293ca95b02SDimitry Andric RestoreBlocks.push_back(&MBB);
3303ca95b02SDimitry Andric }
3313ca95b02SDimitry Andric }
3323ca95b02SDimitry Andric
assignCalleeSavedSpillSlots(MachineFunction & F,const BitVector & SavedRegs,unsigned & MinCSFrameIndex,unsigned & MaxCSFrameIndex)3333ca95b02SDimitry Andric static void assignCalleeSavedSpillSlots(MachineFunction &F,
3343ca95b02SDimitry Andric const BitVector &SavedRegs,
3353ca95b02SDimitry Andric unsigned &MinCSFrameIndex,
3363ca95b02SDimitry Andric unsigned &MaxCSFrameIndex) {
337875ed548SDimitry Andric if (SavedRegs.empty())
338f22ef01cSRoman Divacky return;
339f22ef01cSRoman Divacky
340875ed548SDimitry Andric const TargetRegisterInfo *RegInfo = F.getSubtarget().getRegisterInfo();
3417a7e6055SDimitry Andric const MCPhysReg *CSRegs = F.getRegInfo().getCalleeSavedRegs();
342f22ef01cSRoman Divacky
343f22ef01cSRoman Divacky std::vector<CalleeSavedInfo> CSI;
344f22ef01cSRoman Divacky for (unsigned i = 0; CSRegs[i]; ++i) {
345f22ef01cSRoman Divacky unsigned Reg = CSRegs[i];
346875ed548SDimitry Andric if (SavedRegs.test(Reg))
347ffd1746dSEd Schouten CSI.push_back(CalleeSavedInfo(Reg));
348f22ef01cSRoman Divacky }
349f22ef01cSRoman Divacky
350875ed548SDimitry Andric const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
351d88c1a5aSDimitry Andric MachineFrameInfo &MFI = F.getFrameInfo();
35291bc56edSDimitry Andric if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI)) {
35391bc56edSDimitry Andric // If target doesn't implement this, use generic code.
35491bc56edSDimitry Andric
355f22ef01cSRoman Divacky if (CSI.empty())
356f22ef01cSRoman Divacky return; // Early exit if no callee saved registers are modified!
357f22ef01cSRoman Divacky
358f22ef01cSRoman Divacky unsigned NumFixedSpillSlots;
3592754fe60SDimitry Andric const TargetFrameLowering::SpillSlot *FixedSpillSlots =
360f22ef01cSRoman Divacky TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots);
361f22ef01cSRoman Divacky
362f22ef01cSRoman Divacky // Now that we know which registers need to be saved and restored, allocate
363f22ef01cSRoman Divacky // stack slots for them.
3643ca95b02SDimitry Andric for (auto &CS : CSI) {
365b5893f02SDimitry Andric // If the target has spilled this register to another register, we don't
366b5893f02SDimitry Andric // need to allocate a stack slot.
367b5893f02SDimitry Andric if (CS.isSpilledToReg())
368b5893f02SDimitry Andric continue;
369b5893f02SDimitry Andric
3703ca95b02SDimitry Andric unsigned Reg = CS.getReg();
371ffd1746dSEd Schouten const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
372f22ef01cSRoman Divacky
373f22ef01cSRoman Divacky int FrameIdx;
374139f7f9bSDimitry Andric if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) {
3753ca95b02SDimitry Andric CS.setFrameIdx(FrameIdx);
376f22ef01cSRoman Divacky continue;
377f22ef01cSRoman Divacky }
378f22ef01cSRoman Divacky
379f22ef01cSRoman Divacky // Check to see if this physreg must be spilled to a particular stack slot
380f22ef01cSRoman Divacky // on this target.
3812754fe60SDimitry Andric const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots;
382f22ef01cSRoman Divacky while (FixedSlot != FixedSpillSlots + NumFixedSpillSlots &&
383f22ef01cSRoman Divacky FixedSlot->Reg != Reg)
384f22ef01cSRoman Divacky ++FixedSlot;
385f22ef01cSRoman Divacky
38651690af2SDimitry Andric unsigned Size = RegInfo->getSpillSize(*RC);
387f22ef01cSRoman Divacky if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
388f22ef01cSRoman Divacky // Nope, just spill it anywhere convenient.
38951690af2SDimitry Andric unsigned Align = RegInfo->getSpillAlignment(*RC);
390f22ef01cSRoman Divacky unsigned StackAlign = TFI->getStackAlignment();
391f22ef01cSRoman Divacky
392f22ef01cSRoman Divacky // We may not be able to satisfy the desired alignment specification of
393f22ef01cSRoman Divacky // the TargetRegisterClass if the stack alignment is smaller. Use the
394f22ef01cSRoman Divacky // min.
395f22ef01cSRoman Divacky Align = std::min(Align, StackAlign);
39651690af2SDimitry Andric FrameIdx = MFI.CreateStackObject(Size, Align, true);
397f22ef01cSRoman Divacky if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
398f22ef01cSRoman Divacky if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
399f22ef01cSRoman Divacky } else {
400f22ef01cSRoman Divacky // Spill it to the stack where we must.
40151690af2SDimitry Andric FrameIdx = MFI.CreateFixedSpillStackObject(Size, FixedSlot->Offset);
402f22ef01cSRoman Divacky }
403f22ef01cSRoman Divacky
4043ca95b02SDimitry Andric CS.setFrameIdx(FrameIdx);
405f22ef01cSRoman Divacky }
40691bc56edSDimitry Andric }
407f22ef01cSRoman Divacky
408d88c1a5aSDimitry Andric MFI.setCalleeSavedInfo(CSI);
409f22ef01cSRoman Divacky }
410f22ef01cSRoman Divacky
411ff0cc061SDimitry Andric /// Helper function to update the liveness information for the callee-saved
412ff0cc061SDimitry Andric /// registers.
updateLiveness(MachineFunction & MF)413ff0cc061SDimitry Andric static void updateLiveness(MachineFunction &MF) {
414d88c1a5aSDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
415ff0cc061SDimitry Andric // Visited will contain all the basic blocks that are in the region
416ff0cc061SDimitry Andric // where the callee saved registers are alive:
417ff0cc061SDimitry Andric // - Anything that is not Save or Restore -> LiveThrough.
418ff0cc061SDimitry Andric // - Save -> LiveIn.
419ff0cc061SDimitry Andric // - Restore -> LiveOut.
420ff0cc061SDimitry Andric // The live-out is not attached to the block, so no need to keep
421ff0cc061SDimitry Andric // Restore in this set.
422ff0cc061SDimitry Andric SmallPtrSet<MachineBasicBlock *, 8> Visited;
423ff0cc061SDimitry Andric SmallVector<MachineBasicBlock *, 8> WorkList;
424ff0cc061SDimitry Andric MachineBasicBlock *Entry = &MF.front();
425d88c1a5aSDimitry Andric MachineBasicBlock *Save = MFI.getSavePoint();
426ff0cc061SDimitry Andric
427ff0cc061SDimitry Andric if (!Save)
428ff0cc061SDimitry Andric Save = Entry;
429ff0cc061SDimitry Andric
430ff0cc061SDimitry Andric if (Entry != Save) {
431ff0cc061SDimitry Andric WorkList.push_back(Entry);
432ff0cc061SDimitry Andric Visited.insert(Entry);
433ff0cc061SDimitry Andric }
434ff0cc061SDimitry Andric Visited.insert(Save);
435ff0cc061SDimitry Andric
436d88c1a5aSDimitry Andric MachineBasicBlock *Restore = MFI.getRestorePoint();
437ff0cc061SDimitry Andric if (Restore)
438ff0cc061SDimitry Andric // By construction Restore cannot be visited, otherwise it
439ff0cc061SDimitry Andric // means there exists a path to Restore that does not go
440ff0cc061SDimitry Andric // through Save.
441ff0cc061SDimitry Andric WorkList.push_back(Restore);
442ff0cc061SDimitry Andric
443ff0cc061SDimitry Andric while (!WorkList.empty()) {
444ff0cc061SDimitry Andric const MachineBasicBlock *CurBB = WorkList.pop_back_val();
445ff0cc061SDimitry Andric // By construction, the region that is after the save point is
446ff0cc061SDimitry Andric // dominated by the Save and post-dominated by the Restore.
4477d523365SDimitry Andric if (CurBB == Save && Save != Restore)
448ff0cc061SDimitry Andric continue;
449ff0cc061SDimitry Andric // Enqueue all the successors not already visited.
450ff0cc061SDimitry Andric // Those are by construction either before Save or after Restore.
451ff0cc061SDimitry Andric for (MachineBasicBlock *SuccBB : CurBB->successors())
452ff0cc061SDimitry Andric if (Visited.insert(SuccBB).second)
453ff0cc061SDimitry Andric WorkList.push_back(SuccBB);
454ff0cc061SDimitry Andric }
455ff0cc061SDimitry Andric
456d88c1a5aSDimitry Andric const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
457ff0cc061SDimitry Andric
458302affcbSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
459ff0cc061SDimitry Andric for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
4607d523365SDimitry Andric for (MachineBasicBlock *MBB : Visited) {
4617d523365SDimitry Andric MCPhysReg Reg = CSI[i].getReg();
462ff0cc061SDimitry Andric // Add the callee-saved register as live-in.
463ff0cc061SDimitry Andric // It's killed at the spill.
464302affcbSDimitry Andric if (!MRI.isReserved(Reg) && !MBB->isLiveIn(Reg))
4657d523365SDimitry Andric MBB->addLiveIn(Reg);
4667d523365SDimitry Andric }
467b5893f02SDimitry Andric // If callee-saved register is spilled to another register rather than
468b5893f02SDimitry Andric // spilling to stack, the destination register has to be marked as live for
469b5893f02SDimitry Andric // each MBB between the prologue and epilogue so that it is not clobbered
470b5893f02SDimitry Andric // before it is reloaded in the epilogue. The Visited set contains all
471b5893f02SDimitry Andric // blocks outside of the region delimited by prologue/epilogue.
472b5893f02SDimitry Andric if (CSI[i].isSpilledToReg()) {
473b5893f02SDimitry Andric for (MachineBasicBlock &MBB : MF) {
474b5893f02SDimitry Andric if (Visited.count(&MBB))
475b5893f02SDimitry Andric continue;
476b5893f02SDimitry Andric MCPhysReg DstReg = CSI[i].getDstReg();
477b5893f02SDimitry Andric if (!MBB.isLiveIn(DstReg))
478b5893f02SDimitry Andric MBB.addLiveIn(DstReg);
479ff0cc061SDimitry Andric }
480ff0cc061SDimitry Andric }
481b5893f02SDimitry Andric }
482b5893f02SDimitry Andric
483b5893f02SDimitry Andric }
484ff0cc061SDimitry Andric
4852cab237bSDimitry Andric /// Insert restore code for the callee-saved registers used in the function.
insertCSRSaves(MachineBasicBlock & SaveBlock,ArrayRef<CalleeSavedInfo> CSI)4862cab237bSDimitry Andric static void insertCSRSaves(MachineBasicBlock &SaveBlock,
4872cab237bSDimitry Andric ArrayRef<CalleeSavedInfo> CSI) {
4884ba319b5SDimitry Andric MachineFunction &MF = *SaveBlock.getParent();
4894ba319b5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
4904ba319b5SDimitry Andric const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
4914ba319b5SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
492f22ef01cSRoman Divacky
4932cab237bSDimitry Andric MachineBasicBlock::iterator I = SaveBlock.begin();
4942cab237bSDimitry Andric if (!TFI->spillCalleeSavedRegisters(SaveBlock, I, CSI, TRI)) {
4952cab237bSDimitry Andric for (const CalleeSavedInfo &CS : CSI) {
496f22ef01cSRoman Divacky // Insert the spill to the stack frame.
4972cab237bSDimitry Andric unsigned Reg = CS.getReg();
498ffd1746dSEd Schouten const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
4992cab237bSDimitry Andric TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC,
5002cab237bSDimitry Andric TRI);
501f22ef01cSRoman Divacky }
502f22ef01cSRoman Divacky }
5037d523365SDimitry Andric }
504f22ef01cSRoman Divacky
5052cab237bSDimitry Andric /// Insert restore code for the callee-saved registers used in the function.
insertCSRRestores(MachineBasicBlock & RestoreBlock,std::vector<CalleeSavedInfo> & CSI)5062cab237bSDimitry Andric static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
5072cab237bSDimitry Andric std::vector<CalleeSavedInfo> &CSI) {
5084ba319b5SDimitry Andric MachineFunction &MF = *RestoreBlock.getParent();
5094ba319b5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
5104ba319b5SDimitry Andric const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
5114ba319b5SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
512f22ef01cSRoman Divacky
513f22ef01cSRoman Divacky // Restore all registers immediately before the return and any
5143b0f4066SDimitry Andric // terminators that precede it.
5152cab237bSDimitry Andric MachineBasicBlock::iterator I = RestoreBlock.getFirstTerminator();
5162cab237bSDimitry Andric
5172cab237bSDimitry Andric if (!TFI->restoreCalleeSavedRegisters(RestoreBlock, I, CSI, TRI)) {
5182cab237bSDimitry Andric for (const CalleeSavedInfo &CI : reverse(CSI)) {
5192cab237bSDimitry Andric unsigned Reg = CI.getReg();
520ffd1746dSEd Schouten const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
5212cab237bSDimitry Andric TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI);
5222cab237bSDimitry Andric assert(I != RestoreBlock.begin() &&
523f22ef01cSRoman Divacky "loadRegFromStackSlot didn't insert any code!");
524f22ef01cSRoman Divacky // Insert in reverse order. loadRegFromStackSlot can insert
525f22ef01cSRoman Divacky // multiple instructions.
526f22ef01cSRoman Divacky }
527f22ef01cSRoman Divacky }
528f22ef01cSRoman Divacky }
529f22ef01cSRoman Divacky
spillCalleeSavedRegs(MachineFunction & MF)5304ba319b5SDimitry Andric void PEI::spillCalleeSavedRegs(MachineFunction &MF) {
5312cab237bSDimitry Andric // We can't list this requirement in getRequiredProperties because some
5322cab237bSDimitry Andric // targets (WebAssembly) use virtual registers past this point, and the pass
5332cab237bSDimitry Andric // pipeline is set up without giving the passes a chance to look at the
5342cab237bSDimitry Andric // TargetMachine.
5352cab237bSDimitry Andric // FIXME: Find a way to express this in getRequiredProperties.
5364ba319b5SDimitry Andric assert(MF.getProperties().hasProperty(
5372cab237bSDimitry Andric MachineFunctionProperties::Property::NoVRegs));
5382cab237bSDimitry Andric
5394ba319b5SDimitry Andric const Function &F = MF.getFunction();
5404ba319b5SDimitry Andric const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
5414ba319b5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
5423ca95b02SDimitry Andric MinCSFrameIndex = std::numeric_limits<unsigned>::max();
5433ca95b02SDimitry Andric MaxCSFrameIndex = 0;
5443ca95b02SDimitry Andric
5453ca95b02SDimitry Andric // Determine which of the registers in the callee save list should be saved.
5463ca95b02SDimitry Andric BitVector SavedRegs;
5474ba319b5SDimitry Andric TFI->determineCalleeSaves(MF, SavedRegs, RS);
5483ca95b02SDimitry Andric
5493ca95b02SDimitry Andric // Assign stack slots for any callee-saved registers that must be spilled.
5504ba319b5SDimitry Andric assignCalleeSavedSpillSlots(MF, SavedRegs, MinCSFrameIndex, MaxCSFrameIndex);
5513ca95b02SDimitry Andric
5523ca95b02SDimitry Andric // Add the code to save and restore the callee saved registers.
5532cab237bSDimitry Andric if (!F.hasFnAttribute(Attribute::Naked)) {
5542cab237bSDimitry Andric MFI.setCalleeSavedInfoValid(true);
5552cab237bSDimitry Andric
5562cab237bSDimitry Andric std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
5572cab237bSDimitry Andric if (!CSI.empty()) {
558b5893f02SDimitry Andric if (!MFI.hasCalls())
559b5893f02SDimitry Andric NumLeafFuncWithSpills++;
560b5893f02SDimitry Andric
5612cab237bSDimitry Andric for (MachineBasicBlock *SaveBlock : SaveBlocks) {
5622cab237bSDimitry Andric insertCSRSaves(*SaveBlock, CSI);
5632cab237bSDimitry Andric // Update the live-in information of all the blocks up to the save
5642cab237bSDimitry Andric // point.
5654ba319b5SDimitry Andric updateLiveness(MF);
5662cab237bSDimitry Andric }
5672cab237bSDimitry Andric for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
5682cab237bSDimitry Andric insertCSRRestores(*RestoreBlock, CSI);
5692cab237bSDimitry Andric }
5702cab237bSDimitry Andric }
5713ca95b02SDimitry Andric }
5723ca95b02SDimitry Andric
573f22ef01cSRoman Divacky /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
574f22ef01cSRoman Divacky static inline void
AdjustStackOffset(MachineFrameInfo & MFI,int FrameIdx,bool StackGrowsDown,int64_t & Offset,unsigned & MaxAlign,unsigned Skew)575d88c1a5aSDimitry Andric AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx,
576f22ef01cSRoman Divacky bool StackGrowsDown, int64_t &Offset,
5777d523365SDimitry Andric unsigned &MaxAlign, unsigned Skew) {
578f22ef01cSRoman Divacky // If the stack grows down, add the object size to find the lowest address.
579f22ef01cSRoman Divacky if (StackGrowsDown)
580d88c1a5aSDimitry Andric Offset += MFI.getObjectSize(FrameIdx);
581f22ef01cSRoman Divacky
582d88c1a5aSDimitry Andric unsigned Align = MFI.getObjectAlignment(FrameIdx);
583f22ef01cSRoman Divacky
584f22ef01cSRoman Divacky // If the alignment of this object is greater than that of the stack, then
585f22ef01cSRoman Divacky // increase the stack alignment to match.
586f22ef01cSRoman Divacky MaxAlign = std::max(MaxAlign, Align);
587f22ef01cSRoman Divacky
588f22ef01cSRoman Divacky // Adjust to alignment boundary.
5893ca95b02SDimitry Andric Offset = alignTo(Offset, Align, Skew);
590f22ef01cSRoman Divacky
591f22ef01cSRoman Divacky if (StackGrowsDown) {
5924ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset
5934ba319b5SDimitry Andric << "]\n");
594d88c1a5aSDimitry Andric MFI.setObjectOffset(FrameIdx, -Offset); // Set the computed offset
595f22ef01cSRoman Divacky } else {
5964ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset
5974ba319b5SDimitry Andric << "]\n");
598d88c1a5aSDimitry Andric MFI.setObjectOffset(FrameIdx, Offset);
599d88c1a5aSDimitry Andric Offset += MFI.getObjectSize(FrameIdx);
600f22ef01cSRoman Divacky }
601f22ef01cSRoman Divacky }
602f22ef01cSRoman Divacky
6033ca95b02SDimitry Andric /// Compute which bytes of fixed and callee-save stack area are unused and keep
6043ca95b02SDimitry Andric /// track of them in StackBytesFree.
6053ca95b02SDimitry Andric static inline void
computeFreeStackSlots(MachineFrameInfo & MFI,bool StackGrowsDown,unsigned MinCSFrameIndex,unsigned MaxCSFrameIndex,int64_t FixedCSEnd,BitVector & StackBytesFree)606d88c1a5aSDimitry Andric computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown,
6073ca95b02SDimitry Andric unsigned MinCSFrameIndex, unsigned MaxCSFrameIndex,
6083ca95b02SDimitry Andric int64_t FixedCSEnd, BitVector &StackBytesFree) {
6093ca95b02SDimitry Andric // Avoid undefined int64_t -> int conversion below in extreme case.
6103ca95b02SDimitry Andric if (FixedCSEnd > std::numeric_limits<int>::max())
6113ca95b02SDimitry Andric return;
6123ca95b02SDimitry Andric
6133ca95b02SDimitry Andric StackBytesFree.resize(FixedCSEnd, true);
6143ca95b02SDimitry Andric
6153ca95b02SDimitry Andric SmallVector<int, 16> AllocatedFrameSlots;
6163ca95b02SDimitry Andric // Add fixed objects.
617d88c1a5aSDimitry Andric for (int i = MFI.getObjectIndexBegin(); i != 0; ++i)
6183ca95b02SDimitry Andric AllocatedFrameSlots.push_back(i);
6193ca95b02SDimitry Andric // Add callee-save objects.
6203ca95b02SDimitry Andric for (int i = MinCSFrameIndex; i <= (int)MaxCSFrameIndex; ++i)
6213ca95b02SDimitry Andric AllocatedFrameSlots.push_back(i);
6223ca95b02SDimitry Andric
6233ca95b02SDimitry Andric for (int i : AllocatedFrameSlots) {
6243ca95b02SDimitry Andric // These are converted from int64_t, but they should always fit in int
6253ca95b02SDimitry Andric // because of the FixedCSEnd check above.
626d88c1a5aSDimitry Andric int ObjOffset = MFI.getObjectOffset(i);
627d88c1a5aSDimitry Andric int ObjSize = MFI.getObjectSize(i);
6283ca95b02SDimitry Andric int ObjStart, ObjEnd;
6293ca95b02SDimitry Andric if (StackGrowsDown) {
6303ca95b02SDimitry Andric // ObjOffset is negative when StackGrowsDown is true.
6313ca95b02SDimitry Andric ObjStart = -ObjOffset - ObjSize;
6323ca95b02SDimitry Andric ObjEnd = -ObjOffset;
6333ca95b02SDimitry Andric } else {
6343ca95b02SDimitry Andric ObjStart = ObjOffset;
6353ca95b02SDimitry Andric ObjEnd = ObjOffset + ObjSize;
6363ca95b02SDimitry Andric }
6373ca95b02SDimitry Andric // Ignore fixed holes that are in the previous stack frame.
6383ca95b02SDimitry Andric if (ObjEnd > 0)
6393ca95b02SDimitry Andric StackBytesFree.reset(ObjStart, ObjEnd);
6403ca95b02SDimitry Andric }
6413ca95b02SDimitry Andric }
6423ca95b02SDimitry Andric
6433ca95b02SDimitry Andric /// Assign frame object to an unused portion of the stack in the fixed stack
6443ca95b02SDimitry Andric /// object range. Return true if the allocation was successful.
scavengeStackSlot(MachineFrameInfo & MFI,int FrameIdx,bool StackGrowsDown,unsigned MaxAlign,BitVector & StackBytesFree)645d88c1a5aSDimitry Andric static inline bool scavengeStackSlot(MachineFrameInfo &MFI, int FrameIdx,
6463ca95b02SDimitry Andric bool StackGrowsDown, unsigned MaxAlign,
6473ca95b02SDimitry Andric BitVector &StackBytesFree) {
648d88c1a5aSDimitry Andric if (MFI.isVariableSizedObjectIndex(FrameIdx))
6493ca95b02SDimitry Andric return false;
6503ca95b02SDimitry Andric
6513ca95b02SDimitry Andric if (StackBytesFree.none()) {
6523ca95b02SDimitry Andric // clear it to speed up later scavengeStackSlot calls to
6533ca95b02SDimitry Andric // StackBytesFree.none()
6543ca95b02SDimitry Andric StackBytesFree.clear();
6553ca95b02SDimitry Andric return false;
6563ca95b02SDimitry Andric }
6573ca95b02SDimitry Andric
658d88c1a5aSDimitry Andric unsigned ObjAlign = MFI.getObjectAlignment(FrameIdx);
6593ca95b02SDimitry Andric if (ObjAlign > MaxAlign)
6603ca95b02SDimitry Andric return false;
6613ca95b02SDimitry Andric
662d88c1a5aSDimitry Andric int64_t ObjSize = MFI.getObjectSize(FrameIdx);
6633ca95b02SDimitry Andric int FreeStart;
6643ca95b02SDimitry Andric for (FreeStart = StackBytesFree.find_first(); FreeStart != -1;
6653ca95b02SDimitry Andric FreeStart = StackBytesFree.find_next(FreeStart)) {
6663ca95b02SDimitry Andric
6673ca95b02SDimitry Andric // Check that free space has suitable alignment.
6683ca95b02SDimitry Andric unsigned ObjStart = StackGrowsDown ? FreeStart + ObjSize : FreeStart;
6693ca95b02SDimitry Andric if (alignTo(ObjStart, ObjAlign) != ObjStart)
6703ca95b02SDimitry Andric continue;
6713ca95b02SDimitry Andric
6723ca95b02SDimitry Andric if (FreeStart + ObjSize > StackBytesFree.size())
6733ca95b02SDimitry Andric return false;
6743ca95b02SDimitry Andric
6753ca95b02SDimitry Andric bool AllBytesFree = true;
6763ca95b02SDimitry Andric for (unsigned Byte = 0; Byte < ObjSize; ++Byte)
6773ca95b02SDimitry Andric if (!StackBytesFree.test(FreeStart + Byte)) {
6783ca95b02SDimitry Andric AllBytesFree = false;
6793ca95b02SDimitry Andric break;
6803ca95b02SDimitry Andric }
6813ca95b02SDimitry Andric if (AllBytesFree)
6823ca95b02SDimitry Andric break;
6833ca95b02SDimitry Andric }
6843ca95b02SDimitry Andric
6853ca95b02SDimitry Andric if (FreeStart == -1)
6863ca95b02SDimitry Andric return false;
6873ca95b02SDimitry Andric
6883ca95b02SDimitry Andric if (StackGrowsDown) {
6893ca95b02SDimitry Andric int ObjStart = -(FreeStart + ObjSize);
6904ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") scavenged at SP["
6914ba319b5SDimitry Andric << ObjStart << "]\n");
692d88c1a5aSDimitry Andric MFI.setObjectOffset(FrameIdx, ObjStart);
6933ca95b02SDimitry Andric } else {
6944ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") scavenged at SP["
6954ba319b5SDimitry Andric << FreeStart << "]\n");
696d88c1a5aSDimitry Andric MFI.setObjectOffset(FrameIdx, FreeStart);
6973ca95b02SDimitry Andric }
6983ca95b02SDimitry Andric
6993ca95b02SDimitry Andric StackBytesFree.reset(FreeStart, FreeStart + ObjSize);
7003ca95b02SDimitry Andric return true;
7013ca95b02SDimitry Andric }
7023ca95b02SDimitry Andric
70391bc56edSDimitry Andric /// AssignProtectedObjSet - Helper function to assign large stack objects (i.e.,
70491bc56edSDimitry Andric /// those required to be close to the Stack Protector) to stack offsets.
70591bc56edSDimitry Andric static void
AssignProtectedObjSet(const StackObjSet & UnassignedObjs,SmallSet<int,16> & ProtectedObjs,MachineFrameInfo & MFI,bool StackGrowsDown,int64_t & Offset,unsigned & MaxAlign,unsigned Skew)70691bc56edSDimitry Andric AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
70791bc56edSDimitry Andric SmallSet<int, 16> &ProtectedObjs,
708d88c1a5aSDimitry Andric MachineFrameInfo &MFI, bool StackGrowsDown,
7097d523365SDimitry Andric int64_t &Offset, unsigned &MaxAlign, unsigned Skew) {
71091bc56edSDimitry Andric
71191bc56edSDimitry Andric for (StackObjSet::const_iterator I = UnassignedObjs.begin(),
71291bc56edSDimitry Andric E = UnassignedObjs.end(); I != E; ++I) {
71391bc56edSDimitry Andric int i = *I;
7147d523365SDimitry Andric AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign, Skew);
71591bc56edSDimitry Andric ProtectedObjs.insert(i);
71691bc56edSDimitry Andric }
71791bc56edSDimitry Andric }
71891bc56edSDimitry Andric
719f22ef01cSRoman Divacky /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the
720f22ef01cSRoman Divacky /// abstract stack objects.
calculateFrameObjectOffsets(MachineFunction & MF)7214ba319b5SDimitry Andric void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
7224ba319b5SDimitry Andric const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
723f22ef01cSRoman Divacky
724f22ef01cSRoman Divacky bool StackGrowsDown =
7252754fe60SDimitry Andric TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
726f22ef01cSRoman Divacky
727f22ef01cSRoman Divacky // Loop over all of the stack objects, assigning sequential addresses...
7284ba319b5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
729f22ef01cSRoman Divacky
730f22ef01cSRoman Divacky // Start at the beginning of the local area.
731f22ef01cSRoman Divacky // The Offset is the distance from the stack top in the direction
732f22ef01cSRoman Divacky // of stack growth -- so it's always nonnegative.
733f22ef01cSRoman Divacky int LocalAreaOffset = TFI.getOffsetOfLocalArea();
734f22ef01cSRoman Divacky if (StackGrowsDown)
735f22ef01cSRoman Divacky LocalAreaOffset = -LocalAreaOffset;
736f22ef01cSRoman Divacky assert(LocalAreaOffset >= 0
737f22ef01cSRoman Divacky && "Local area offset should be in direction of stack growth");
738f22ef01cSRoman Divacky int64_t Offset = LocalAreaOffset;
739f22ef01cSRoman Divacky
7407d523365SDimitry Andric // Skew to be applied to alignment.
7414ba319b5SDimitry Andric unsigned Skew = TFI.getStackAlignmentSkew(MF);
7427d523365SDimitry Andric
743f22ef01cSRoman Divacky // If there are fixed sized objects that are preallocated in the local area,
744f22ef01cSRoman Divacky // non-fixed objects can't be allocated right at the start of local area.
7453ca95b02SDimitry Andric // Adjust 'Offset' to point to the end of last fixed sized preallocated
7463ca95b02SDimitry Andric // object.
747d88c1a5aSDimitry Andric for (int i = MFI.getObjectIndexBegin(); i != 0; ++i) {
748f22ef01cSRoman Divacky int64_t FixedOff;
749f22ef01cSRoman Divacky if (StackGrowsDown) {
750f22ef01cSRoman Divacky // The maximum distance from the stack pointer is at lower address of
751f22ef01cSRoman Divacky // the object -- which is given by offset. For down growing stack
752f22ef01cSRoman Divacky // the offset is negative, so we negate the offset to get the distance.
753d88c1a5aSDimitry Andric FixedOff = -MFI.getObjectOffset(i);
754f22ef01cSRoman Divacky } else {
755f22ef01cSRoman Divacky // The maximum distance from the start pointer is at the upper
756f22ef01cSRoman Divacky // address of the object.
757d88c1a5aSDimitry Andric FixedOff = MFI.getObjectOffset(i) + MFI.getObjectSize(i);
758f22ef01cSRoman Divacky }
759f22ef01cSRoman Divacky if (FixedOff > Offset) Offset = FixedOff;
760f22ef01cSRoman Divacky }
761f22ef01cSRoman Divacky
762f22ef01cSRoman Divacky // First assign frame offsets to stack objects that are used to spill
763f22ef01cSRoman Divacky // callee saved registers.
764f22ef01cSRoman Divacky if (StackGrowsDown) {
765f22ef01cSRoman Divacky for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) {
766f22ef01cSRoman Divacky // If the stack grows down, we need to add the size to find the lowest
767f22ef01cSRoman Divacky // address of the object.
768d88c1a5aSDimitry Andric Offset += MFI.getObjectSize(i);
769f22ef01cSRoman Divacky
770d88c1a5aSDimitry Andric unsigned Align = MFI.getObjectAlignment(i);
771f22ef01cSRoman Divacky // Adjust to alignment boundary
7723ca95b02SDimitry Andric Offset = alignTo(Offset, Align, Skew);
773f22ef01cSRoman Divacky
7744ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "alloc FI(" << i << ") at SP[" << -Offset << "]\n");
775d88c1a5aSDimitry Andric MFI.setObjectOffset(i, -Offset); // Set the computed offset
776f22ef01cSRoman Divacky }
7773ca95b02SDimitry Andric } else if (MaxCSFrameIndex >= MinCSFrameIndex) {
7783ca95b02SDimitry Andric // Be careful about underflow in comparisons agains MinCSFrameIndex.
7793ca95b02SDimitry Andric for (unsigned i = MaxCSFrameIndex; i != MinCSFrameIndex - 1; --i) {
780f37b6182SDimitry Andric if (MFI.isDeadObjectIndex(i))
781f37b6182SDimitry Andric continue;
782f37b6182SDimitry Andric
783d88c1a5aSDimitry Andric unsigned Align = MFI.getObjectAlignment(i);
784f22ef01cSRoman Divacky // Adjust to alignment boundary
7853ca95b02SDimitry Andric Offset = alignTo(Offset, Align, Skew);
786f22ef01cSRoman Divacky
7874ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "alloc FI(" << i << ") at SP[" << Offset << "]\n");
788d88c1a5aSDimitry Andric MFI.setObjectOffset(i, Offset);
789d88c1a5aSDimitry Andric Offset += MFI.getObjectSize(i);
790f22ef01cSRoman Divacky }
791f22ef01cSRoman Divacky }
792f22ef01cSRoman Divacky
7933ca95b02SDimitry Andric // FixedCSEnd is the stack offset to the end of the fixed and callee-save
7943ca95b02SDimitry Andric // stack area.
7953ca95b02SDimitry Andric int64_t FixedCSEnd = Offset;
796d88c1a5aSDimitry Andric unsigned MaxAlign = MFI.getMaxAlignment();
797f22ef01cSRoman Divacky
798f22ef01cSRoman Divacky // Make sure the special register scavenging spill slot is closest to the
799f785676fSDimitry Andric // incoming stack pointer if a frame pointer is required and is closer
800f785676fSDimitry Andric // to the incoming rather than the final stack pointer.
8014ba319b5SDimitry Andric const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
8024ba319b5SDimitry Andric bool EarlyScavengingSlots = (TFI.hasFP(MF) &&
803f785676fSDimitry Andric TFI.isFPCloseToIncomingSP() &&
8044ba319b5SDimitry Andric RegInfo->useFPForScavengingIndex(MF) &&
8054ba319b5SDimitry Andric !RegInfo->needsStackRealignment(MF));
806f785676fSDimitry Andric if (RS && EarlyScavengingSlots) {
807139f7f9bSDimitry Andric SmallVector<int, 2> SFIs;
808139f7f9bSDimitry Andric RS->getScavengingFrameIndices(SFIs);
809f785676fSDimitry Andric for (SmallVectorImpl<int>::iterator I = SFIs.begin(),
810139f7f9bSDimitry Andric IE = SFIs.end(); I != IE; ++I)
8117d523365SDimitry Andric AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign, Skew);
812f22ef01cSRoman Divacky }
813f22ef01cSRoman Divacky
814e580952dSDimitry Andric // FIXME: Once this is working, then enable flag will change to a target
815e580952dSDimitry Andric // check for whether the frame is large enough to want to use virtual
816e580952dSDimitry Andric // frame index registers. Functions which don't want/need this optimization
817e580952dSDimitry Andric // will continue to use the existing code path.
818d88c1a5aSDimitry Andric if (MFI.getUseLocalStackAllocationBlock()) {
819d88c1a5aSDimitry Andric unsigned Align = MFI.getLocalFrameMaxAlign();
820e580952dSDimitry Andric
821e580952dSDimitry Andric // Adjust to alignment boundary.
8223ca95b02SDimitry Andric Offset = alignTo(Offset, Align, Skew);
823e580952dSDimitry Andric
8244ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
825e580952dSDimitry Andric
826e580952dSDimitry Andric // Resolve offsets for objects in the local block.
827d88c1a5aSDimitry Andric for (unsigned i = 0, e = MFI.getLocalFrameObjectCount(); i != e; ++i) {
828d88c1a5aSDimitry Andric std::pair<int, int64_t> Entry = MFI.getLocalFrameObjectMap(i);
829e580952dSDimitry Andric int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
8304ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << FIOffset
8314ba319b5SDimitry Andric << "]\n");
832d88c1a5aSDimitry Andric MFI.setObjectOffset(Entry.first, FIOffset);
833e580952dSDimitry Andric }
834e580952dSDimitry Andric // Allocate the local block
835d88c1a5aSDimitry Andric Offset += MFI.getLocalFrameSize();
836e580952dSDimitry Andric
837e580952dSDimitry Andric MaxAlign = std::max(Align, MaxAlign);
838e580952dSDimitry Andric }
839e580952dSDimitry Andric
8403ca95b02SDimitry Andric // Retrieve the Exception Handler registration node.
8412cab237bSDimitry Andric int EHRegNodeFrameIndex = std::numeric_limits<int>::max();
8424ba319b5SDimitry Andric if (const WinEHFuncInfo *FuncInfo = MF.getWinEHFuncInfo())
8433ca95b02SDimitry Andric EHRegNodeFrameIndex = FuncInfo->EHRegNodeFrameIndex;
8443ca95b02SDimitry Andric
845f22ef01cSRoman Divacky // Make sure that the stack protector comes before the local variables on the
846f22ef01cSRoman Divacky // stack.
84791bc56edSDimitry Andric SmallSet<int, 16> ProtectedObjs;
848*ecadc219SDimitry Andric if (MFI.hasStackProtectorIndex()) {
849*ecadc219SDimitry Andric int StackProtectorFI = MFI.getStackProtectorIndex();
85091bc56edSDimitry Andric StackObjSet LargeArrayObjs;
85191bc56edSDimitry Andric StackObjSet SmallArrayObjs;
85291bc56edSDimitry Andric StackObjSet AddrOfObjs;
85391bc56edSDimitry Andric
854*ecadc219SDimitry Andric // If we need a stack protector, we need to make sure that
855*ecadc219SDimitry Andric // LocalStackSlotPass didn't already allocate a slot for it.
856*ecadc219SDimitry Andric // If we are told to use the LocalStackAllocationBlock, the stack protector
857*ecadc219SDimitry Andric // is expected to be already pre-allocated.
858*ecadc219SDimitry Andric if (!MFI.getUseLocalStackAllocationBlock())
859*ecadc219SDimitry Andric AdjustStackOffset(MFI, StackProtectorFI, StackGrowsDown, Offset, MaxAlign,
860*ecadc219SDimitry Andric Skew);
861*ecadc219SDimitry Andric else if (!MFI.isObjectPreAllocated(MFI.getStackProtectorIndex()))
862*ecadc219SDimitry Andric llvm_unreachable(
863*ecadc219SDimitry Andric "Stack protector not pre-allocated by LocalStackSlotPass.");
864f22ef01cSRoman Divacky
865e580952dSDimitry Andric // Assign large stack objects first.
866d88c1a5aSDimitry Andric for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
867*ecadc219SDimitry Andric if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock())
868e580952dSDimitry Andric continue;
869f22ef01cSRoman Divacky if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
870f22ef01cSRoman Divacky continue;
871139f7f9bSDimitry Andric if (RS && RS->isScavengingFrameIndex((int)i))
872f22ef01cSRoman Divacky continue;
873d88c1a5aSDimitry Andric if (MFI.isDeadObjectIndex(i))
874f22ef01cSRoman Divacky continue;
875*ecadc219SDimitry Andric if (StackProtectorFI == (int)i || EHRegNodeFrameIndex == (int)i)
876f22ef01cSRoman Divacky continue;
877e580952dSDimitry Andric
8784ba319b5SDimitry Andric switch (MFI.getObjectSSPLayout(i)) {
8794ba319b5SDimitry Andric case MachineFrameInfo::SSPLK_None:
88091bc56edSDimitry Andric continue;
8814ba319b5SDimitry Andric case MachineFrameInfo::SSPLK_SmallArray:
88291bc56edSDimitry Andric SmallArrayObjs.insert(i);
88391bc56edSDimitry Andric continue;
8844ba319b5SDimitry Andric case MachineFrameInfo::SSPLK_AddrOf:
88591bc56edSDimitry Andric AddrOfObjs.insert(i);
88691bc56edSDimitry Andric continue;
8874ba319b5SDimitry Andric case MachineFrameInfo::SSPLK_LargeArray:
88891bc56edSDimitry Andric LargeArrayObjs.insert(i);
88991bc56edSDimitry Andric continue;
890e580952dSDimitry Andric }
89191bc56edSDimitry Andric llvm_unreachable("Unexpected SSPLayoutKind.");
89291bc56edSDimitry Andric }
89391bc56edSDimitry Andric
894*ecadc219SDimitry Andric // We expect **all** the protected stack objects to be pre-allocated by
895*ecadc219SDimitry Andric // LocalStackSlotPass. If it turns out that PEI still has to allocate some
896*ecadc219SDimitry Andric // of them, we may end up messing up the expected order of the objects.
897*ecadc219SDimitry Andric if (MFI.getUseLocalStackAllocationBlock() &&
898*ecadc219SDimitry Andric !(LargeArrayObjs.empty() && SmallArrayObjs.empty() &&
899*ecadc219SDimitry Andric AddrOfObjs.empty()))
900*ecadc219SDimitry Andric llvm_unreachable("Found protected stack objects not pre-allocated by "
901*ecadc219SDimitry Andric "LocalStackSlotPass.");
902*ecadc219SDimitry Andric
90391bc56edSDimitry Andric AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
9047d523365SDimitry Andric Offset, MaxAlign, Skew);
90591bc56edSDimitry Andric AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
9067d523365SDimitry Andric Offset, MaxAlign, Skew);
90791bc56edSDimitry Andric AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown,
9087d523365SDimitry Andric Offset, MaxAlign, Skew);
909e580952dSDimitry Andric }
910e580952dSDimitry Andric
9113ca95b02SDimitry Andric SmallVector<int, 8> ObjectsToAllocate;
9123ca95b02SDimitry Andric
9133ca95b02SDimitry Andric // Then prepare to assign frame offsets to stack objects that are not used to
9143ca95b02SDimitry Andric // spill callee saved registers.
915d88c1a5aSDimitry Andric for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
916d88c1a5aSDimitry Andric if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock())
917e580952dSDimitry Andric continue;
918e580952dSDimitry Andric if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
919e580952dSDimitry Andric continue;
920139f7f9bSDimitry Andric if (RS && RS->isScavengingFrameIndex((int)i))
921e580952dSDimitry Andric continue;
922d88c1a5aSDimitry Andric if (MFI.isDeadObjectIndex(i))
923e580952dSDimitry Andric continue;
924*ecadc219SDimitry Andric if (MFI.getStackProtectorIndex() == (int)i || EHRegNodeFrameIndex == (int)i)
925e580952dSDimitry Andric continue;
92691bc56edSDimitry Andric if (ProtectedObjs.count(i))
927e580952dSDimitry Andric continue;
928f22ef01cSRoman Divacky
9293ca95b02SDimitry Andric // Add the objects that we need to allocate to our working set.
9303ca95b02SDimitry Andric ObjectsToAllocate.push_back(i);
931f22ef01cSRoman Divacky }
932f22ef01cSRoman Divacky
9333ca95b02SDimitry Andric // Allocate the EH registration node first if one is present.
9342cab237bSDimitry Andric if (EHRegNodeFrameIndex != std::numeric_limits<int>::max())
9353ca95b02SDimitry Andric AdjustStackOffset(MFI, EHRegNodeFrameIndex, StackGrowsDown, Offset,
9363ca95b02SDimitry Andric MaxAlign, Skew);
9373ca95b02SDimitry Andric
9383ca95b02SDimitry Andric // Give the targets a chance to order the objects the way they like it.
9394ba319b5SDimitry Andric if (MF.getTarget().getOptLevel() != CodeGenOpt::None &&
9404ba319b5SDimitry Andric MF.getTarget().Options.StackSymbolOrdering)
9414ba319b5SDimitry Andric TFI.orderFrameObjects(MF, ObjectsToAllocate);
9423ca95b02SDimitry Andric
9433ca95b02SDimitry Andric // Keep track of which bytes in the fixed and callee-save range are used so we
9443ca95b02SDimitry Andric // can use the holes when allocating later stack objects. Only do this if
9453ca95b02SDimitry Andric // stack protector isn't being used and the target requests it and we're
9463ca95b02SDimitry Andric // optimizing.
9473ca95b02SDimitry Andric BitVector StackBytesFree;
9483ca95b02SDimitry Andric if (!ObjectsToAllocate.empty() &&
9494ba319b5SDimitry Andric MF.getTarget().getOptLevel() != CodeGenOpt::None &&
9504ba319b5SDimitry Andric MFI.getStackProtectorIndex() < 0 && TFI.enableStackSlotScavenging(MF))
9513ca95b02SDimitry Andric computeFreeStackSlots(MFI, StackGrowsDown, MinCSFrameIndex, MaxCSFrameIndex,
9523ca95b02SDimitry Andric FixedCSEnd, StackBytesFree);
9533ca95b02SDimitry Andric
9543ca95b02SDimitry Andric // Now walk the objects and actually assign base offsets to them.
9553ca95b02SDimitry Andric for (auto &Object : ObjectsToAllocate)
9563ca95b02SDimitry Andric if (!scavengeStackSlot(MFI, Object, StackGrowsDown, MaxAlign,
9573ca95b02SDimitry Andric StackBytesFree))
9583ca95b02SDimitry Andric AdjustStackOffset(MFI, Object, StackGrowsDown, Offset, MaxAlign, Skew);
9593ca95b02SDimitry Andric
960f22ef01cSRoman Divacky // Make sure the special register scavenging spill slot is closest to the
961f22ef01cSRoman Divacky // stack pointer.
962f785676fSDimitry Andric if (RS && !EarlyScavengingSlots) {
963139f7f9bSDimitry Andric SmallVector<int, 2> SFIs;
964139f7f9bSDimitry Andric RS->getScavengingFrameIndices(SFIs);
965f785676fSDimitry Andric for (SmallVectorImpl<int>::iterator I = SFIs.begin(),
966139f7f9bSDimitry Andric IE = SFIs.end(); I != IE; ++I)
9677d523365SDimitry Andric AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign, Skew);
968f22ef01cSRoman Divacky }
969f22ef01cSRoman Divacky
9702754fe60SDimitry Andric if (!TFI.targetHandlesStackFrameRounding()) {
971f22ef01cSRoman Divacky // If we have reserved argument space for call sites in the function
972f22ef01cSRoman Divacky // immediately on entry to the current function, count it as part of the
973f22ef01cSRoman Divacky // overall stack size.
9744ba319b5SDimitry Andric if (MFI.adjustsStack() && TFI.hasReservedCallFrame(MF))
975d88c1a5aSDimitry Andric Offset += MFI.getMaxCallFrameSize();
976f22ef01cSRoman Divacky
977f22ef01cSRoman Divacky // Round up the size to a multiple of the alignment. If the function has
978f22ef01cSRoman Divacky // any calls or alloca's, align to the target's StackAlignment value to
979f22ef01cSRoman Divacky // ensure that the callee's frame or the alloca data is suitably aligned;
980f22ef01cSRoman Divacky // otherwise, for leaf functions, align to the TransientStackAlignment
981f22ef01cSRoman Divacky // value.
982f22ef01cSRoman Divacky unsigned StackAlign;
983d88c1a5aSDimitry Andric if (MFI.adjustsStack() || MFI.hasVarSizedObjects() ||
9844ba319b5SDimitry Andric (RegInfo->needsStackRealignment(MF) && MFI.getObjectIndexEnd() != 0))
985f22ef01cSRoman Divacky StackAlign = TFI.getStackAlignment();
986f22ef01cSRoman Divacky else
987f22ef01cSRoman Divacky StackAlign = TFI.getTransientStackAlignment();
988f22ef01cSRoman Divacky
989f22ef01cSRoman Divacky // If the frame pointer is eliminated, all frame offsets will be relative to
990f22ef01cSRoman Divacky // SP not FP. Align to MaxAlign so this works.
991f22ef01cSRoman Divacky StackAlign = std::max(StackAlign, MaxAlign);
9923ca95b02SDimitry Andric Offset = alignTo(Offset, StackAlign, Skew);
993f22ef01cSRoman Divacky }
994f22ef01cSRoman Divacky
995f22ef01cSRoman Divacky // Update frame info to pretend that this is part of the stack...
9966122f3e6SDimitry Andric int64_t StackSize = Offset - LocalAreaOffset;
997d88c1a5aSDimitry Andric MFI.setStackSize(StackSize);
9986122f3e6SDimitry Andric NumBytesStackSpace += StackSize;
999f22ef01cSRoman Divacky }
1000f22ef01cSRoman Divacky
1001f22ef01cSRoman Divacky /// insertPrologEpilogCode - Scan the function for modified callee saved
1002f22ef01cSRoman Divacky /// registers, insert spill code for these callee saved registers, then add
1003f22ef01cSRoman Divacky /// prolog and epilog code to the function.
insertPrologEpilogCode(MachineFunction & MF)10044ba319b5SDimitry Andric void PEI::insertPrologEpilogCode(MachineFunction &MF) {
10054ba319b5SDimitry Andric const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
1006f22ef01cSRoman Divacky
1007f22ef01cSRoman Divacky // Add prologue to the function...
10087d523365SDimitry Andric for (MachineBasicBlock *SaveBlock : SaveBlocks)
10094ba319b5SDimitry Andric TFI.emitPrologue(MF, *SaveBlock);
1010f22ef01cSRoman Divacky
1011ff0cc061SDimitry Andric // Add epilogue to restore the callee-save registers in each exiting block.
1012ff0cc061SDimitry Andric for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
10134ba319b5SDimitry Andric TFI.emitEpilogue(MF, *RestoreBlock);
10146122f3e6SDimitry Andric
10157d523365SDimitry Andric for (MachineBasicBlock *SaveBlock : SaveBlocks)
10164ba319b5SDimitry Andric TFI.inlineStackProbe(MF, *SaveBlock);
10177d523365SDimitry Andric
10186122f3e6SDimitry Andric // Emit additional code that is required to support segmented stacks, if
10196122f3e6SDimitry Andric // we've been asked for it. This, when linked with a runtime with support
10206122f3e6SDimitry Andric // for segmented stacks (libgcc is one), will result in allocating stack
10216122f3e6SDimitry Andric // space in small chunks instead of one large contiguous block.
10224ba319b5SDimitry Andric if (MF.shouldSplitStack()) {
10237d523365SDimitry Andric for (MachineBasicBlock *SaveBlock : SaveBlocks)
10244ba319b5SDimitry Andric TFI.adjustForSegmentedStacks(MF, *SaveBlock);
10252cab237bSDimitry Andric // Record that there are split-stack functions, so we will emit a
10262cab237bSDimitry Andric // special section to tell the linker.
10274ba319b5SDimitry Andric MF.getMMI().setHasSplitStack(true);
10282cab237bSDimitry Andric } else
10294ba319b5SDimitry Andric MF.getMMI().setHasNosplitStack(true);
1030139f7f9bSDimitry Andric
1031139f7f9bSDimitry Andric // Emit additional code that is required to explicitly handle the stack in
1032139f7f9bSDimitry Andric // HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The
1033139f7f9bSDimitry Andric // approach is rather similar to that of Segmented Stacks, but it uses a
1034139f7f9bSDimitry Andric // different conditional check and another BIF for allocating more stack
1035139f7f9bSDimitry Andric // space.
10364ba319b5SDimitry Andric if (MF.getFunction().getCallingConv() == CallingConv::HiPE)
10377d523365SDimitry Andric for (MachineBasicBlock *SaveBlock : SaveBlocks)
10384ba319b5SDimitry Andric TFI.adjustForHiPEPrologue(MF, *SaveBlock);
1039f22ef01cSRoman Divacky }
1040f22ef01cSRoman Divacky
1041f22ef01cSRoman Divacky /// replaceFrameIndices - Replace all MO_FrameIndex operands with physical
1042f22ef01cSRoman Divacky /// register references and actual offsets.
replaceFrameIndices(MachineFunction & MF)10434ba319b5SDimitry Andric void PEI::replaceFrameIndices(MachineFunction &MF) {
10444ba319b5SDimitry Andric const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
10454ba319b5SDimitry Andric if (!TFI.needsFrameIndexResolution(MF)) return;
1046f22ef01cSRoman Divacky
1047f785676fSDimitry Andric // Store SPAdj at exit of a basic block.
1048f785676fSDimitry Andric SmallVector<int, 8> SPState;
10494ba319b5SDimitry Andric SPState.resize(MF.getNumBlockIDs());
1050d88c1a5aSDimitry Andric df_iterator_default_set<MachineBasicBlock*> Reachable;
1051f785676fSDimitry Andric
1052f785676fSDimitry Andric // Iterate over the reachable blocks in DFS order.
10534ba319b5SDimitry Andric for (auto DFI = df_ext_begin(&MF, Reachable), DFE = df_ext_end(&MF, Reachable);
1054f785676fSDimitry Andric DFI != DFE; ++DFI) {
1055f785676fSDimitry Andric int SPAdj = 0;
1056f785676fSDimitry Andric // Check the exit state of the DFS stack predecessor.
1057f785676fSDimitry Andric if (DFI.getPathLength() >= 2) {
1058f785676fSDimitry Andric MachineBasicBlock *StackPred = DFI.getPath(DFI.getPathLength() - 2);
1059f785676fSDimitry Andric assert(Reachable.count(StackPred) &&
1060f785676fSDimitry Andric "DFS stack predecessor is already visited.\n");
1061f785676fSDimitry Andric SPAdj = SPState[StackPred->getNumber()];
1062f785676fSDimitry Andric }
1063f785676fSDimitry Andric MachineBasicBlock *BB = *DFI;
10644ba319b5SDimitry Andric replaceFrameIndices(BB, MF, SPAdj);
1065f785676fSDimitry Andric SPState[BB->getNumber()] = SPAdj;
1066f785676fSDimitry Andric }
1067f785676fSDimitry Andric
1068f785676fSDimitry Andric // Handle the unreachable blocks.
10694ba319b5SDimitry Andric for (auto &BB : MF) {
10707d523365SDimitry Andric if (Reachable.count(&BB))
1071f785676fSDimitry Andric // Already handled in DFS traversal.
1072f785676fSDimitry Andric continue;
1073f785676fSDimitry Andric int SPAdj = 0;
10744ba319b5SDimitry Andric replaceFrameIndices(&BB, MF, SPAdj);
1075f785676fSDimitry Andric }
1076f785676fSDimitry Andric }
1077f785676fSDimitry Andric
replaceFrameIndices(MachineBasicBlock * BB,MachineFunction & MF,int & SPAdj)10784ba319b5SDimitry Andric void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
1079f785676fSDimitry Andric int &SPAdj) {
10804ba319b5SDimitry Andric assert(MF.getSubtarget().getRegisterInfo() &&
108139d628a0SDimitry Andric "getRegisterInfo() must be implemented!");
10824ba319b5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
10834ba319b5SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
10844ba319b5SDimitry Andric const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
1085f22ef01cSRoman Divacky
1086d88c1a5aSDimitry Andric if (RS && FrameIndexEliminationScavenging)
1087d88c1a5aSDimitry Andric RS->enterBasicBlock(*BB);
1088f22ef01cSRoman Divacky
108939d628a0SDimitry Andric bool InsideCallSequence = false;
109039d628a0SDimitry Andric
1091f22ef01cSRoman Divacky for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
10927a7e6055SDimitry Andric if (TII.isFrameInstr(*I)) {
10937a7e6055SDimitry Andric InsideCallSequence = TII.isFrameSetup(*I);
10943ca95b02SDimitry Andric SPAdj += TII.getSPAdjust(*I);
10954ba319b5SDimitry Andric I = TFI->eliminateCallFramePseudoInstr(MF, *BB, I);
1096f22ef01cSRoman Divacky continue;
1097f22ef01cSRoman Divacky }
1098f22ef01cSRoman Divacky
10993ca95b02SDimitry Andric MachineInstr &MI = *I;
1100f22ef01cSRoman Divacky bool DoIncr = true;
11013ca95b02SDimitry Andric bool DidFinishLoop = true;
11023ca95b02SDimitry Andric for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
11033ca95b02SDimitry Andric if (!MI.getOperand(i).isFI())
1104139f7f9bSDimitry Andric continue;
1105139f7f9bSDimitry Andric
11067d523365SDimitry Andric // Frame indices in debug values are encoded in a target independent
1107f785676fSDimitry Andric // way with simply the frame index and offset rather than any
1108f785676fSDimitry Andric // target-specific addressing mode.
11093ca95b02SDimitry Andric if (MI.isDebugValue()) {
11107d523365SDimitry Andric assert(i == 0 && "Frame indices can only appear as the first "
1111f785676fSDimitry Andric "operand of a DBG_VALUE machine instruction");
1112f785676fSDimitry Andric unsigned Reg;
11132cab237bSDimitry Andric int64_t Offset =
11144ba319b5SDimitry Andric TFI->getFrameIndexReference(MF, MI.getOperand(0).getIndex(), Reg);
11153ca95b02SDimitry Andric MI.getOperand(0).ChangeToRegister(Reg, false /*isDef*/);
11164ba319b5SDimitry Andric MI.getOperand(0).setIsDebug();
11172cab237bSDimitry Andric auto *DIExpr = DIExpression::prepend(MI.getDebugExpression(),
11182cab237bSDimitry Andric DIExpression::NoDeref, Offset);
11192cab237bSDimitry Andric MI.getOperand(3).setMetadata(DIExpr);
1120f785676fSDimitry Andric continue;
1121f785676fSDimitry Andric }
1122f785676fSDimitry Andric
112339d628a0SDimitry Andric // TODO: This code should be commoned with the code for
112439d628a0SDimitry Andric // PATCHPOINT. There's no good reason for the difference in
112539d628a0SDimitry Andric // implementation other than historical accident. The only
112639d628a0SDimitry Andric // remaining difference is the unconditional use of the stack
112739d628a0SDimitry Andric // pointer as the base register.
11283ca95b02SDimitry Andric if (MI.getOpcode() == TargetOpcode::STATEPOINT) {
11293ca95b02SDimitry Andric assert((!MI.isDebugValue() || i == 0) &&
113039d628a0SDimitry Andric "Frame indicies can only appear as the first operand of a "
113139d628a0SDimitry Andric "DBG_VALUE machine instruction");
113239d628a0SDimitry Andric unsigned Reg;
11333ca95b02SDimitry Andric MachineOperand &Offset = MI.getOperand(i + 1);
11343ca95b02SDimitry Andric int refOffset = TFI->getFrameIndexReferencePreferSP(
11354ba319b5SDimitry Andric MF, MI.getOperand(i).getIndex(), Reg, /*IgnoreSPUpdates*/ false);
1136b5893f02SDimitry Andric Offset.setImm(Offset.getImm() + refOffset + SPAdj);
11373ca95b02SDimitry Andric MI.getOperand(i).ChangeToRegister(Reg, false /*isDef*/);
113839d628a0SDimitry Andric continue;
113939d628a0SDimitry Andric }
114039d628a0SDimitry Andric
1141f22ef01cSRoman Divacky // Some instructions (e.g. inline asm instructions) can have
1142f22ef01cSRoman Divacky // multiple frame indices and/or cause eliminateFrameIndex
1143f22ef01cSRoman Divacky // to insert more than one instruction. We need the register
1144f22ef01cSRoman Divacky // scavenger to go through all of these instructions so that
1145f22ef01cSRoman Divacky // it can update its register information. We keep the
1146f22ef01cSRoman Divacky // iterator at the point before insertion so that we can
1147f22ef01cSRoman Divacky // revisit them in full.
1148f22ef01cSRoman Divacky bool AtBeginning = (I == BB->begin());
1149f22ef01cSRoman Divacky if (!AtBeginning) --I;
1150f22ef01cSRoman Divacky
1151f22ef01cSRoman Divacky // If this instruction has a FrameIndex operand, we need to
1152f22ef01cSRoman Divacky // use that target machine register info object to eliminate
1153f22ef01cSRoman Divacky // it.
1154139f7f9bSDimitry Andric TRI.eliminateFrameIndex(MI, SPAdj, i,
1155d88c1a5aSDimitry Andric FrameIndexEliminationScavenging ? RS : nullptr);
1156f22ef01cSRoman Divacky
1157f22ef01cSRoman Divacky // Reset the iterator if we were at the beginning of the BB.
1158f22ef01cSRoman Divacky if (AtBeginning) {
1159f22ef01cSRoman Divacky I = BB->begin();
1160f22ef01cSRoman Divacky DoIncr = false;
1161f22ef01cSRoman Divacky }
1162f22ef01cSRoman Divacky
11633ca95b02SDimitry Andric DidFinishLoop = false;
1164f22ef01cSRoman Divacky break;
1165f22ef01cSRoman Divacky }
1166f22ef01cSRoman Divacky
11670f0f2bfaSDimitry Andric // If we are looking at a call sequence, we need to keep track of
11680f0f2bfaSDimitry Andric // the SP adjustment made by each instruction in the sequence.
11690f0f2bfaSDimitry Andric // This includes both the frame setup/destroy pseudos (handled above),
11700f0f2bfaSDimitry Andric // as well as other instructions that have side effects w.r.t the SP.
11710f0f2bfaSDimitry Andric // Note that this must come after eliminateFrameIndex, because
11720f0f2bfaSDimitry Andric // if I itself referred to a frame index, we shouldn't count its own
11730f0f2bfaSDimitry Andric // adjustment.
11743ca95b02SDimitry Andric if (DidFinishLoop && InsideCallSequence)
11750f0f2bfaSDimitry Andric SPAdj += TII.getSPAdjust(MI);
11760f0f2bfaSDimitry Andric
1177f22ef01cSRoman Divacky if (DoIncr && I != BB->end()) ++I;
1178f22ef01cSRoman Divacky
1179f22ef01cSRoman Divacky // Update register states.
1180d88c1a5aSDimitry Andric if (RS && FrameIndexEliminationScavenging && DidFinishLoop)
11813ca95b02SDimitry Andric RS->forward(MI);
1182f22ef01cSRoman Divacky }
1183f22ef01cSRoman Divacky }
1184