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 /// Return true if the function has a redzone (accessible bytes past the 197 /// frame of the top of stack function) as part of it's ABI. 198 bool has128ByteRedZone(const MachineFunction& MF) const; 199 200 private: 201 bool isWin64Prologue(const MachineFunction &MF) const; 202 203 bool needsDwarfCFI(const MachineFunction &MF) const; 204 205 uint64_t calculateMaxStackAlign(const MachineFunction &MF) const; 206 207 /// Emit target stack probe as a call to a helper function 208 void emitStackProbeCall( 209 MachineFunction &MF, MachineBasicBlock &MBB, 210 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog, 211 std::optional<MachineFunction::DebugInstrOperandPair> InstrNum) const; 212 213 /// Emit target stack probe as an inline sequence. 214 void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB, 215 MachineBasicBlock::iterator MBBI, 216 const DebugLoc &DL, bool InProlog) const; 217 void emitStackProbeInlineWindowsCoreCLR64(MachineFunction &MF, 218 MachineBasicBlock &MBB, 219 MachineBasicBlock::iterator MBBI, 220 const DebugLoc &DL, 221 bool InProlog) const; 222 void emitStackProbeInlineGeneric(MachineFunction &MF, MachineBasicBlock &MBB, 223 MachineBasicBlock::iterator MBBI, 224 const DebugLoc &DL, bool InProlog) const; 225 226 void emitStackProbeInlineGenericBlock(MachineFunction &MF, 227 MachineBasicBlock &MBB, 228 MachineBasicBlock::iterator MBBI, 229 const DebugLoc &DL, uint64_t Offset, 230 uint64_t Align) const; 231 232 void emitStackProbeInlineGenericLoop(MachineFunction &MF, 233 MachineBasicBlock &MBB, 234 MachineBasicBlock::iterator MBBI, 235 const DebugLoc &DL, uint64_t Offset, 236 uint64_t Align) const; 237 238 /// Emit target zero call-used regs. 239 void emitZeroCallUsedRegs(BitVector RegsToZero, 240 MachineBasicBlock &MBB) const override; 241 242 void adjustFrameForMsvcCxxEh(MachineFunction &MF) const; 243 244 /// Aligns the stack pointer by ANDing it with -MaxAlign. 245 void BuildStackAlignAND(MachineBasicBlock &MBB, 246 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 247 unsigned Reg, uint64_t MaxAlign) const; 248 249 /// Make small positive stack adjustments using POPs. 250 bool adjustStackWithPops(MachineBasicBlock &MBB, 251 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 252 int Offset) const; 253 254 /// Adjusts the stack pointer using LEA, SUB, or ADD. 255 MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB, 256 MachineBasicBlock::iterator MBBI, 257 const DebugLoc &DL, int64_t Offset, 258 bool InEpilogue) const; 259 260 unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const; 261 262 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const; 263 264 /// Materialize the catchret target MBB in RAX. 265 void emitCatchRetReturnValue(MachineBasicBlock &MBB, 266 MachineBasicBlock::iterator MBBI, 267 MachineInstr *CatchRet) const; 268 }; 269 270 } // End llvm namespace 271 272 #endif 273