xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/PrologEpilogInserter.cpp (revision 62987288060ff68c817b7056815aa9fb8ba8ecd7)
10b57cec5SDimitry Andric //===- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function ---===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This pass is responsible for finalizing the functions frame layout, saving
100b57cec5SDimitry Andric // callee saved registers, and for emitting prolog & epilog code for the
110b57cec5SDimitry Andric // function.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric // This pass must be run after register allocation.  After this pass is
140b57cec5SDimitry Andric // executed, it is illegal to construct MO_FrameIndex operands.
150b57cec5SDimitry Andric //
160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
190b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
230b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
240b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
250b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
260b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
390b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
430b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
440b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
450b57cec5SDimitry Andric #include "llvm/CodeGen/WinEHFuncInfo.h"
460b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
470b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h"
480b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
490b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
500b57cec5SDimitry Andric #include "llvm/IR/Function.h"
510b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h"
520b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
53480093f4SDimitry Andric #include "llvm/InitializePasses.h"
540b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
550b57cec5SDimitry Andric #include "llvm/Pass.h"
560b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
570b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
580b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
59bdd1243dSDimitry Andric #include "llvm/Support/FormatVariadic.h"
600b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
610b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
620b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
630b57cec5SDimitry Andric #include <algorithm>
640b57cec5SDimitry Andric #include <cassert>
650b57cec5SDimitry Andric #include <cstdint>
660b57cec5SDimitry Andric #include <functional>
670b57cec5SDimitry Andric #include <limits>
680b57cec5SDimitry Andric #include <utility>
690b57cec5SDimitry Andric #include <vector>
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric using namespace llvm;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric #define DEBUG_TYPE "prologepilog"
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric using MBBVector = SmallVector<MachineBasicBlock *, 4>;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric STATISTIC(NumLeafFuncWithSpills, "Number of leaf functions with CSRs");
780b57cec5SDimitry Andric STATISTIC(NumFuncSeen, "Number of functions seen in PEI");
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric namespace {
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric class PEI : public MachineFunctionPass {
840b57cec5SDimitry Andric public:
850b57cec5SDimitry Andric   static char ID;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   PEI() : MachineFunctionPass(ID) {
880b57cec5SDimitry Andric     initializePEIPass(*PassRegistry::getPassRegistry());
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   /// runOnMachineFunction - Insert prolog/epilog code and replace abstract
940b57cec5SDimitry Andric   /// frame indexes with appropriate references.
950b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric private:
9806c3fb27SDimitry Andric   RegScavenger *RS = nullptr;
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved
1010b57cec5SDimitry Andric   // stack frame indexes.
1020b57cec5SDimitry Andric   unsigned MinCSFrameIndex = std::numeric_limits<unsigned>::max();
1030b57cec5SDimitry Andric   unsigned MaxCSFrameIndex = 0;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   // Save and Restore blocks of the current function. Typically there is a
1060b57cec5SDimitry Andric   // single save block, unless Windows EH funclets are involved.
1070b57cec5SDimitry Andric   MBBVector SaveBlocks;
1080b57cec5SDimitry Andric   MBBVector RestoreBlocks;
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   // Flag to control whether to use the register scavenger to resolve
1110b57cec5SDimitry Andric   // frame index materialization registers. Set according to
1120b57cec5SDimitry Andric   // TRI->requiresFrameIndexScavenging() for the current function.
11306c3fb27SDimitry Andric   bool FrameIndexVirtualScavenging = false;
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   // Flag to control whether the scavenger should be passed even though
1160b57cec5SDimitry Andric   // FrameIndexVirtualScavenging is used.
11706c3fb27SDimitry Andric   bool FrameIndexEliminationScavenging = false;
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   // Emit remarks.
1200b57cec5SDimitry Andric   MachineOptimizationRemarkEmitter *ORE = nullptr;
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   void calculateCallFrameInfo(MachineFunction &MF);
1230b57cec5SDimitry Andric   void calculateSaveRestoreBlocks(MachineFunction &MF);
1240b57cec5SDimitry Andric   void spillCalleeSavedRegs(MachineFunction &MF);
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   void calculateFrameObjectOffsets(MachineFunction &MF);
1270b57cec5SDimitry Andric   void replaceFrameIndices(MachineFunction &MF);
1280b57cec5SDimitry Andric   void replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
1290b57cec5SDimitry Andric                            int &SPAdj);
130bdd1243dSDimitry Andric   // Frame indices in debug values are encoded in a target independent
131bdd1243dSDimitry Andric   // way with simply the frame index and offset rather than any
132bdd1243dSDimitry Andric   // target-specific addressing mode.
133bdd1243dSDimitry Andric   bool replaceFrameIndexDebugInstr(MachineFunction &MF, MachineInstr &MI,
134bdd1243dSDimitry Andric                                    unsigned OpIdx, int SPAdj = 0);
135bdd1243dSDimitry Andric   // Does same as replaceFrameIndices but using the backward MIR walk and
1365f757f3fSDimitry Andric   // backward register scavenger walk.
1375f757f3fSDimitry Andric   void replaceFrameIndicesBackward(MachineFunction &MF);
138bdd1243dSDimitry Andric   void replaceFrameIndicesBackward(MachineBasicBlock *BB, MachineFunction &MF,
139bdd1243dSDimitry Andric                                    int &SPAdj);
140bdd1243dSDimitry Andric 
1410b57cec5SDimitry Andric   void insertPrologEpilogCode(MachineFunction &MF);
14281ad6265SDimitry Andric   void insertZeroCallUsedRegs(MachineFunction &MF);
1430b57cec5SDimitry Andric };
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric } // end anonymous namespace
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric char PEI::ID = 0;
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric char &llvm::PrologEpilogCodeInserterID = PEI::ID;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(PEI, DEBUG_TYPE, "Prologue/Epilogue Insertion", false,
1520b57cec5SDimitry Andric                       false)
1530fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
1540fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
1550b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
1560b57cec5SDimitry Andric INITIALIZE_PASS_END(PEI, DEBUG_TYPE,
1570b57cec5SDimitry Andric                     "Prologue/Epilogue Insertion & Frame Finalization", false,
1580b57cec5SDimitry Andric                     false)
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric MachineFunctionPass *llvm::createPrologEpilogInserterPass() {
1610b57cec5SDimitry Andric   return new PEI();
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric STATISTIC(NumBytesStackSpace,
1650b57cec5SDimitry Andric           "Number of bytes used for stack in all functions");
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric void PEI::getAnalysisUsage(AnalysisUsage &AU) const {
1680b57cec5SDimitry Andric   AU.setPreservesCFG();
1690fca6ea1SDimitry Andric   AU.addPreserved<MachineLoopInfoWrapperPass>();
1700fca6ea1SDimitry Andric   AU.addPreserved<MachineDominatorTreeWrapperPass>();
1710b57cec5SDimitry Andric   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
1720b57cec5SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric /// StackObjSet - A set of stack object indexes
1760b57cec5SDimitry Andric using StackObjSet = SmallSetVector<int, 8>;
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric using SavedDbgValuesMap =
1790b57cec5SDimitry Andric     SmallDenseMap<MachineBasicBlock *, SmallVector<MachineInstr *, 4>, 4>;
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric /// Stash DBG_VALUEs that describe parameters and which are placed at the start
1820b57cec5SDimitry Andric /// of the block. Later on, after the prologue code has been emitted, the
1830b57cec5SDimitry Andric /// stashed DBG_VALUEs will be reinserted at the start of the block.
1840b57cec5SDimitry Andric static void stashEntryDbgValues(MachineBasicBlock &MBB,
1850b57cec5SDimitry Andric                                 SavedDbgValuesMap &EntryDbgValues) {
1860b57cec5SDimitry Andric   SmallVector<const MachineInstr *, 4> FrameIndexValues;
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   for (auto &MI : MBB) {
1890b57cec5SDimitry Andric     if (!MI.isDebugInstr())
1900b57cec5SDimitry Andric       break;
1910b57cec5SDimitry Andric     if (!MI.isDebugValue() || !MI.getDebugVariable()->isParameter())
1920b57cec5SDimitry Andric       continue;
193fe6060f1SDimitry Andric     if (any_of(MI.debug_operands(),
194fe6060f1SDimitry Andric                [](const MachineOperand &MO) { return MO.isFI(); })) {
1950b57cec5SDimitry Andric       // We can only emit valid locations for frame indices after the frame
1960b57cec5SDimitry Andric       // setup, so do not stash away them.
1970b57cec5SDimitry Andric       FrameIndexValues.push_back(&MI);
1980b57cec5SDimitry Andric       continue;
1990b57cec5SDimitry Andric     }
2000b57cec5SDimitry Andric     const DILocalVariable *Var = MI.getDebugVariable();
2010b57cec5SDimitry Andric     const DIExpression *Expr = MI.getDebugExpression();
2020b57cec5SDimitry Andric     auto Overlaps = [Var, Expr](const MachineInstr *DV) {
2030b57cec5SDimitry Andric       return Var == DV->getDebugVariable() &&
2040b57cec5SDimitry Andric              Expr->fragmentsOverlap(DV->getDebugExpression());
2050b57cec5SDimitry Andric     };
2060b57cec5SDimitry Andric     // See if the debug value overlaps with any preceding debug value that will
2070b57cec5SDimitry Andric     // not be stashed. If that is the case, then we can't stash this value, as
2080b57cec5SDimitry Andric     // we would then reorder the values at reinsertion.
2090b57cec5SDimitry Andric     if (llvm::none_of(FrameIndexValues, Overlaps))
2100b57cec5SDimitry Andric       EntryDbgValues[&MBB].push_back(&MI);
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   // Remove stashed debug values from the block.
2140b57cec5SDimitry Andric   if (EntryDbgValues.count(&MBB))
2150b57cec5SDimitry Andric     for (auto *MI : EntryDbgValues[&MBB])
2160b57cec5SDimitry Andric       MI->removeFromParent();
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric /// runOnMachineFunction - Insert prolog/epilog code and replace abstract
2200b57cec5SDimitry Andric /// frame indexes with appropriate references.
2210b57cec5SDimitry Andric bool PEI::runOnMachineFunction(MachineFunction &MF) {
2220b57cec5SDimitry Andric   NumFuncSeen++;
2230b57cec5SDimitry Andric   const Function &F = MF.getFunction();
2240b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
2250b57cec5SDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr;
2280b57cec5SDimitry Andric   FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(MF);
2290b57cec5SDimitry Andric   ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
2300b57cec5SDimitry Andric 
2310fca6ea1SDimitry Andric   // Calculate the MaxCallFrameSize value for the function's frame
2320fca6ea1SDimitry Andric   // information. Also eliminates call frame pseudo instructions.
2330b57cec5SDimitry Andric   calculateCallFrameInfo(MF);
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   // Determine placement of CSR spill/restore code and prolog/epilog code:
2360b57cec5SDimitry Andric   // place all spills in the entry block, all restores in return blocks.
2370b57cec5SDimitry Andric   calculateSaveRestoreBlocks(MF);
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   // Stash away DBG_VALUEs that should not be moved by insertion of prolog code.
2400b57cec5SDimitry Andric   SavedDbgValuesMap EntryDbgValues;
2410b57cec5SDimitry Andric   for (MachineBasicBlock *SaveBlock : SaveBlocks)
2420b57cec5SDimitry Andric     stashEntryDbgValues(*SaveBlock, EntryDbgValues);
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   // Handle CSR spilling and restoring, for targets that need it.
2455ffd83dbSDimitry Andric   if (MF.getTarget().usesPhysRegsForValues())
2460b57cec5SDimitry Andric     spillCalleeSavedRegs(MF);
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   // Allow the target machine to make final modifications to the function
2490b57cec5SDimitry Andric   // before the frame layout is finalized.
2500b57cec5SDimitry Andric   TFI->processFunctionBeforeFrameFinalized(MF, RS);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   // Calculate actual frame offsets for all abstract stack objects...
2530b57cec5SDimitry Andric   calculateFrameObjectOffsets(MF);
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   // Add prolog and epilog code to the function.  This function is required
2560b57cec5SDimitry Andric   // to align the stack frame as necessary for any stack variables or
2570b57cec5SDimitry Andric   // called functions.  Because of this, calculateCalleeSavedRegisters()
2580b57cec5SDimitry Andric   // must be called before this function in order to set the AdjustsStack
2590b57cec5SDimitry Andric   // and MaxCallFrameSize variables.
2600b57cec5SDimitry Andric   if (!F.hasFnAttribute(Attribute::Naked))
2610b57cec5SDimitry Andric     insertPrologEpilogCode(MF);
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   // Reinsert stashed debug values at the start of the entry blocks.
2640b57cec5SDimitry Andric   for (auto &I : EntryDbgValues)
2650b57cec5SDimitry Andric     I.first->insert(I.first->begin(), I.second.begin(), I.second.end());
2660b57cec5SDimitry Andric 
2675ffd83dbSDimitry Andric   // Allow the target machine to make final modifications to the function
2685ffd83dbSDimitry Andric   // before the frame layout is finalized.
2695ffd83dbSDimitry Andric   TFI->processFunctionBeforeFrameIndicesReplaced(MF, RS);
2705ffd83dbSDimitry Andric 
2710b57cec5SDimitry Andric   // Replace all MO_FrameIndex operands with physical register references
2720b57cec5SDimitry Andric   // and actual offsets.
2735f757f3fSDimitry Andric   if (TFI->needsFrameIndexResolution(MF)) {
2745f757f3fSDimitry Andric     // Allow the target to determine this after knowing the frame size.
2755f757f3fSDimitry Andric     FrameIndexEliminationScavenging =
2765f757f3fSDimitry Andric         (RS && !FrameIndexVirtualScavenging) ||
2775f757f3fSDimitry Andric         TRI->requiresFrameIndexReplacementScavenging(MF);
2785f757f3fSDimitry Andric 
2795f757f3fSDimitry Andric     if (TRI->eliminateFrameIndicesBackwards())
2805f757f3fSDimitry Andric       replaceFrameIndicesBackward(MF);
2815f757f3fSDimitry Andric     else
2820b57cec5SDimitry Andric       replaceFrameIndices(MF);
2835f757f3fSDimitry Andric   }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   // If register scavenging is needed, as we've enabled doing it as a
2860b57cec5SDimitry Andric   // post-pass, scavenge the virtual registers that frame index elimination
2870b57cec5SDimitry Andric   // inserted.
2880b57cec5SDimitry Andric   if (TRI->requiresRegisterScavenging(MF) && FrameIndexVirtualScavenging)
2890b57cec5SDimitry Andric     scavengeFrameVirtualRegs(MF, *RS);
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   // Warn on stack size when we exceeds the given limit.
2920b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
2930b57cec5SDimitry Andric   uint64_t StackSize = MFI.getStackSize();
294fe6060f1SDimitry Andric 
2955f757f3fSDimitry Andric   uint64_t Threshold = TFI->getStackThreshold();
296fe6060f1SDimitry Andric   if (MF.getFunction().hasFnAttribute("warn-stack-size")) {
297fe6060f1SDimitry Andric     bool Failed = MF.getFunction()
298fe6060f1SDimitry Andric                       .getFnAttribute("warn-stack-size")
299fe6060f1SDimitry Andric                       .getValueAsString()
300fe6060f1SDimitry Andric                       .getAsInteger(10, Threshold);
301fe6060f1SDimitry Andric     // Verifier should have caught this.
302fe6060f1SDimitry Andric     assert(!Failed && "Invalid warn-stack-size fn attr value");
303fe6060f1SDimitry Andric     (void)Failed;
304fe6060f1SDimitry Andric   }
305bdd1243dSDimitry Andric   uint64_t UnsafeStackSize = MFI.getUnsafeStackSize();
306bdd1243dSDimitry Andric   if (MF.getFunction().hasFnAttribute(Attribute::SafeStack))
307bdd1243dSDimitry Andric     StackSize += UnsafeStackSize;
308bdd1243dSDimitry Andric 
309fe6060f1SDimitry Andric   if (StackSize > Threshold) {
310349cc55cSDimitry Andric     DiagnosticInfoStackSize DiagStackSize(F, StackSize, Threshold, DS_Warning);
3110b57cec5SDimitry Andric     F.getContext().diagnose(DiagStackSize);
312bdd1243dSDimitry Andric     int64_t SpillSize = 0;
313bdd1243dSDimitry Andric     for (int Idx = MFI.getObjectIndexBegin(), End = MFI.getObjectIndexEnd();
314bdd1243dSDimitry Andric          Idx != End; ++Idx) {
315bdd1243dSDimitry Andric       if (MFI.isSpillSlotObjectIndex(Idx))
316bdd1243dSDimitry Andric         SpillSize += MFI.getObjectSize(Idx);
3170b57cec5SDimitry Andric     }
318bdd1243dSDimitry Andric 
31906c3fb27SDimitry Andric     [[maybe_unused]] float SpillPct =
320bdd1243dSDimitry Andric         static_cast<float>(SpillSize) / static_cast<float>(StackSize);
32106c3fb27SDimitry Andric     LLVM_DEBUG(
322bdd1243dSDimitry Andric         dbgs() << formatv("{0}/{1} ({3:P}) spills, {2}/{1} ({4:P}) variables",
32306c3fb27SDimitry Andric                           SpillSize, StackSize, StackSize - SpillSize, SpillPct,
32406c3fb27SDimitry Andric                           1.0f - SpillPct));
325bdd1243dSDimitry Andric     if (UnsafeStackSize != 0) {
32606c3fb27SDimitry Andric       LLVM_DEBUG(dbgs() << formatv(", {0}/{2} ({1:P}) unsafe stack",
32706c3fb27SDimitry Andric                                    UnsafeStackSize,
32806c3fb27SDimitry Andric                                    static_cast<float>(UnsafeStackSize) /
32906c3fb27SDimitry Andric                                        static_cast<float>(StackSize),
33006c3fb27SDimitry Andric                                    StackSize));
331bdd1243dSDimitry Andric     }
33206c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "\n");
333bdd1243dSDimitry Andric   }
334bdd1243dSDimitry Andric 
3350b57cec5SDimitry Andric   ORE->emit([&]() {
3360b57cec5SDimitry Andric     return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "StackSize",
3370b57cec5SDimitry Andric                                              MF.getFunction().getSubprogram(),
3380b57cec5SDimitry Andric                                              &MF.front())
3395f757f3fSDimitry Andric            << ore::NV("NumStackBytes", StackSize)
3405f757f3fSDimitry Andric            << " stack bytes in function '"
3415f757f3fSDimitry Andric            << ore::NV("Function", MF.getFunction().getName()) << "'";
3420b57cec5SDimitry Andric   });
3430b57cec5SDimitry Andric 
344*62987288SDimitry Andric   // Emit any remarks implemented for the target, based on final frame layout.
345*62987288SDimitry Andric   TFI->emitRemarks(MF, ORE);
346*62987288SDimitry Andric 
3470b57cec5SDimitry Andric   delete RS;
3480b57cec5SDimitry Andric   SaveBlocks.clear();
3490b57cec5SDimitry Andric   RestoreBlocks.clear();
3500b57cec5SDimitry Andric   MFI.setSavePoint(nullptr);
3510b57cec5SDimitry Andric   MFI.setRestorePoint(nullptr);
3520b57cec5SDimitry Andric   return true;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550fca6ea1SDimitry Andric /// Calculate the MaxCallFrameSize variable for the function's frame
3560fca6ea1SDimitry Andric /// information and eliminate call frame pseudo instructions.
3570b57cec5SDimitry Andric void PEI::calculateCallFrameInfo(MachineFunction &MF) {
3580b57cec5SDimitry Andric   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
3590b57cec5SDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
3600b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric   // Get the function call frame set-up and tear-down instruction opcode
3630b57cec5SDimitry Andric   unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
3640b57cec5SDimitry Andric   unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric   // Early exit for targets which have no call frame setup/destroy pseudo
3670b57cec5SDimitry Andric   // instructions.
3680b57cec5SDimitry Andric   if (FrameSetupOpcode == ~0u && FrameDestroyOpcode == ~0u)
3690b57cec5SDimitry Andric     return;
3700b57cec5SDimitry Andric 
3710fca6ea1SDimitry Andric   // (Re-)Compute the MaxCallFrameSize.
37236b606aeSDimitry Andric   [[maybe_unused]] uint64_t MaxCFSIn =
37336b606aeSDimitry Andric       MFI.isMaxCallFrameSizeComputed() ? MFI.getMaxCallFrameSize() : UINT64_MAX;
3740b57cec5SDimitry Andric   std::vector<MachineBasicBlock::iterator> FrameSDOps;
3750fca6ea1SDimitry Andric   MFI.computeMaxCallFrameSize(MF, &FrameSDOps);
3760fca6ea1SDimitry Andric   assert(MFI.getMaxCallFrameSize() <= MaxCFSIn &&
3770fca6ea1SDimitry Andric          "Recomputing MaxCFS gave a larger value.");
3780fca6ea1SDimitry Andric   assert((FrameSDOps.empty() || MF.getFrameInfo().adjustsStack()) &&
3790fca6ea1SDimitry Andric          "AdjustsStack not set in presence of a frame pseudo instruction.");
3800b57cec5SDimitry Andric 
3815f757f3fSDimitry Andric   if (TFI->canSimplifyCallFramePseudos(MF)) {
3820b57cec5SDimitry Andric     // If call frames are not being included as part of the stack frame, and
3830b57cec5SDimitry Andric     // the target doesn't indicate otherwise, remove the call frame pseudos
3840b57cec5SDimitry Andric     // here. The sub/add sp instruction pairs are still inserted, but we don't
3850b57cec5SDimitry Andric     // need to track the SP adjustment for frame index elimination.
3865f757f3fSDimitry Andric     for (MachineBasicBlock::iterator I : FrameSDOps)
3870b57cec5SDimitry Andric       TFI->eliminateCallFramePseudoInstr(MF, *I->getParent(), I);
3885f757f3fSDimitry Andric 
3895f757f3fSDimitry Andric     // We can't track the call frame size after call frame pseudos have been
3905f757f3fSDimitry Andric     // eliminated. Set it to zero everywhere to keep MachineVerifier happy.
3915f757f3fSDimitry Andric     for (MachineBasicBlock &MBB : MF)
3925f757f3fSDimitry Andric       MBB.setCallFrameSize(0);
3930b57cec5SDimitry Andric   }
3940b57cec5SDimitry Andric }
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric /// Compute the sets of entry and return blocks for saving and restoring
3970b57cec5SDimitry Andric /// callee-saved registers, and placing prolog and epilog code.
3980b57cec5SDimitry Andric void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) {
3990b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   // Even when we do not change any CSR, we still want to insert the
4020b57cec5SDimitry Andric   // prologue and epilogue of the function.
4030b57cec5SDimitry Andric   // So set the save points for those.
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   // Use the points found by shrink-wrapping, if any.
4060b57cec5SDimitry Andric   if (MFI.getSavePoint()) {
4070b57cec5SDimitry Andric     SaveBlocks.push_back(MFI.getSavePoint());
4080b57cec5SDimitry Andric     assert(MFI.getRestorePoint() && "Both restore and save must be set");
4090b57cec5SDimitry Andric     MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
4100b57cec5SDimitry Andric     // If RestoreBlock does not have any successor and is not a return block
4110b57cec5SDimitry Andric     // then the end point is unreachable and we do not need to insert any
4120b57cec5SDimitry Andric     // epilogue.
4130b57cec5SDimitry Andric     if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
4140b57cec5SDimitry Andric       RestoreBlocks.push_back(RestoreBlock);
4150b57cec5SDimitry Andric     return;
4160b57cec5SDimitry Andric   }
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   // Save refs to entry and return blocks.
4190b57cec5SDimitry Andric   SaveBlocks.push_back(&MF.front());
4200b57cec5SDimitry Andric   for (MachineBasicBlock &MBB : MF) {
4210b57cec5SDimitry Andric     if (MBB.isEHFuncletEntry())
4220b57cec5SDimitry Andric       SaveBlocks.push_back(&MBB);
4230b57cec5SDimitry Andric     if (MBB.isReturnBlock())
4240b57cec5SDimitry Andric       RestoreBlocks.push_back(&MBB);
4250b57cec5SDimitry Andric   }
4260b57cec5SDimitry Andric }
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric static void assignCalleeSavedSpillSlots(MachineFunction &F,
4290b57cec5SDimitry Andric                                         const BitVector &SavedRegs,
4300b57cec5SDimitry Andric                                         unsigned &MinCSFrameIndex,
4310b57cec5SDimitry Andric                                         unsigned &MaxCSFrameIndex) {
4320b57cec5SDimitry Andric   if (SavedRegs.empty())
4330b57cec5SDimitry Andric     return;
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   const TargetRegisterInfo *RegInfo = F.getSubtarget().getRegisterInfo();
4360b57cec5SDimitry Andric   const MCPhysReg *CSRegs = F.getRegInfo().getCalleeSavedRegs();
437349cc55cSDimitry Andric   BitVector CSMask(SavedRegs.size());
438349cc55cSDimitry Andric 
439349cc55cSDimitry Andric   for (unsigned i = 0; CSRegs[i]; ++i)
440349cc55cSDimitry Andric     CSMask.set(CSRegs[i]);
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   std::vector<CalleeSavedInfo> CSI;
4430b57cec5SDimitry Andric   for (unsigned i = 0; CSRegs[i]; ++i) {
4440b57cec5SDimitry Andric     unsigned Reg = CSRegs[i];
445349cc55cSDimitry Andric     if (SavedRegs.test(Reg)) {
446349cc55cSDimitry Andric       bool SavedSuper = false;
447349cc55cSDimitry Andric       for (const MCPhysReg &SuperReg : RegInfo->superregs(Reg)) {
448349cc55cSDimitry Andric         // Some backends set all aliases for some registers as saved, such as
449349cc55cSDimitry Andric         // Mips's $fp, so they appear in SavedRegs but not CSRegs.
450349cc55cSDimitry Andric         if (SavedRegs.test(SuperReg) && CSMask.test(SuperReg)) {
451349cc55cSDimitry Andric           SavedSuper = true;
452349cc55cSDimitry Andric           break;
453349cc55cSDimitry Andric         }
454349cc55cSDimitry Andric       }
455349cc55cSDimitry Andric 
456349cc55cSDimitry Andric       if (!SavedSuper)
4570b57cec5SDimitry Andric         CSI.push_back(CalleeSavedInfo(Reg));
4580b57cec5SDimitry Andric     }
459349cc55cSDimitry Andric   }
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric   const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
4620b57cec5SDimitry Andric   MachineFrameInfo &MFI = F.getFrameInfo();
463fe6060f1SDimitry Andric   if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI, MinCSFrameIndex,
464fe6060f1SDimitry Andric                                         MaxCSFrameIndex)) {
4650b57cec5SDimitry Andric     // If target doesn't implement this, use generic code.
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric     if (CSI.empty())
4680b57cec5SDimitry Andric       return; // Early exit if no callee saved registers are modified!
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric     unsigned NumFixedSpillSlots;
4710b57cec5SDimitry Andric     const TargetFrameLowering::SpillSlot *FixedSpillSlots =
4720b57cec5SDimitry Andric         TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots);
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric     // Now that we know which registers need to be saved and restored, allocate
4750b57cec5SDimitry Andric     // stack slots for them.
4760b57cec5SDimitry Andric     for (auto &CS : CSI) {
4770b57cec5SDimitry Andric       // If the target has spilled this register to another register, we don't
4780b57cec5SDimitry Andric       // need to allocate a stack slot.
4790b57cec5SDimitry Andric       if (CS.isSpilledToReg())
4800b57cec5SDimitry Andric         continue;
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric       unsigned Reg = CS.getReg();
4830b57cec5SDimitry Andric       const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric       int FrameIdx;
4860b57cec5SDimitry Andric       if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) {
4870b57cec5SDimitry Andric         CS.setFrameIdx(FrameIdx);
4880b57cec5SDimitry Andric         continue;
4890b57cec5SDimitry Andric       }
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric       // Check to see if this physreg must be spilled to a particular stack slot
4920b57cec5SDimitry Andric       // on this target.
4930b57cec5SDimitry Andric       const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots;
4940b57cec5SDimitry Andric       while (FixedSlot != FixedSpillSlots + NumFixedSpillSlots &&
4950b57cec5SDimitry Andric              FixedSlot->Reg != Reg)
4960b57cec5SDimitry Andric         ++FixedSlot;
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric       unsigned Size = RegInfo->getSpillSize(*RC);
4990b57cec5SDimitry Andric       if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
5000b57cec5SDimitry Andric         // Nope, just spill it anywhere convenient.
501fe6060f1SDimitry Andric         Align Alignment = RegInfo->getSpillAlign(*RC);
5020b57cec5SDimitry Andric         // We may not be able to satisfy the desired alignment specification of
5030b57cec5SDimitry Andric         // the TargetRegisterClass if the stack alignment is smaller. Use the
5040b57cec5SDimitry Andric         // min.
5055ffd83dbSDimitry Andric         Alignment = std::min(Alignment, TFI->getStackAlign());
5065ffd83dbSDimitry Andric         FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
5070b57cec5SDimitry Andric         if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
5080b57cec5SDimitry Andric         if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
5090b57cec5SDimitry Andric       } else {
5100b57cec5SDimitry Andric         // Spill it to the stack where we must.
5110b57cec5SDimitry Andric         FrameIdx = MFI.CreateFixedSpillStackObject(Size, FixedSlot->Offset);
5120b57cec5SDimitry Andric       }
5130b57cec5SDimitry Andric 
5140b57cec5SDimitry Andric       CS.setFrameIdx(FrameIdx);
5150b57cec5SDimitry Andric     }
5160b57cec5SDimitry Andric   }
5170b57cec5SDimitry Andric 
5180b57cec5SDimitry Andric   MFI.setCalleeSavedInfo(CSI);
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric /// Helper function to update the liveness information for the callee-saved
5220b57cec5SDimitry Andric /// registers.
5230b57cec5SDimitry Andric static void updateLiveness(MachineFunction &MF) {
5240b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
5250b57cec5SDimitry Andric   // Visited will contain all the basic blocks that are in the region
5260b57cec5SDimitry Andric   // where the callee saved registers are alive:
5270b57cec5SDimitry Andric   // - Anything that is not Save or Restore -> LiveThrough.
5280b57cec5SDimitry Andric   // - Save -> LiveIn.
5290b57cec5SDimitry Andric   // - Restore -> LiveOut.
5300b57cec5SDimitry Andric   // The live-out is not attached to the block, so no need to keep
5310b57cec5SDimitry Andric   // Restore in this set.
5320b57cec5SDimitry Andric   SmallPtrSet<MachineBasicBlock *, 8> Visited;
5330b57cec5SDimitry Andric   SmallVector<MachineBasicBlock *, 8> WorkList;
5340b57cec5SDimitry Andric   MachineBasicBlock *Entry = &MF.front();
5350b57cec5SDimitry Andric   MachineBasicBlock *Save = MFI.getSavePoint();
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric   if (!Save)
5380b57cec5SDimitry Andric     Save = Entry;
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric   if (Entry != Save) {
5410b57cec5SDimitry Andric     WorkList.push_back(Entry);
5420b57cec5SDimitry Andric     Visited.insert(Entry);
5430b57cec5SDimitry Andric   }
5440b57cec5SDimitry Andric   Visited.insert(Save);
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   MachineBasicBlock *Restore = MFI.getRestorePoint();
5470b57cec5SDimitry Andric   if (Restore)
5480b57cec5SDimitry Andric     // By construction Restore cannot be visited, otherwise it
5490b57cec5SDimitry Andric     // means there exists a path to Restore that does not go
5500b57cec5SDimitry Andric     // through Save.
5510b57cec5SDimitry Andric     WorkList.push_back(Restore);
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric   while (!WorkList.empty()) {
5540b57cec5SDimitry Andric     const MachineBasicBlock *CurBB = WorkList.pop_back_val();
5550b57cec5SDimitry Andric     // By construction, the region that is after the save point is
5560b57cec5SDimitry Andric     // dominated by the Save and post-dominated by the Restore.
5570b57cec5SDimitry Andric     if (CurBB == Save && Save != Restore)
5580b57cec5SDimitry Andric       continue;
5590b57cec5SDimitry Andric     // Enqueue all the successors not already visited.
5600b57cec5SDimitry Andric     // Those are by construction either before Save or after Restore.
5610b57cec5SDimitry Andric     for (MachineBasicBlock *SuccBB : CurBB->successors())
5620b57cec5SDimitry Andric       if (Visited.insert(SuccBB).second)
5630b57cec5SDimitry Andric         WorkList.push_back(SuccBB);
5640b57cec5SDimitry Andric   }
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
5694824e7fdSDimitry Andric   for (const CalleeSavedInfo &I : CSI) {
5700b57cec5SDimitry Andric     for (MachineBasicBlock *MBB : Visited) {
5714824e7fdSDimitry Andric       MCPhysReg Reg = I.getReg();
5720b57cec5SDimitry Andric       // Add the callee-saved register as live-in.
5730b57cec5SDimitry Andric       // It's killed at the spill.
5740b57cec5SDimitry Andric       if (!MRI.isReserved(Reg) && !MBB->isLiveIn(Reg))
5750b57cec5SDimitry Andric         MBB->addLiveIn(Reg);
5760b57cec5SDimitry Andric     }
5770b57cec5SDimitry Andric     // If callee-saved register is spilled to another register rather than
5780b57cec5SDimitry Andric     // spilling to stack, the destination register has to be marked as live for
5790b57cec5SDimitry Andric     // each MBB between the prologue and epilogue so that it is not clobbered
5800b57cec5SDimitry Andric     // before it is reloaded in the epilogue. The Visited set contains all
5810b57cec5SDimitry Andric     // blocks outside of the region delimited by prologue/epilogue.
5824824e7fdSDimitry Andric     if (I.isSpilledToReg()) {
5830b57cec5SDimitry Andric       for (MachineBasicBlock &MBB : MF) {
5840b57cec5SDimitry Andric         if (Visited.count(&MBB))
5850b57cec5SDimitry Andric           continue;
5864824e7fdSDimitry Andric         MCPhysReg DstReg = I.getDstReg();
5870b57cec5SDimitry Andric         if (!MBB.isLiveIn(DstReg))
5880b57cec5SDimitry Andric           MBB.addLiveIn(DstReg);
5890b57cec5SDimitry Andric       }
5900b57cec5SDimitry Andric     }
5910b57cec5SDimitry Andric   }
5920b57cec5SDimitry Andric }
5930b57cec5SDimitry Andric 
594753f127fSDimitry Andric /// Insert spill code for the callee-saved registers used in the function.
5950b57cec5SDimitry Andric static void insertCSRSaves(MachineBasicBlock &SaveBlock,
5960b57cec5SDimitry Andric                            ArrayRef<CalleeSavedInfo> CSI) {
5970b57cec5SDimitry Andric   MachineFunction &MF = *SaveBlock.getParent();
5980b57cec5SDimitry Andric   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
5990b57cec5SDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
6000b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   MachineBasicBlock::iterator I = SaveBlock.begin();
6030b57cec5SDimitry Andric   if (!TFI->spillCalleeSavedRegisters(SaveBlock, I, CSI, TRI)) {
6040b57cec5SDimitry Andric     for (const CalleeSavedInfo &CS : CSI) {
6050b57cec5SDimitry Andric       // Insert the spill to the stack frame.
6060b57cec5SDimitry Andric       unsigned Reg = CS.getReg();
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric       if (CS.isSpilledToReg()) {
6090b57cec5SDimitry Andric         BuildMI(SaveBlock, I, DebugLoc(),
6100b57cec5SDimitry Andric                 TII.get(TargetOpcode::COPY), CS.getDstReg())
6110b57cec5SDimitry Andric           .addReg(Reg, getKillRegState(true));
6120b57cec5SDimitry Andric       } else {
6130b57cec5SDimitry Andric         const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
6140b57cec5SDimitry Andric         TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC,
615bdd1243dSDimitry Andric                                 TRI, Register());
6160b57cec5SDimitry Andric       }
6170b57cec5SDimitry Andric     }
6180b57cec5SDimitry Andric   }
6190b57cec5SDimitry Andric }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric /// Insert restore code for the callee-saved registers used in the function.
6220b57cec5SDimitry Andric static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
6230b57cec5SDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) {
6240b57cec5SDimitry Andric   MachineFunction &MF = *RestoreBlock.getParent();
6250b57cec5SDimitry Andric   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
6260b57cec5SDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
6270b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric   // Restore all registers immediately before the return and any
6300b57cec5SDimitry Andric   // terminators that precede it.
6310b57cec5SDimitry Andric   MachineBasicBlock::iterator I = RestoreBlock.getFirstTerminator();
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric   if (!TFI->restoreCalleeSavedRegisters(RestoreBlock, I, CSI, TRI)) {
6340b57cec5SDimitry Andric     for (const CalleeSavedInfo &CI : reverse(CSI)) {
6350b57cec5SDimitry Andric       unsigned Reg = CI.getReg();
6360b57cec5SDimitry Andric       if (CI.isSpilledToReg()) {
6370b57cec5SDimitry Andric         BuildMI(RestoreBlock, I, DebugLoc(), TII.get(TargetOpcode::COPY), Reg)
6380b57cec5SDimitry Andric           .addReg(CI.getDstReg(), getKillRegState(true));
6390b57cec5SDimitry Andric       } else {
6400b57cec5SDimitry Andric         const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
641bdd1243dSDimitry Andric         TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC,
642bdd1243dSDimitry Andric                                  TRI, Register());
6430b57cec5SDimitry Andric         assert(I != RestoreBlock.begin() &&
6440b57cec5SDimitry Andric                "loadRegFromStackSlot didn't insert any code!");
6450b57cec5SDimitry Andric         // Insert in reverse order.  loadRegFromStackSlot can insert
6460b57cec5SDimitry Andric         // multiple instructions.
6470b57cec5SDimitry Andric       }
6480b57cec5SDimitry Andric     }
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric }
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric void PEI::spillCalleeSavedRegs(MachineFunction &MF) {
6530b57cec5SDimitry Andric   // We can't list this requirement in getRequiredProperties because some
6540b57cec5SDimitry Andric   // targets (WebAssembly) use virtual registers past this point, and the pass
6550b57cec5SDimitry Andric   // pipeline is set up without giving the passes a chance to look at the
6560b57cec5SDimitry Andric   // TargetMachine.
6570b57cec5SDimitry Andric   // FIXME: Find a way to express this in getRequiredProperties.
6580b57cec5SDimitry Andric   assert(MF.getProperties().hasProperty(
6590b57cec5SDimitry Andric       MachineFunctionProperties::Property::NoVRegs));
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric   const Function &F = MF.getFunction();
6620b57cec5SDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
6630b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
6640b57cec5SDimitry Andric   MinCSFrameIndex = std::numeric_limits<unsigned>::max();
6650b57cec5SDimitry Andric   MaxCSFrameIndex = 0;
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   // Determine which of the registers in the callee save list should be saved.
6680b57cec5SDimitry Andric   BitVector SavedRegs;
6690b57cec5SDimitry Andric   TFI->determineCalleeSaves(MF, SavedRegs, RS);
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric   // Assign stack slots for any callee-saved registers that must be spilled.
6720b57cec5SDimitry Andric   assignCalleeSavedSpillSlots(MF, SavedRegs, MinCSFrameIndex, MaxCSFrameIndex);
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   // Add the code to save and restore the callee saved registers.
6750b57cec5SDimitry Andric   if (!F.hasFnAttribute(Attribute::Naked)) {
6760b57cec5SDimitry Andric     MFI.setCalleeSavedInfoValid(true);
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric     std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
6790b57cec5SDimitry Andric     if (!CSI.empty()) {
6800b57cec5SDimitry Andric       if (!MFI.hasCalls())
6810b57cec5SDimitry Andric         NumLeafFuncWithSpills++;
6820b57cec5SDimitry Andric 
683e8d8bef9SDimitry Andric       for (MachineBasicBlock *SaveBlock : SaveBlocks)
6840b57cec5SDimitry Andric         insertCSRSaves(*SaveBlock, CSI);
685e8d8bef9SDimitry Andric 
686e8d8bef9SDimitry Andric       // Update the live-in information of all the blocks up to the save point.
6870b57cec5SDimitry Andric       updateLiveness(MF);
688e8d8bef9SDimitry Andric 
6890b57cec5SDimitry Andric       for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
6900b57cec5SDimitry Andric         insertCSRRestores(*RestoreBlock, CSI);
6910b57cec5SDimitry Andric     }
6920b57cec5SDimitry Andric   }
6930b57cec5SDimitry Andric }
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
6965ffd83dbSDimitry Andric static inline void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx,
6970b57cec5SDimitry Andric                                      bool StackGrowsDown, int64_t &Offset,
69806c3fb27SDimitry Andric                                      Align &MaxAlign) {
6990b57cec5SDimitry Andric   // If the stack grows down, add the object size to find the lowest address.
7000b57cec5SDimitry Andric   if (StackGrowsDown)
7010b57cec5SDimitry Andric     Offset += MFI.getObjectSize(FrameIdx);
7020b57cec5SDimitry Andric 
7035ffd83dbSDimitry Andric   Align Alignment = MFI.getObjectAlign(FrameIdx);
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric   // If the alignment of this object is greater than that of the stack, then
7060b57cec5SDimitry Andric   // increase the stack alignment to match.
7075ffd83dbSDimitry Andric   MaxAlign = std::max(MaxAlign, Alignment);
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric   // Adjust to alignment boundary.
71006c3fb27SDimitry Andric   Offset = alignTo(Offset, Alignment);
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric   if (StackGrowsDown) {
7130b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset
7140b57cec5SDimitry Andric                       << "]\n");
7150b57cec5SDimitry Andric     MFI.setObjectOffset(FrameIdx, -Offset); // Set the computed offset
7160b57cec5SDimitry Andric   } else {
7170b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset
7180b57cec5SDimitry Andric                       << "]\n");
7190b57cec5SDimitry Andric     MFI.setObjectOffset(FrameIdx, Offset);
7200b57cec5SDimitry Andric     Offset += MFI.getObjectSize(FrameIdx);
7210b57cec5SDimitry Andric   }
7220b57cec5SDimitry Andric }
7230b57cec5SDimitry Andric 
7240b57cec5SDimitry Andric /// Compute which bytes of fixed and callee-save stack area are unused and keep
7250b57cec5SDimitry Andric /// track of them in StackBytesFree.
7260b57cec5SDimitry Andric static inline void
7270b57cec5SDimitry Andric computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown,
7280b57cec5SDimitry Andric                       unsigned MinCSFrameIndex, unsigned MaxCSFrameIndex,
7290b57cec5SDimitry Andric                       int64_t FixedCSEnd, BitVector &StackBytesFree) {
7300b57cec5SDimitry Andric   // Avoid undefined int64_t -> int conversion below in extreme case.
7310b57cec5SDimitry Andric   if (FixedCSEnd > std::numeric_limits<int>::max())
7320b57cec5SDimitry Andric     return;
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   StackBytesFree.resize(FixedCSEnd, true);
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   SmallVector<int, 16> AllocatedFrameSlots;
7370b57cec5SDimitry Andric   // Add fixed objects.
7380b57cec5SDimitry Andric   for (int i = MFI.getObjectIndexBegin(); i != 0; ++i)
7390b57cec5SDimitry Andric     // StackSlot scavenging is only implemented for the default stack.
7400b57cec5SDimitry Andric     if (MFI.getStackID(i) == TargetStackID::Default)
7410b57cec5SDimitry Andric       AllocatedFrameSlots.push_back(i);
742fe6060f1SDimitry Andric   // Add callee-save objects if there are any.
743fe6060f1SDimitry Andric   if (MinCSFrameIndex <= MaxCSFrameIndex) {
7440b57cec5SDimitry Andric     for (int i = MinCSFrameIndex; i <= (int)MaxCSFrameIndex; ++i)
7450b57cec5SDimitry Andric       if (MFI.getStackID(i) == TargetStackID::Default)
7460b57cec5SDimitry Andric         AllocatedFrameSlots.push_back(i);
747fe6060f1SDimitry Andric   }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric   for (int i : AllocatedFrameSlots) {
7500b57cec5SDimitry Andric     // These are converted from int64_t, but they should always fit in int
7510b57cec5SDimitry Andric     // because of the FixedCSEnd check above.
7520b57cec5SDimitry Andric     int ObjOffset = MFI.getObjectOffset(i);
7530b57cec5SDimitry Andric     int ObjSize = MFI.getObjectSize(i);
7540b57cec5SDimitry Andric     int ObjStart, ObjEnd;
7550b57cec5SDimitry Andric     if (StackGrowsDown) {
7560b57cec5SDimitry Andric       // ObjOffset is negative when StackGrowsDown is true.
7570b57cec5SDimitry Andric       ObjStart = -ObjOffset - ObjSize;
7580b57cec5SDimitry Andric       ObjEnd = -ObjOffset;
7590b57cec5SDimitry Andric     } else {
7600b57cec5SDimitry Andric       ObjStart = ObjOffset;
7610b57cec5SDimitry Andric       ObjEnd = ObjOffset + ObjSize;
7620b57cec5SDimitry Andric     }
7630b57cec5SDimitry Andric     // Ignore fixed holes that are in the previous stack frame.
7640b57cec5SDimitry Andric     if (ObjEnd > 0)
7650b57cec5SDimitry Andric       StackBytesFree.reset(ObjStart, ObjEnd);
7660b57cec5SDimitry Andric   }
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric 
7690b57cec5SDimitry Andric /// Assign frame object to an unused portion of the stack in the fixed stack
7700b57cec5SDimitry Andric /// object range.  Return true if the allocation was successful.
7710b57cec5SDimitry Andric static inline bool scavengeStackSlot(MachineFrameInfo &MFI, int FrameIdx,
7725ffd83dbSDimitry Andric                                      bool StackGrowsDown, Align MaxAlign,
7730b57cec5SDimitry Andric                                      BitVector &StackBytesFree) {
7740b57cec5SDimitry Andric   if (MFI.isVariableSizedObjectIndex(FrameIdx))
7750b57cec5SDimitry Andric     return false;
7760b57cec5SDimitry Andric 
7770b57cec5SDimitry Andric   if (StackBytesFree.none()) {
7780b57cec5SDimitry Andric     // clear it to speed up later scavengeStackSlot calls to
7790b57cec5SDimitry Andric     // StackBytesFree.none()
7800b57cec5SDimitry Andric     StackBytesFree.clear();
7810b57cec5SDimitry Andric     return false;
7820b57cec5SDimitry Andric   }
7830b57cec5SDimitry Andric 
7845ffd83dbSDimitry Andric   Align ObjAlign = MFI.getObjectAlign(FrameIdx);
7850b57cec5SDimitry Andric   if (ObjAlign > MaxAlign)
7860b57cec5SDimitry Andric     return false;
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric   int64_t ObjSize = MFI.getObjectSize(FrameIdx);
7890b57cec5SDimitry Andric   int FreeStart;
7900b57cec5SDimitry Andric   for (FreeStart = StackBytesFree.find_first(); FreeStart != -1;
7910b57cec5SDimitry Andric        FreeStart = StackBytesFree.find_next(FreeStart)) {
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric     // Check that free space has suitable alignment.
7940b57cec5SDimitry Andric     unsigned ObjStart = StackGrowsDown ? FreeStart + ObjSize : FreeStart;
7950b57cec5SDimitry Andric     if (alignTo(ObjStart, ObjAlign) != ObjStart)
7960b57cec5SDimitry Andric       continue;
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric     if (FreeStart + ObjSize > StackBytesFree.size())
7990b57cec5SDimitry Andric       return false;
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric     bool AllBytesFree = true;
8020b57cec5SDimitry Andric     for (unsigned Byte = 0; Byte < ObjSize; ++Byte)
8030b57cec5SDimitry Andric       if (!StackBytesFree.test(FreeStart + Byte)) {
8040b57cec5SDimitry Andric         AllBytesFree = false;
8050b57cec5SDimitry Andric         break;
8060b57cec5SDimitry Andric       }
8070b57cec5SDimitry Andric     if (AllBytesFree)
8080b57cec5SDimitry Andric       break;
8090b57cec5SDimitry Andric   }
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric   if (FreeStart == -1)
8120b57cec5SDimitry Andric     return false;
8130b57cec5SDimitry Andric 
8140b57cec5SDimitry Andric   if (StackGrowsDown) {
8150b57cec5SDimitry Andric     int ObjStart = -(FreeStart + ObjSize);
8160b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") scavenged at SP["
8170b57cec5SDimitry Andric                       << ObjStart << "]\n");
8180b57cec5SDimitry Andric     MFI.setObjectOffset(FrameIdx, ObjStart);
8190b57cec5SDimitry Andric   } else {
8200b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") scavenged at SP["
8210b57cec5SDimitry Andric                       << FreeStart << "]\n");
8220b57cec5SDimitry Andric     MFI.setObjectOffset(FrameIdx, FreeStart);
8230b57cec5SDimitry Andric   }
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric   StackBytesFree.reset(FreeStart, FreeStart + ObjSize);
8260b57cec5SDimitry Andric   return true;
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric /// AssignProtectedObjSet - Helper function to assign large stack objects (i.e.,
8300b57cec5SDimitry Andric /// those required to be close to the Stack Protector) to stack offsets.
8315ffd83dbSDimitry Andric static void AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
8320b57cec5SDimitry Andric                                   SmallSet<int, 16> &ProtectedObjs,
8330b57cec5SDimitry Andric                                   MachineFrameInfo &MFI, bool StackGrowsDown,
83406c3fb27SDimitry Andric                                   int64_t &Offset, Align &MaxAlign) {
8350b57cec5SDimitry Andric 
836fe6060f1SDimitry Andric   for (int i : UnassignedObjs) {
83706c3fb27SDimitry Andric     AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
8380b57cec5SDimitry Andric     ProtectedObjs.insert(i);
8390b57cec5SDimitry Andric   }
8400b57cec5SDimitry Andric }
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the
8430b57cec5SDimitry Andric /// abstract stack objects.
8440b57cec5SDimitry Andric void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
8450b57cec5SDimitry Andric   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric   bool StackGrowsDown =
8480b57cec5SDimitry Andric     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric   // Loop over all of the stack objects, assigning sequential addresses...
8510b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   // Start at the beginning of the local area.
8540b57cec5SDimitry Andric   // The Offset is the distance from the stack top in the direction
8550b57cec5SDimitry Andric   // of stack growth -- so it's always nonnegative.
8560b57cec5SDimitry Andric   int LocalAreaOffset = TFI.getOffsetOfLocalArea();
8570b57cec5SDimitry Andric   if (StackGrowsDown)
8580b57cec5SDimitry Andric     LocalAreaOffset = -LocalAreaOffset;
8590b57cec5SDimitry Andric   assert(LocalAreaOffset >= 0
8600b57cec5SDimitry Andric          && "Local area offset should be in direction of stack growth");
8610b57cec5SDimitry Andric   int64_t Offset = LocalAreaOffset;
8620b57cec5SDimitry Andric 
8630b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
8640b57cec5SDimitry Andric   for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i)
8650b57cec5SDimitry Andric     if (!MFI.isDeadObjectIndex(i) &&
8660b57cec5SDimitry Andric         MFI.getStackID(i) == TargetStackID::Default)
8675ffd83dbSDimitry Andric       assert(MFI.getObjectAlign(i) <= MFI.getMaxAlign() &&
8680b57cec5SDimitry Andric              "MaxAlignment is invalid");
8690b57cec5SDimitry Andric #endif
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric   // If there are fixed sized objects that are preallocated in the local area,
8720b57cec5SDimitry Andric   // non-fixed objects can't be allocated right at the start of local area.
8730b57cec5SDimitry Andric   // Adjust 'Offset' to point to the end of last fixed sized preallocated
8740b57cec5SDimitry Andric   // object.
8750b57cec5SDimitry Andric   for (int i = MFI.getObjectIndexBegin(); i != 0; ++i) {
87681ad6265SDimitry Andric     // Only allocate objects on the default stack.
87781ad6265SDimitry Andric     if (MFI.getStackID(i) != TargetStackID::Default)
8780b57cec5SDimitry Andric       continue;
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric     int64_t FixedOff;
8810b57cec5SDimitry Andric     if (StackGrowsDown) {
8820b57cec5SDimitry Andric       // The maximum distance from the stack pointer is at lower address of
8830b57cec5SDimitry Andric       // the object -- which is given by offset. For down growing stack
8840b57cec5SDimitry Andric       // the offset is negative, so we negate the offset to get the distance.
8850b57cec5SDimitry Andric       FixedOff = -MFI.getObjectOffset(i);
8860b57cec5SDimitry Andric     } else {
8870b57cec5SDimitry Andric       // The maximum distance from the start pointer is at the upper
8880b57cec5SDimitry Andric       // address of the object.
8890b57cec5SDimitry Andric       FixedOff = MFI.getObjectOffset(i) + MFI.getObjectSize(i);
8900b57cec5SDimitry Andric     }
8910b57cec5SDimitry Andric     if (FixedOff > Offset) Offset = FixedOff;
8920b57cec5SDimitry Andric   }
8930b57cec5SDimitry Andric 
89481ad6265SDimitry Andric   Align MaxAlign = MFI.getMaxAlign();
8950b57cec5SDimitry Andric   // First assign frame offsets to stack objects that are used to spill
8960b57cec5SDimitry Andric   // callee saved registers.
89781ad6265SDimitry Andric   if (MaxCSFrameIndex >= MinCSFrameIndex) {
89881ad6265SDimitry Andric     for (unsigned i = 0; i <= MaxCSFrameIndex - MinCSFrameIndex; ++i) {
89981ad6265SDimitry Andric       unsigned FrameIndex =
90081ad6265SDimitry Andric           StackGrowsDown ? MinCSFrameIndex + i : MaxCSFrameIndex - i;
90181ad6265SDimitry Andric 
90281ad6265SDimitry Andric       // Only allocate objects on the default stack.
90381ad6265SDimitry Andric       if (MFI.getStackID(FrameIndex) != TargetStackID::Default)
9040b57cec5SDimitry Andric         continue;
9050b57cec5SDimitry Andric 
90681ad6265SDimitry Andric       // TODO: should this just be if (MFI.isDeadObjectIndex(FrameIndex))
90781ad6265SDimitry Andric       if (!StackGrowsDown && MFI.isDeadObjectIndex(FrameIndex))
9080b57cec5SDimitry Andric         continue;
9090b57cec5SDimitry Andric 
91006c3fb27SDimitry Andric       AdjustStackOffset(MFI, FrameIndex, StackGrowsDown, Offset, MaxAlign);
9110b57cec5SDimitry Andric     }
9120b57cec5SDimitry Andric   }
9130b57cec5SDimitry Andric 
91481ad6265SDimitry Andric   assert(MaxAlign == MFI.getMaxAlign() &&
91581ad6265SDimitry Andric          "MFI.getMaxAlign should already account for all callee-saved "
91681ad6265SDimitry Andric          "registers without a fixed stack slot");
91781ad6265SDimitry Andric 
9180b57cec5SDimitry Andric   // FixedCSEnd is the stack offset to the end of the fixed and callee-save
9190b57cec5SDimitry Andric   // stack area.
9200b57cec5SDimitry Andric   int64_t FixedCSEnd = Offset;
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric   // Make sure the special register scavenging spill slot is closest to the
9230b57cec5SDimitry Andric   // incoming stack pointer if a frame pointer is required and is closer
9240b57cec5SDimitry Andric   // to the incoming rather than the final stack pointer.
9250b57cec5SDimitry Andric   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
9264824e7fdSDimitry Andric   bool EarlyScavengingSlots = TFI.allocateScavengingFrameIndexesNearIncomingSP(MF);
9270b57cec5SDimitry Andric   if (RS && EarlyScavengingSlots) {
9280b57cec5SDimitry Andric     SmallVector<int, 2> SFIs;
9290b57cec5SDimitry Andric     RS->getScavengingFrameIndices(SFIs);
930fe6060f1SDimitry Andric     for (int SFI : SFIs)
93106c3fb27SDimitry Andric       AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
9320b57cec5SDimitry Andric   }
9330b57cec5SDimitry Andric 
9340b57cec5SDimitry Andric   // FIXME: Once this is working, then enable flag will change to a target
9350b57cec5SDimitry Andric   // check for whether the frame is large enough to want to use virtual
9360b57cec5SDimitry Andric   // frame index registers. Functions which don't want/need this optimization
9370b57cec5SDimitry Andric   // will continue to use the existing code path.
9380b57cec5SDimitry Andric   if (MFI.getUseLocalStackAllocationBlock()) {
9395ffd83dbSDimitry Andric     Align Alignment = MFI.getLocalFrameMaxAlign();
9400b57cec5SDimitry Andric 
9410b57cec5SDimitry Andric     // Adjust to alignment boundary.
94206c3fb27SDimitry Andric     Offset = alignTo(Offset, Alignment);
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric     // Resolve offsets for objects in the local block.
9470b57cec5SDimitry Andric     for (unsigned i = 0, e = MFI.getLocalFrameObjectCount(); i != e; ++i) {
9480b57cec5SDimitry Andric       std::pair<int, int64_t> Entry = MFI.getLocalFrameObjectMap(i);
9490b57cec5SDimitry Andric       int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
9500b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << FIOffset
9510b57cec5SDimitry Andric                         << "]\n");
9520b57cec5SDimitry Andric       MFI.setObjectOffset(Entry.first, FIOffset);
9530b57cec5SDimitry Andric     }
9540b57cec5SDimitry Andric     // Allocate the local block
9550b57cec5SDimitry Andric     Offset += MFI.getLocalFrameSize();
9560b57cec5SDimitry Andric 
9575ffd83dbSDimitry Andric     MaxAlign = std::max(Alignment, MaxAlign);
9580b57cec5SDimitry Andric   }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   // Retrieve the Exception Handler registration node.
9610b57cec5SDimitry Andric   int EHRegNodeFrameIndex = std::numeric_limits<int>::max();
9620b57cec5SDimitry Andric   if (const WinEHFuncInfo *FuncInfo = MF.getWinEHFuncInfo())
9630b57cec5SDimitry Andric     EHRegNodeFrameIndex = FuncInfo->EHRegNodeFrameIndex;
9640b57cec5SDimitry Andric 
9650b57cec5SDimitry Andric   // Make sure that the stack protector comes before the local variables on the
9660b57cec5SDimitry Andric   // stack.
9670b57cec5SDimitry Andric   SmallSet<int, 16> ProtectedObjs;
9680b57cec5SDimitry Andric   if (MFI.hasStackProtectorIndex()) {
9690b57cec5SDimitry Andric     int StackProtectorFI = MFI.getStackProtectorIndex();
9700b57cec5SDimitry Andric     StackObjSet LargeArrayObjs;
9710b57cec5SDimitry Andric     StackObjSet SmallArrayObjs;
9720b57cec5SDimitry Andric     StackObjSet AddrOfObjs;
9730b57cec5SDimitry Andric 
9740b57cec5SDimitry Andric     // If we need a stack protector, we need to make sure that
9750b57cec5SDimitry Andric     // LocalStackSlotPass didn't already allocate a slot for it.
9760b57cec5SDimitry Andric     // If we are told to use the LocalStackAllocationBlock, the stack protector
9770b57cec5SDimitry Andric     // is expected to be already pre-allocated.
9780eae32dcSDimitry Andric     if (MFI.getStackID(StackProtectorFI) != TargetStackID::Default) {
9790eae32dcSDimitry Andric       // If the stack protector isn't on the default stack then it's up to the
9800eae32dcSDimitry Andric       // target to set the stack offset.
9810eae32dcSDimitry Andric       assert(MFI.getObjectOffset(StackProtectorFI) != 0 &&
9820eae32dcSDimitry Andric              "Offset of stack protector on non-default stack expected to be "
9830eae32dcSDimitry Andric              "already set.");
9840eae32dcSDimitry Andric       assert(!MFI.isObjectPreAllocated(MFI.getStackProtectorIndex()) &&
9850eae32dcSDimitry Andric              "Stack protector on non-default stack expected to not be "
9860eae32dcSDimitry Andric              "pre-allocated by LocalStackSlotPass.");
9870eae32dcSDimitry Andric     } else if (!MFI.getUseLocalStackAllocationBlock()) {
98806c3fb27SDimitry Andric       AdjustStackOffset(MFI, StackProtectorFI, StackGrowsDown, Offset,
98906c3fb27SDimitry Andric                         MaxAlign);
9900eae32dcSDimitry Andric     } else if (!MFI.isObjectPreAllocated(MFI.getStackProtectorIndex())) {
9910b57cec5SDimitry Andric       llvm_unreachable(
9920b57cec5SDimitry Andric           "Stack protector not pre-allocated by LocalStackSlotPass.");
9930eae32dcSDimitry Andric     }
9940b57cec5SDimitry Andric 
9950b57cec5SDimitry Andric     // Assign large stack objects first.
9960b57cec5SDimitry Andric     for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
9970b57cec5SDimitry Andric       if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock())
9980b57cec5SDimitry Andric         continue;
9990b57cec5SDimitry Andric       if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
10000b57cec5SDimitry Andric         continue;
10010b57cec5SDimitry Andric       if (RS && RS->isScavengingFrameIndex((int)i))
10020b57cec5SDimitry Andric         continue;
10030b57cec5SDimitry Andric       if (MFI.isDeadObjectIndex(i))
10040b57cec5SDimitry Andric         continue;
10050b57cec5SDimitry Andric       if (StackProtectorFI == (int)i || EHRegNodeFrameIndex == (int)i)
10060b57cec5SDimitry Andric         continue;
100781ad6265SDimitry Andric       // Only allocate objects on the default stack.
100881ad6265SDimitry Andric       if (MFI.getStackID(i) != TargetStackID::Default)
10090b57cec5SDimitry Andric         continue;
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric       switch (MFI.getObjectSSPLayout(i)) {
10120b57cec5SDimitry Andric       case MachineFrameInfo::SSPLK_None:
10130b57cec5SDimitry Andric         continue;
10140b57cec5SDimitry Andric       case MachineFrameInfo::SSPLK_SmallArray:
10150b57cec5SDimitry Andric         SmallArrayObjs.insert(i);
10160b57cec5SDimitry Andric         continue;
10170b57cec5SDimitry Andric       case MachineFrameInfo::SSPLK_AddrOf:
10180b57cec5SDimitry Andric         AddrOfObjs.insert(i);
10190b57cec5SDimitry Andric         continue;
10200b57cec5SDimitry Andric       case MachineFrameInfo::SSPLK_LargeArray:
10210b57cec5SDimitry Andric         LargeArrayObjs.insert(i);
10220b57cec5SDimitry Andric         continue;
10230b57cec5SDimitry Andric       }
10240b57cec5SDimitry Andric       llvm_unreachable("Unexpected SSPLayoutKind.");
10250b57cec5SDimitry Andric     }
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric     // We expect **all** the protected stack objects to be pre-allocated by
10280b57cec5SDimitry Andric     // LocalStackSlotPass. If it turns out that PEI still has to allocate some
10290b57cec5SDimitry Andric     // of them, we may end up messing up the expected order of the objects.
10300b57cec5SDimitry Andric     if (MFI.getUseLocalStackAllocationBlock() &&
10310b57cec5SDimitry Andric         !(LargeArrayObjs.empty() && SmallArrayObjs.empty() &&
10320b57cec5SDimitry Andric           AddrOfObjs.empty()))
10330b57cec5SDimitry Andric       llvm_unreachable("Found protected stack objects not pre-allocated by "
10340b57cec5SDimitry Andric                        "LocalStackSlotPass.");
10350b57cec5SDimitry Andric 
10360b57cec5SDimitry Andric     AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
103706c3fb27SDimitry Andric                           Offset, MaxAlign);
10380b57cec5SDimitry Andric     AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
103906c3fb27SDimitry Andric                           Offset, MaxAlign);
10400b57cec5SDimitry Andric     AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown,
104106c3fb27SDimitry Andric                           Offset, MaxAlign);
10420b57cec5SDimitry Andric   }
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   SmallVector<int, 8> ObjectsToAllocate;
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric   // Then prepare to assign frame offsets to stack objects that are not used to
10470b57cec5SDimitry Andric   // spill callee saved registers.
10480b57cec5SDimitry Andric   for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
10490b57cec5SDimitry Andric     if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock())
10500b57cec5SDimitry Andric       continue;
10510b57cec5SDimitry Andric     if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
10520b57cec5SDimitry Andric       continue;
10530b57cec5SDimitry Andric     if (RS && RS->isScavengingFrameIndex((int)i))
10540b57cec5SDimitry Andric       continue;
10550b57cec5SDimitry Andric     if (MFI.isDeadObjectIndex(i))
10560b57cec5SDimitry Andric       continue;
10570b57cec5SDimitry Andric     if (MFI.getStackProtectorIndex() == (int)i || EHRegNodeFrameIndex == (int)i)
10580b57cec5SDimitry Andric       continue;
10590b57cec5SDimitry Andric     if (ProtectedObjs.count(i))
10600b57cec5SDimitry Andric       continue;
106181ad6265SDimitry Andric     // Only allocate objects on the default stack.
106281ad6265SDimitry Andric     if (MFI.getStackID(i) != TargetStackID::Default)
10630b57cec5SDimitry Andric       continue;
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric     // Add the objects that we need to allocate to our working set.
10660b57cec5SDimitry Andric     ObjectsToAllocate.push_back(i);
10670b57cec5SDimitry Andric   }
10680b57cec5SDimitry Andric 
10690b57cec5SDimitry Andric   // Allocate the EH registration node first if one is present.
10700b57cec5SDimitry Andric   if (EHRegNodeFrameIndex != std::numeric_limits<int>::max())
10710b57cec5SDimitry Andric     AdjustStackOffset(MFI, EHRegNodeFrameIndex, StackGrowsDown, Offset,
107206c3fb27SDimitry Andric                       MaxAlign);
10730b57cec5SDimitry Andric 
10740b57cec5SDimitry Andric   // Give the targets a chance to order the objects the way they like it.
10755f757f3fSDimitry Andric   if (MF.getTarget().getOptLevel() != CodeGenOptLevel::None &&
10760b57cec5SDimitry Andric       MF.getTarget().Options.StackSymbolOrdering)
10770b57cec5SDimitry Andric     TFI.orderFrameObjects(MF, ObjectsToAllocate);
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   // Keep track of which bytes in the fixed and callee-save range are used so we
10800b57cec5SDimitry Andric   // can use the holes when allocating later stack objects.  Only do this if
10810b57cec5SDimitry Andric   // stack protector isn't being used and the target requests it and we're
10820b57cec5SDimitry Andric   // optimizing.
10830b57cec5SDimitry Andric   BitVector StackBytesFree;
10840b57cec5SDimitry Andric   if (!ObjectsToAllocate.empty() &&
10855f757f3fSDimitry Andric       MF.getTarget().getOptLevel() != CodeGenOptLevel::None &&
10860b57cec5SDimitry Andric       MFI.getStackProtectorIndex() < 0 && TFI.enableStackSlotScavenging(MF))
10870b57cec5SDimitry Andric     computeFreeStackSlots(MFI, StackGrowsDown, MinCSFrameIndex, MaxCSFrameIndex,
10880b57cec5SDimitry Andric                           FixedCSEnd, StackBytesFree);
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric   // Now walk the objects and actually assign base offsets to them.
10910b57cec5SDimitry Andric   for (auto &Object : ObjectsToAllocate)
10920b57cec5SDimitry Andric     if (!scavengeStackSlot(MFI, Object, StackGrowsDown, MaxAlign,
10930b57cec5SDimitry Andric                            StackBytesFree))
109406c3fb27SDimitry Andric       AdjustStackOffset(MFI, Object, StackGrowsDown, Offset, MaxAlign);
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric   // Make sure the special register scavenging spill slot is closest to the
10970b57cec5SDimitry Andric   // stack pointer.
10980b57cec5SDimitry Andric   if (RS && !EarlyScavengingSlots) {
10990b57cec5SDimitry Andric     SmallVector<int, 2> SFIs;
11000b57cec5SDimitry Andric     RS->getScavengingFrameIndices(SFIs);
1101fe6060f1SDimitry Andric     for (int SFI : SFIs)
110206c3fb27SDimitry Andric       AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
11030b57cec5SDimitry Andric   }
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   if (!TFI.targetHandlesStackFrameRounding()) {
11060b57cec5SDimitry Andric     // If we have reserved argument space for call sites in the function
11070b57cec5SDimitry Andric     // immediately on entry to the current function, count it as part of the
11080b57cec5SDimitry Andric     // overall stack size.
11090b57cec5SDimitry Andric     if (MFI.adjustsStack() && TFI.hasReservedCallFrame(MF))
11100b57cec5SDimitry Andric       Offset += MFI.getMaxCallFrameSize();
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric     // Round up the size to a multiple of the alignment.  If the function has
11130b57cec5SDimitry Andric     // any calls or alloca's, align to the target's StackAlignment value to
11140b57cec5SDimitry Andric     // ensure that the callee's frame or the alloca data is suitably aligned;
11150b57cec5SDimitry Andric     // otherwise, for leaf functions, align to the TransientStackAlignment
11160b57cec5SDimitry Andric     // value.
11175ffd83dbSDimitry Andric     Align StackAlign;
11180b57cec5SDimitry Andric     if (MFI.adjustsStack() || MFI.hasVarSizedObjects() ||
1119fe6060f1SDimitry Andric         (RegInfo->hasStackRealignment(MF) && MFI.getObjectIndexEnd() != 0))
11205ffd83dbSDimitry Andric       StackAlign = TFI.getStackAlign();
11210b57cec5SDimitry Andric     else
11225ffd83dbSDimitry Andric       StackAlign = TFI.getTransientStackAlign();
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric     // If the frame pointer is eliminated, all frame offsets will be relative to
11250b57cec5SDimitry Andric     // SP not FP. Align to MaxAlign so this works.
11260b57cec5SDimitry Andric     StackAlign = std::max(StackAlign, MaxAlign);
1127e8d8bef9SDimitry Andric     int64_t OffsetBeforeAlignment = Offset;
112806c3fb27SDimitry Andric     Offset = alignTo(Offset, StackAlign);
1129e8d8bef9SDimitry Andric 
1130e8d8bef9SDimitry Andric     // If we have increased the offset to fulfill the alignment constrants,
1131e8d8bef9SDimitry Andric     // then the scavenging spill slots may become harder to reach from the
1132e8d8bef9SDimitry Andric     // stack pointer, float them so they stay close.
1133fe6060f1SDimitry Andric     if (StackGrowsDown && OffsetBeforeAlignment != Offset && RS &&
1134fe6060f1SDimitry Andric         !EarlyScavengingSlots) {
1135e8d8bef9SDimitry Andric       SmallVector<int, 2> SFIs;
1136e8d8bef9SDimitry Andric       RS->getScavengingFrameIndices(SFIs);
1137e8d8bef9SDimitry Andric       LLVM_DEBUG(if (!SFIs.empty()) llvm::dbgs()
1138e8d8bef9SDimitry Andric                      << "Adjusting emergency spill slots!\n";);
1139e8d8bef9SDimitry Andric       int64_t Delta = Offset - OffsetBeforeAlignment;
1140fe6060f1SDimitry Andric       for (int SFI : SFIs) {
1141fe6060f1SDimitry Andric         LLVM_DEBUG(llvm::dbgs()
1142fe6060f1SDimitry Andric                        << "Adjusting offset of emergency spill slot #" << SFI
1143fe6060f1SDimitry Andric                        << " from " << MFI.getObjectOffset(SFI););
1144fe6060f1SDimitry Andric         MFI.setObjectOffset(SFI, MFI.getObjectOffset(SFI) - Delta);
1145fe6060f1SDimitry Andric         LLVM_DEBUG(llvm::dbgs() << " to " << MFI.getObjectOffset(SFI) << "\n";);
1146e8d8bef9SDimitry Andric       }
1147e8d8bef9SDimitry Andric     }
11480b57cec5SDimitry Andric   }
11490b57cec5SDimitry Andric 
11500b57cec5SDimitry Andric   // Update frame info to pretend that this is part of the stack...
11510b57cec5SDimitry Andric   int64_t StackSize = Offset - LocalAreaOffset;
11520b57cec5SDimitry Andric   MFI.setStackSize(StackSize);
11530b57cec5SDimitry Andric   NumBytesStackSpace += StackSize;
11540b57cec5SDimitry Andric }
11550b57cec5SDimitry Andric 
11560b57cec5SDimitry Andric /// insertPrologEpilogCode - Scan the function for modified callee saved
11570b57cec5SDimitry Andric /// registers, insert spill code for these callee saved registers, then add
11580b57cec5SDimitry Andric /// prolog and epilog code to the function.
11590b57cec5SDimitry Andric void PEI::insertPrologEpilogCode(MachineFunction &MF) {
11600b57cec5SDimitry Andric   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
11610b57cec5SDimitry Andric 
11620b57cec5SDimitry Andric   // Add prologue to the function...
11630b57cec5SDimitry Andric   for (MachineBasicBlock *SaveBlock : SaveBlocks)
11640b57cec5SDimitry Andric     TFI.emitPrologue(MF, *SaveBlock);
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   // Add epilogue to restore the callee-save registers in each exiting block.
11670b57cec5SDimitry Andric   for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
11680b57cec5SDimitry Andric     TFI.emitEpilogue(MF, *RestoreBlock);
11690b57cec5SDimitry Andric 
117081ad6265SDimitry Andric   // Zero call used registers before restoring callee-saved registers.
117181ad6265SDimitry Andric   insertZeroCallUsedRegs(MF);
117281ad6265SDimitry Andric 
11730b57cec5SDimitry Andric   for (MachineBasicBlock *SaveBlock : SaveBlocks)
11740b57cec5SDimitry Andric     TFI.inlineStackProbe(MF, *SaveBlock);
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric   // Emit additional code that is required to support segmented stacks, if
11770b57cec5SDimitry Andric   // we've been asked for it.  This, when linked with a runtime with support
11780b57cec5SDimitry Andric   // for segmented stacks (libgcc is one), will result in allocating stack
11790b57cec5SDimitry Andric   // space in small chunks instead of one large contiguous block.
11800b57cec5SDimitry Andric   if (MF.shouldSplitStack()) {
11810b57cec5SDimitry Andric     for (MachineBasicBlock *SaveBlock : SaveBlocks)
11820b57cec5SDimitry Andric       TFI.adjustForSegmentedStacks(MF, *SaveBlock);
118381ad6265SDimitry Andric   }
11840b57cec5SDimitry Andric 
11850b57cec5SDimitry Andric   // Emit additional code that is required to explicitly handle the stack in
11860b57cec5SDimitry Andric   // HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The
11870b57cec5SDimitry Andric   // approach is rather similar to that of Segmented Stacks, but it uses a
11880b57cec5SDimitry Andric   // different conditional check and another BIF for allocating more stack
11890b57cec5SDimitry Andric   // space.
11900b57cec5SDimitry Andric   if (MF.getFunction().getCallingConv() == CallingConv::HiPE)
11910b57cec5SDimitry Andric     for (MachineBasicBlock *SaveBlock : SaveBlocks)
11920b57cec5SDimitry Andric       TFI.adjustForHiPEPrologue(MF, *SaveBlock);
11930b57cec5SDimitry Andric }
11940b57cec5SDimitry Andric 
119581ad6265SDimitry Andric /// insertZeroCallUsedRegs - Zero out call used registers.
119681ad6265SDimitry Andric void PEI::insertZeroCallUsedRegs(MachineFunction &MF) {
119781ad6265SDimitry Andric   const Function &F = MF.getFunction();
119881ad6265SDimitry Andric 
119981ad6265SDimitry Andric   if (!F.hasFnAttribute("zero-call-used-regs"))
120081ad6265SDimitry Andric     return;
120181ad6265SDimitry Andric 
120281ad6265SDimitry Andric   using namespace ZeroCallUsedRegs;
120381ad6265SDimitry Andric 
120481ad6265SDimitry Andric   ZeroCallUsedRegsKind ZeroRegsKind =
120581ad6265SDimitry Andric       StringSwitch<ZeroCallUsedRegsKind>(
120681ad6265SDimitry Andric           F.getFnAttribute("zero-call-used-regs").getValueAsString())
120781ad6265SDimitry Andric           .Case("skip", ZeroCallUsedRegsKind::Skip)
120881ad6265SDimitry Andric           .Case("used-gpr-arg", ZeroCallUsedRegsKind::UsedGPRArg)
120981ad6265SDimitry Andric           .Case("used-gpr", ZeroCallUsedRegsKind::UsedGPR)
121081ad6265SDimitry Andric           .Case("used-arg", ZeroCallUsedRegsKind::UsedArg)
121181ad6265SDimitry Andric           .Case("used", ZeroCallUsedRegsKind::Used)
121281ad6265SDimitry Andric           .Case("all-gpr-arg", ZeroCallUsedRegsKind::AllGPRArg)
121381ad6265SDimitry Andric           .Case("all-gpr", ZeroCallUsedRegsKind::AllGPR)
121481ad6265SDimitry Andric           .Case("all-arg", ZeroCallUsedRegsKind::AllArg)
121581ad6265SDimitry Andric           .Case("all", ZeroCallUsedRegsKind::All);
121681ad6265SDimitry Andric 
121781ad6265SDimitry Andric   if (ZeroRegsKind == ZeroCallUsedRegsKind::Skip)
121881ad6265SDimitry Andric     return;
121981ad6265SDimitry Andric 
122081ad6265SDimitry Andric   const bool OnlyGPR = static_cast<unsigned>(ZeroRegsKind) & ONLY_GPR;
122181ad6265SDimitry Andric   const bool OnlyUsed = static_cast<unsigned>(ZeroRegsKind) & ONLY_USED;
122281ad6265SDimitry Andric   const bool OnlyArg = static_cast<unsigned>(ZeroRegsKind) & ONLY_ARG;
122381ad6265SDimitry Andric 
122481ad6265SDimitry Andric   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
122581ad6265SDimitry Andric   const BitVector AllocatableSet(TRI.getAllocatableSet(MF));
122681ad6265SDimitry Andric 
122781ad6265SDimitry Andric   // Mark all used registers.
122881ad6265SDimitry Andric   BitVector UsedRegs(TRI.getNumRegs());
122981ad6265SDimitry Andric   if (OnlyUsed)
123081ad6265SDimitry Andric     for (const MachineBasicBlock &MBB : MF)
1231bdd1243dSDimitry Andric       for (const MachineInstr &MI : MBB) {
1232bdd1243dSDimitry Andric         // skip debug instructions
1233bdd1243dSDimitry Andric         if (MI.isDebugInstr())
1234bdd1243dSDimitry Andric           continue;
1235bdd1243dSDimitry Andric 
123681ad6265SDimitry Andric         for (const MachineOperand &MO : MI.operands()) {
123781ad6265SDimitry Andric           if (!MO.isReg())
123881ad6265SDimitry Andric             continue;
123981ad6265SDimitry Andric 
124081ad6265SDimitry Andric           MCRegister Reg = MO.getReg();
124181ad6265SDimitry Andric           if (AllocatableSet[Reg] && !MO.isImplicit() &&
124281ad6265SDimitry Andric               (MO.isDef() || MO.isUse()))
124381ad6265SDimitry Andric             UsedRegs.set(Reg);
124481ad6265SDimitry Andric         }
1245bdd1243dSDimitry Andric       }
1246bdd1243dSDimitry Andric 
1247bdd1243dSDimitry Andric   // Get a list of registers that are used.
1248bdd1243dSDimitry Andric   BitVector LiveIns(TRI.getNumRegs());
1249bdd1243dSDimitry Andric   for (const MachineBasicBlock::RegisterMaskPair &LI : MF.front().liveins())
1250bdd1243dSDimitry Andric     LiveIns.set(LI.PhysReg);
125181ad6265SDimitry Andric 
125281ad6265SDimitry Andric   BitVector RegsToZero(TRI.getNumRegs());
125381ad6265SDimitry Andric   for (MCRegister Reg : AllocatableSet.set_bits()) {
125481ad6265SDimitry Andric     // Skip over fixed registers.
125581ad6265SDimitry Andric     if (TRI.isFixedRegister(MF, Reg))
125681ad6265SDimitry Andric       continue;
125781ad6265SDimitry Andric 
125881ad6265SDimitry Andric     // Want only general purpose registers.
125981ad6265SDimitry Andric     if (OnlyGPR && !TRI.isGeneralPurposeRegister(MF, Reg))
126081ad6265SDimitry Andric       continue;
126181ad6265SDimitry Andric 
126281ad6265SDimitry Andric     // Want only used registers.
126381ad6265SDimitry Andric     if (OnlyUsed && !UsedRegs[Reg])
126481ad6265SDimitry Andric       continue;
126581ad6265SDimitry Andric 
126681ad6265SDimitry Andric     // Want only registers used for arguments.
1267bdd1243dSDimitry Andric     if (OnlyArg) {
1268bdd1243dSDimitry Andric       if (OnlyUsed) {
1269bdd1243dSDimitry Andric         if (!LiveIns[Reg])
127081ad6265SDimitry Andric           continue;
1271bdd1243dSDimitry Andric       } else if (!TRI.isArgumentRegister(MF, Reg)) {
1272bdd1243dSDimitry Andric         continue;
1273bdd1243dSDimitry Andric       }
1274bdd1243dSDimitry Andric     }
127581ad6265SDimitry Andric 
127681ad6265SDimitry Andric     RegsToZero.set(Reg);
127781ad6265SDimitry Andric   }
127881ad6265SDimitry Andric 
127981ad6265SDimitry Andric   // Don't clear registers that are live when leaving the function.
128081ad6265SDimitry Andric   for (const MachineBasicBlock &MBB : MF)
128181ad6265SDimitry Andric     for (const MachineInstr &MI : MBB.terminators()) {
128281ad6265SDimitry Andric       if (!MI.isReturn())
128381ad6265SDimitry Andric         continue;
128481ad6265SDimitry Andric 
128581ad6265SDimitry Andric       for (const auto &MO : MI.operands()) {
128681ad6265SDimitry Andric         if (!MO.isReg())
128781ad6265SDimitry Andric           continue;
128881ad6265SDimitry Andric 
128950d7464cSDimitry Andric         MCRegister Reg = MO.getReg();
1290a39b3aa4SDimitry Andric         if (!Reg)
1291a39b3aa4SDimitry Andric           continue;
129250d7464cSDimitry Andric 
129350d7464cSDimitry Andric         // This picks up sibling registers (e.q. %al -> %ah).
129406c3fb27SDimitry Andric         for (MCRegUnit Unit : TRI.regunits(Reg))
129506c3fb27SDimitry Andric           RegsToZero.reset(Unit);
129650d7464cSDimitry Andric 
129750d7464cSDimitry Andric         for (MCPhysReg SReg : TRI.sub_and_superregs_inclusive(Reg))
129881ad6265SDimitry Andric           RegsToZero.reset(SReg);
129981ad6265SDimitry Andric       }
130081ad6265SDimitry Andric     }
130181ad6265SDimitry Andric 
130281ad6265SDimitry Andric   // Don't need to clear registers that are used/clobbered by terminating
130381ad6265SDimitry Andric   // instructions.
130481ad6265SDimitry Andric   for (const MachineBasicBlock &MBB : MF) {
130581ad6265SDimitry Andric     if (!MBB.isReturnBlock())
130681ad6265SDimitry Andric       continue;
130781ad6265SDimitry Andric 
130881ad6265SDimitry Andric     MachineBasicBlock::const_iterator MBBI = MBB.getFirstTerminator();
130981ad6265SDimitry Andric     for (MachineBasicBlock::const_iterator I = MBBI, E = MBB.end(); I != E;
131081ad6265SDimitry Andric          ++I) {
131181ad6265SDimitry Andric       for (const MachineOperand &MO : I->operands()) {
131281ad6265SDimitry Andric         if (!MO.isReg())
131381ad6265SDimitry Andric           continue;
131481ad6265SDimitry Andric 
1315a39b3aa4SDimitry Andric         MCRegister Reg = MO.getReg();
1316a39b3aa4SDimitry Andric         if (!Reg)
1317a39b3aa4SDimitry Andric           continue;
1318a39b3aa4SDimitry Andric 
1319a39b3aa4SDimitry Andric         for (const MCPhysReg Reg : TRI.sub_and_superregs_inclusive(Reg))
132081ad6265SDimitry Andric           RegsToZero.reset(Reg);
132181ad6265SDimitry Andric       }
132281ad6265SDimitry Andric     }
132381ad6265SDimitry Andric   }
132481ad6265SDimitry Andric 
13256246ae0bSDimitry Andric   // Don't clear registers that must be preserved.
13266246ae0bSDimitry Andric   for (const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF);
13276246ae0bSDimitry Andric        MCPhysReg CSReg = *CSRegs; ++CSRegs)
13286246ae0bSDimitry Andric     for (MCRegister Reg : TRI.sub_and_superregs_inclusive(CSReg))
132981ad6265SDimitry Andric       RegsToZero.reset(Reg);
133081ad6265SDimitry Andric 
133181ad6265SDimitry Andric   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
133281ad6265SDimitry Andric   for (MachineBasicBlock &MBB : MF)
133381ad6265SDimitry Andric     if (MBB.isReturnBlock())
133481ad6265SDimitry Andric       TFI.emitZeroCallUsedRegs(RegsToZero, MBB);
133581ad6265SDimitry Andric }
133681ad6265SDimitry Andric 
13375f757f3fSDimitry Andric /// Replace all FrameIndex operands with physical register references and actual
13385f757f3fSDimitry Andric /// offsets.
13395f757f3fSDimitry Andric void PEI::replaceFrameIndicesBackward(MachineFunction &MF) {
13405f757f3fSDimitry Andric   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
13415f757f3fSDimitry Andric 
13425f757f3fSDimitry Andric   for (auto &MBB : MF) {
13435f757f3fSDimitry Andric     int SPAdj = 0;
13445f757f3fSDimitry Andric     if (!MBB.succ_empty()) {
13455f757f3fSDimitry Andric       // Get the SP adjustment for the end of MBB from the start of any of its
13465f757f3fSDimitry Andric       // successors. They should all be the same.
13475f757f3fSDimitry Andric       assert(all_of(MBB.successors(), [&MBB](const MachineBasicBlock *Succ) {
13485f757f3fSDimitry Andric         return Succ->getCallFrameSize() ==
13495f757f3fSDimitry Andric                (*MBB.succ_begin())->getCallFrameSize();
13505f757f3fSDimitry Andric       }));
13515f757f3fSDimitry Andric       const MachineBasicBlock &FirstSucc = **MBB.succ_begin();
13525f757f3fSDimitry Andric       SPAdj = TFI.alignSPAdjust(FirstSucc.getCallFrameSize());
13535f757f3fSDimitry Andric       if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp)
13545f757f3fSDimitry Andric         SPAdj = -SPAdj;
13555f757f3fSDimitry Andric     }
13565f757f3fSDimitry Andric 
13575f757f3fSDimitry Andric     replaceFrameIndicesBackward(&MBB, MF, SPAdj);
13585f757f3fSDimitry Andric 
13595f757f3fSDimitry Andric     // We can't track the call frame size after call frame pseudos have been
13605f757f3fSDimitry Andric     // eliminated. Set it to zero everywhere to keep MachineVerifier happy.
13615f757f3fSDimitry Andric     MBB.setCallFrameSize(0);
13625f757f3fSDimitry Andric   }
13635f757f3fSDimitry Andric }
13645f757f3fSDimitry Andric 
13650b57cec5SDimitry Andric /// replaceFrameIndices - Replace all MO_FrameIndex operands with physical
13660b57cec5SDimitry Andric /// register references and actual offsets.
13670b57cec5SDimitry Andric void PEI::replaceFrameIndices(MachineFunction &MF) {
13685f757f3fSDimitry Andric   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
13690b57cec5SDimitry Andric 
13705f757f3fSDimitry Andric   for (auto &MBB : MF) {
13715f757f3fSDimitry Andric     int SPAdj = TFI.alignSPAdjust(MBB.getCallFrameSize());
13725f757f3fSDimitry Andric     if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp)
13735f757f3fSDimitry Andric       SPAdj = -SPAdj;
13740b57cec5SDimitry Andric 
13755f757f3fSDimitry Andric     replaceFrameIndices(&MBB, MF, SPAdj);
13760b57cec5SDimitry Andric 
13775f757f3fSDimitry Andric     // We can't track the call frame size after call frame pseudos have been
13785f757f3fSDimitry Andric     // eliminated. Set it to zero everywhere to keep MachineVerifier happy.
13795f757f3fSDimitry Andric     MBB.setCallFrameSize(0);
13800b57cec5SDimitry Andric   }
13810b57cec5SDimitry Andric }
13820b57cec5SDimitry Andric 
1383bdd1243dSDimitry Andric bool PEI::replaceFrameIndexDebugInstr(MachineFunction &MF, MachineInstr &MI,
1384bdd1243dSDimitry Andric                                       unsigned OpIdx, int SPAdj) {
13850b57cec5SDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
1386bdd1243dSDimitry Andric   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
13870b57cec5SDimitry Andric   if (MI.isDebugValue()) {
1388bdd1243dSDimitry Andric 
1389bdd1243dSDimitry Andric     MachineOperand &Op = MI.getOperand(OpIdx);
1390bdd1243dSDimitry Andric     assert(MI.isDebugOperand(&Op) &&
1391fe6060f1SDimitry Andric            "Frame indices can only appear as a debug operand in a DBG_VALUE*"
1392fe6060f1SDimitry Andric            " machine instruction");
13935ffd83dbSDimitry Andric     Register Reg;
1394fe6060f1SDimitry Andric     unsigned FrameIdx = Op.getIndex();
13950b57cec5SDimitry Andric     unsigned Size = MF.getFrameInfo().getObjectSize(FrameIdx);
13960b57cec5SDimitry Andric 
1397bdd1243dSDimitry Andric     StackOffset Offset = TFI->getFrameIndexReference(MF, FrameIdx, Reg);
1398fe6060f1SDimitry Andric     Op.ChangeToRegister(Reg, false /*isDef*/);
13990b57cec5SDimitry Andric 
14000b57cec5SDimitry Andric     const DIExpression *DIExpr = MI.getDebugExpression();
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric     // If we have a direct DBG_VALUE, and its location expression isn't
14030b57cec5SDimitry Andric     // currently complex, then adding an offset will morph it into a
14040b57cec5SDimitry Andric     // complex location that is interpreted as being a memory address.
14050b57cec5SDimitry Andric     // This changes a pointer-valued variable to dereference that pointer,
14060b57cec5SDimitry Andric     // which is incorrect. Fix by adding DW_OP_stack_value.
1407fe6060f1SDimitry Andric 
1408fe6060f1SDimitry Andric     if (MI.isNonListDebugValue()) {
14090b57cec5SDimitry Andric       unsigned PrependFlags = DIExpression::ApplyOffset;
14100b57cec5SDimitry Andric       if (!MI.isIndirectDebugValue() && !DIExpr->isComplex())
14110b57cec5SDimitry Andric         PrependFlags |= DIExpression::StackValue;
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric       // If we have DBG_VALUE that is indirect and has a Implicit location
14140b57cec5SDimitry Andric       // expression need to insert a deref before prepending a Memory
14150b57cec5SDimitry Andric       // location expression. Also after doing this we change the DBG_VALUE
14160b57cec5SDimitry Andric       // to be direct.
14170b57cec5SDimitry Andric       if (MI.isIndirectDebugValue() && DIExpr->isImplicit()) {
14180b57cec5SDimitry Andric         SmallVector<uint64_t, 2> Ops = {dwarf::DW_OP_deref_size, Size};
14190b57cec5SDimitry Andric         bool WithStackValue = true;
14200b57cec5SDimitry Andric         DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue);
14210b57cec5SDimitry Andric         // Make the DBG_VALUE direct.
14225ffd83dbSDimitry Andric         MI.getDebugOffset().ChangeToRegister(0, false);
14230b57cec5SDimitry Andric       }
1424e8d8bef9SDimitry Andric       DIExpr = TRI.prependOffsetExpression(DIExpr, PrependFlags, Offset);
1425fe6060f1SDimitry Andric     } else {
1426fe6060f1SDimitry Andric       // The debug operand at DebugOpIndex was a frame index at offset
1427fe6060f1SDimitry Andric       // `Offset`; now the operand has been replaced with the frame
1428fe6060f1SDimitry Andric       // register, we must add Offset with `register x, plus Offset`.
1429fe6060f1SDimitry Andric       unsigned DebugOpIndex = MI.getDebugOperandIndex(&Op);
1430fe6060f1SDimitry Andric       SmallVector<uint64_t, 3> Ops;
1431fe6060f1SDimitry Andric       TRI.getOffsetOpcodes(Offset, Ops);
1432fe6060f1SDimitry Andric       DIExpr = DIExpression::appendOpsToArg(DIExpr, Ops, DebugOpIndex);
1433fe6060f1SDimitry Andric     }
14345ffd83dbSDimitry Andric     MI.getDebugExpressionOp().setMetadata(DIExpr);
1435bdd1243dSDimitry Andric     return true;
1436bdd1243dSDimitry Andric   }
1437bdd1243dSDimitry Andric 
1438bdd1243dSDimitry Andric   if (MI.isDebugPHI()) {
1439fe6060f1SDimitry Andric     // Allow stack ref to continue onwards.
1440bdd1243dSDimitry Andric     return true;
14410b57cec5SDimitry Andric   }
14420b57cec5SDimitry Andric 
14430b57cec5SDimitry Andric   // TODO: This code should be commoned with the code for
14440b57cec5SDimitry Andric   // PATCHPOINT. There's no good reason for the difference in
14450b57cec5SDimitry Andric   // implementation other than historical accident.  The only
14460b57cec5SDimitry Andric   // remaining difference is the unconditional use of the stack
14470b57cec5SDimitry Andric   // pointer as the base register.
14480b57cec5SDimitry Andric   if (MI.getOpcode() == TargetOpcode::STATEPOINT) {
1449bdd1243dSDimitry Andric     assert((!MI.isDebugValue() || OpIdx == 0) &&
14500fca6ea1SDimitry Andric            "Frame indices can only appear as the first operand of a "
14510b57cec5SDimitry Andric            "DBG_VALUE machine instruction");
14525ffd83dbSDimitry Andric     Register Reg;
1453bdd1243dSDimitry Andric     MachineOperand &Offset = MI.getOperand(OpIdx + 1);
1454e8d8bef9SDimitry Andric     StackOffset refOffset = TFI->getFrameIndexReferencePreferSP(
1455bdd1243dSDimitry Andric         MF, MI.getOperand(OpIdx).getIndex(), Reg, /*IgnoreSPUpdates*/ false);
1456e8d8bef9SDimitry Andric     assert(!refOffset.getScalable() &&
1457e8d8bef9SDimitry Andric            "Frame offsets with a scalable component are not supported");
1458e8d8bef9SDimitry Andric     Offset.setImm(Offset.getImm() + refOffset.getFixed() + SPAdj);
1459bdd1243dSDimitry Andric     MI.getOperand(OpIdx).ChangeToRegister(Reg, false /*isDef*/);
1460bdd1243dSDimitry Andric     return true;
1461bdd1243dSDimitry Andric   }
1462bdd1243dSDimitry Andric   return false;
1463bdd1243dSDimitry Andric }
1464bdd1243dSDimitry Andric 
1465bdd1243dSDimitry Andric void PEI::replaceFrameIndicesBackward(MachineBasicBlock *BB,
1466bdd1243dSDimitry Andric                                       MachineFunction &MF, int &SPAdj) {
1467bdd1243dSDimitry Andric   assert(MF.getSubtarget().getRegisterInfo() &&
1468bdd1243dSDimitry Andric          "getRegisterInfo() must be implemented!");
1469bdd1243dSDimitry Andric 
147006c3fb27SDimitry Andric   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
1471bdd1243dSDimitry Andric   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
147206c3fb27SDimitry Andric   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
1473bdd1243dSDimitry Andric 
147406c3fb27SDimitry Andric   RegScavenger *LocalRS = FrameIndexEliminationScavenging ? RS : nullptr;
147506c3fb27SDimitry Andric   if (LocalRS)
147606c3fb27SDimitry Andric     LocalRS->enterBasicBlockEnd(*BB);
1477bdd1243dSDimitry Andric 
14785f757f3fSDimitry Andric   for (MachineBasicBlock::iterator I = BB->end(); I != BB->begin();) {
14795f757f3fSDimitry Andric     MachineInstr &MI = *std::prev(I);
14805f757f3fSDimitry Andric 
148106c3fb27SDimitry Andric     if (TII.isFrameInstr(MI)) {
14825f757f3fSDimitry Andric       SPAdj -= TII.getSPAdjust(MI);
148306c3fb27SDimitry Andric       TFI.eliminateCallFramePseudoInstr(MF, *BB, &MI);
148406c3fb27SDimitry Andric       continue;
148506c3fb27SDimitry Andric     }
1486bdd1243dSDimitry Andric 
148706c3fb27SDimitry Andric     // Step backwards to get the liveness state at (immedately after) MI.
148806c3fb27SDimitry Andric     if (LocalRS)
14895f757f3fSDimitry Andric       LocalRS->backward(I);
149006c3fb27SDimitry Andric 
14915f757f3fSDimitry Andric     bool RemovedMI = false;
14925f757f3fSDimitry Andric     for (const auto &[Idx, Op] : enumerate(MI.operands())) {
14935f757f3fSDimitry Andric       if (!Op.isFI())
1494bdd1243dSDimitry Andric         continue;
1495bdd1243dSDimitry Andric 
14965f757f3fSDimitry Andric       if (replaceFrameIndexDebugInstr(MF, MI, Idx, SPAdj))
1497bdd1243dSDimitry Andric         continue;
1498bdd1243dSDimitry Andric 
149906c3fb27SDimitry Andric       // Eliminate this FrameIndex operand.
15005f757f3fSDimitry Andric       RemovedMI = TRI.eliminateFrameIndex(MI, SPAdj, Idx, LocalRS);
15015f757f3fSDimitry Andric       if (RemovedMI)
1502bdd1243dSDimitry Andric         break;
1503bdd1243dSDimitry Andric     }
15045f757f3fSDimitry Andric 
15055f757f3fSDimitry Andric     if (!RemovedMI)
15065f757f3fSDimitry Andric       --I;
1507bdd1243dSDimitry Andric   }
1508bdd1243dSDimitry Andric }
1509bdd1243dSDimitry Andric 
1510bdd1243dSDimitry Andric void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
1511bdd1243dSDimitry Andric                               int &SPAdj) {
1512bdd1243dSDimitry Andric   assert(MF.getSubtarget().getRegisterInfo() &&
1513bdd1243dSDimitry Andric          "getRegisterInfo() must be implemented!");
1514bdd1243dSDimitry Andric   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
1515bdd1243dSDimitry Andric   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
1516bdd1243dSDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
1517bdd1243dSDimitry Andric 
1518bdd1243dSDimitry Andric   bool InsideCallSequence = false;
1519bdd1243dSDimitry Andric 
1520bdd1243dSDimitry Andric   for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
1521bdd1243dSDimitry Andric     if (TII.isFrameInstr(*I)) {
1522bdd1243dSDimitry Andric       InsideCallSequence = TII.isFrameSetup(*I);
1523bdd1243dSDimitry Andric       SPAdj += TII.getSPAdjust(*I);
1524bdd1243dSDimitry Andric       I = TFI->eliminateCallFramePseudoInstr(MF, *BB, I);
15250b57cec5SDimitry Andric       continue;
15260b57cec5SDimitry Andric     }
15270b57cec5SDimitry Andric 
1528bdd1243dSDimitry Andric     MachineInstr &MI = *I;
1529bdd1243dSDimitry Andric     bool DoIncr = true;
1530bdd1243dSDimitry Andric     bool DidFinishLoop = true;
1531bdd1243dSDimitry Andric     for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
1532bdd1243dSDimitry Andric       if (!MI.getOperand(i).isFI())
1533bdd1243dSDimitry Andric         continue;
1534bdd1243dSDimitry Andric 
1535bdd1243dSDimitry Andric       if (replaceFrameIndexDebugInstr(MF, MI, i, SPAdj))
1536bdd1243dSDimitry Andric         continue;
1537bdd1243dSDimitry Andric 
15380b57cec5SDimitry Andric       // Some instructions (e.g. inline asm instructions) can have
15390b57cec5SDimitry Andric       // multiple frame indices and/or cause eliminateFrameIndex
15400b57cec5SDimitry Andric       // to insert more than one instruction. We need the register
15410b57cec5SDimitry Andric       // scavenger to go through all of these instructions so that
15420b57cec5SDimitry Andric       // it can update its register information. We keep the
15430b57cec5SDimitry Andric       // iterator at the point before insertion so that we can
15440b57cec5SDimitry Andric       // revisit them in full.
15450b57cec5SDimitry Andric       bool AtBeginning = (I == BB->begin());
15460b57cec5SDimitry Andric       if (!AtBeginning) --I;
15470b57cec5SDimitry Andric 
15480b57cec5SDimitry Andric       // If this instruction has a FrameIndex operand, we need to
15490b57cec5SDimitry Andric       // use that target machine register info object to eliminate
15500b57cec5SDimitry Andric       // it.
15515f757f3fSDimitry Andric       TRI.eliminateFrameIndex(MI, SPAdj, i);
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric       // Reset the iterator if we were at the beginning of the BB.
15540b57cec5SDimitry Andric       if (AtBeginning) {
15550b57cec5SDimitry Andric         I = BB->begin();
15560b57cec5SDimitry Andric         DoIncr = false;
15570b57cec5SDimitry Andric       }
15580b57cec5SDimitry Andric 
15590b57cec5SDimitry Andric       DidFinishLoop = false;
15600b57cec5SDimitry Andric       break;
15610b57cec5SDimitry Andric     }
15620b57cec5SDimitry Andric 
15630b57cec5SDimitry Andric     // If we are looking at a call sequence, we need to keep track of
15640b57cec5SDimitry Andric     // the SP adjustment made by each instruction in the sequence.
15650b57cec5SDimitry Andric     // This includes both the frame setup/destroy pseudos (handled above),
15660b57cec5SDimitry Andric     // as well as other instructions that have side effects w.r.t the SP.
15670b57cec5SDimitry Andric     // Note that this must come after eliminateFrameIndex, because
15680b57cec5SDimitry Andric     // if I itself referred to a frame index, we shouldn't count its own
15690b57cec5SDimitry Andric     // adjustment.
15700b57cec5SDimitry Andric     if (DidFinishLoop && InsideCallSequence)
15710b57cec5SDimitry Andric       SPAdj += TII.getSPAdjust(MI);
15720b57cec5SDimitry Andric 
15735f757f3fSDimitry Andric     if (DoIncr && I != BB->end())
15745f757f3fSDimitry Andric       ++I;
15750b57cec5SDimitry Andric   }
15760b57cec5SDimitry Andric }
1577