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