1 //===-- X86TargetFrameLowering.h - Define frame lowering for X86 -*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This class implements X86-specific bits of TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H 14 #define LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H 15 16 #include "llvm/CodeGen/MachineFunction.h" 17 #include "llvm/CodeGen/TargetFrameLowering.h" 18 #include "llvm/Support/TypeSize.h" 19 20 namespace llvm { 21 22 class MachineInstrBuilder; 23 class MCCFIInstruction; 24 class X86InstrInfo; 25 class X86Subtarget; 26 class X86RegisterInfo; 27 28 class X86FrameLowering : public TargetFrameLowering { 29 public: 30 X86FrameLowering(const X86Subtarget &STI, MaybeAlign StackAlignOverride); 31 32 // Cached subtarget predicates. 33 34 const X86Subtarget &STI; 35 const X86InstrInfo &TII; 36 const X86RegisterInfo *TRI; 37 38 unsigned SlotSize; 39 40 /// Is64Bit implies that x86_64 instructions are available. 41 bool Is64Bit; 42 43 bool IsLP64; 44 45 /// True if the 64-bit frame or stack pointer should be used. True for most 46 /// 64-bit targets with the exception of x32. If this is false, 32-bit 47 /// instruction operands should be used to manipulate StackPtr and FramePtr. 48 bool Uses64BitFramePtr; 49 50 unsigned StackPtr; 51 52 /// Emit target stack probe code. This is required for all 53 /// large stack allocations on Windows. The caller is required to materialize 54 /// the number of bytes to probe in RAX/EAX. 55 /// \p InstrNum optionally contains a debug-info instruction number for the 56 /// new stack pointer. 57 void emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB, 58 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 59 bool InProlog, 60 std::optional<MachineFunction::DebugInstrOperandPair> 61 InstrNum = std::nullopt) const; 62 63 bool stackProbeFunctionModifiesSP() const override; 64 65 /// Replace a StackProbe inline-stub with the actual probe code inline. 66 void inlineStackProbe(MachineFunction &MF, 67 MachineBasicBlock &PrologMBB) const override; 68 69 void emitCalleeSavedFrameMovesFullCFA( 70 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override; 71 72 void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, 73 MachineBasicBlock::iterator MBBI, 74 const DebugLoc &DL, bool IsPrologue) const; 75 76 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into 77 /// the function. 78 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 79 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 80 81 void adjustForSegmentedStacks(MachineFunction &MF, 82 MachineBasicBlock &PrologueMBB) const override; 83 84 void adjustForHiPEPrologue(MachineFunction &MF, 85 MachineBasicBlock &PrologueMBB) const override; 86 87 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 88 RegScavenger *RS = nullptr) const override; 89 90 bool 91 assignCalleeSavedSpillSlots(MachineFunction &MF, 92 const TargetRegisterInfo *TRI, 93 std::vector<CalleeSavedInfo> &CSI) const override; 94 95 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 96 MachineBasicBlock::iterator MI, 97 ArrayRef<CalleeSavedInfo> CSI, 98 const TargetRegisterInfo *TRI) const override; 99 100 bool 101 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 102 MachineBasicBlock::iterator MI, 103 MutableArrayRef<CalleeSavedInfo> CSI, 104 const TargetRegisterInfo *TRI) const override; 105 106 bool hasFP(const MachineFunction &MF) const override; 107 bool hasReservedCallFrame(const MachineFunction &MF) const override; 108 bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; 109 bool needsFrameIndexResolution(const MachineFunction &MF) const override; 110 111 StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 112 Register &FrameReg) const override; 113 114 int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI, 115 Register &SPReg) const; 116 StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI, 117 Register &SPReg, int Adjustment) const; 118 StackOffset 119 getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, 120 Register &FrameReg, 121 bool IgnoreSPUpdates) const override; 122 123 MachineBasicBlock::iterator 124 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 125 MachineBasicBlock::iterator MI) const override; 126 127 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override; 128 129 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 130 RegScavenger *RS) const override; 131 132 void 133 processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, 134 RegScavenger *RS) const override; 135 136 /// Check the instruction before/after the passed instruction. If 137 /// it is an ADD/SUB/LEA instruction it is deleted argument and the 138 /// stack adjustment is returned as a positive value for ADD/LEA and 139 /// a negative for SUB. 140 int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 141 bool doMergeWithPrevious) const; 142 143 /// Emit a series of instructions to increment / decrement the stack 144 /// pointer by a constant value. 145 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 146 const DebugLoc &DL, int64_t NumBytes, bool InEpilogue) const; 147 148 /// Check that LEA can be used on SP in an epilogue sequence for \p MF. 149 bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const; 150 151 /// Check whether or not the given \p MBB can be used as a prologue 152 /// for the target. 153 /// The prologue will be inserted first in this basic block. 154 /// This method is used by the shrink-wrapping pass to decide if 155 /// \p MBB will be correctly handled by the target. 156 /// As soon as the target enable shrink-wrapping without overriding 157 /// this method, we assume that each basic block is a valid 158 /// prologue. 159 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; 160 161 /// Check whether or not the given \p MBB can be used as a epilogue 162 /// for the target. 163 /// The epilogue will be inserted before the first terminator of that block. 164 /// This method is used by the shrink-wrapping pass to decide if 165 /// \p MBB will be correctly handled by the target. 166 bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override; 167 168 /// Returns true if the target will correctly handle shrink wrapping. 169 bool enableShrinkWrapping(const MachineFunction &MF) const override; 170 171 /// Order the symbols in the local stack. 172 /// We want to place the local stack objects in some sort of sensible order. 173 /// The heuristic we use is to try and pack them according to static number 174 /// of uses and size in order to minimize code size. 175 void orderFrameObjects(const MachineFunction &MF, 176 SmallVectorImpl<int> &ObjectsToAllocate) const override; 177 178 /// Wraps up getting a CFI index and building a MachineInstr for it. 179 void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 180 const DebugLoc &DL, const MCCFIInstruction &CFIInst, 181 MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; 182 183 /// Sets up EBP and optionally ESI based on the incoming EBP value. Only 184 /// needed for 32-bit. Used in funclet prologues and at catchret destinations. 185 MachineBasicBlock::iterator 186 restoreWin32EHStackPointers(MachineBasicBlock &MBB, 187 MachineBasicBlock::iterator MBBI, 188 const DebugLoc &DL, bool RestoreSP = false) const; 189 190 void restoreWinEHStackPointersInParent(MachineFunction &MF) const; 191 192 int getInitialCFAOffset(const MachineFunction &MF) const override; 193 194 Register getInitialCFARegister(const MachineFunction &MF) const override; 195 196 DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override; 197 198 /// Return true if the function has a redzone (accessible bytes past the 199 /// frame of the top of stack function) as part of it's ABI. 200 bool has128ByteRedZone(const MachineFunction& MF) const; 201 202 private: 203 bool isWin64Prologue(const MachineFunction &MF) const; 204 205 bool needsDwarfCFI(const MachineFunction &MF) const; 206 207 uint64_t calculateMaxStackAlign(const MachineFunction &MF) const; 208 209 /// Emit target stack probe as a call to a helper function 210 void emitStackProbeCall( 211 MachineFunction &MF, MachineBasicBlock &MBB, 212 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog, 213 std::optional<MachineFunction::DebugInstrOperandPair> InstrNum) const; 214 215 /// Emit target stack probe as an inline sequence. 216 void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB, 217 MachineBasicBlock::iterator MBBI, 218 const DebugLoc &DL, bool InProlog) const; 219 void emitStackProbeInlineWindowsCoreCLR64(MachineFunction &MF, 220 MachineBasicBlock &MBB, 221 MachineBasicBlock::iterator MBBI, 222 const DebugLoc &DL, 223 bool InProlog) const; 224 void emitStackProbeInlineGeneric(MachineFunction &MF, MachineBasicBlock &MBB, 225 MachineBasicBlock::iterator MBBI, 226 const DebugLoc &DL, bool InProlog) const; 227 228 void emitStackProbeInlineGenericBlock(MachineFunction &MF, 229 MachineBasicBlock &MBB, 230 MachineBasicBlock::iterator MBBI, 231 const DebugLoc &DL, uint64_t Offset, 232 uint64_t Align) const; 233 234 void emitStackProbeInlineGenericLoop(MachineFunction &MF, 235 MachineBasicBlock &MBB, 236 MachineBasicBlock::iterator MBBI, 237 const DebugLoc &DL, uint64_t Offset, 238 uint64_t Align) const; 239 240 /// Emit target zero call-used regs. 241 void emitZeroCallUsedRegs(BitVector RegsToZero, 242 MachineBasicBlock &MBB) const override; 243 244 void adjustFrameForMsvcCxxEh(MachineFunction &MF) const; 245 246 /// Aligns the stack pointer by ANDing it with -MaxAlign. 247 void BuildStackAlignAND(MachineBasicBlock &MBB, 248 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 249 unsigned Reg, uint64_t MaxAlign) const; 250 251 /// Make small positive stack adjustments using POPs. 252 bool adjustStackWithPops(MachineBasicBlock &MBB, 253 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 254 int Offset) const; 255 256 /// Adjusts the stack pointer using LEA, SUB, or ADD. 257 MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB, 258 MachineBasicBlock::iterator MBBI, 259 const DebugLoc &DL, int64_t Offset, 260 bool InEpilogue) const; 261 262 unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const; 263 264 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const; 265 266 /// Materialize the catchret target MBB in RAX. 267 void emitCatchRetReturnValue(MachineBasicBlock &MBB, 268 MachineBasicBlock::iterator MBBI, 269 MachineInstr *CatchRet) const; 270 }; 271 272 } // End llvm namespace 273 274 #endif 275