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