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 void spillFPBP(MachineFunction &MF) const override; 107 108 bool hasReservedCallFrame(const MachineFunction &MF) const override; 109 bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; 110 bool needsFrameIndexResolution(const MachineFunction &MF) const override; 111 112 StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 113 Register &FrameReg) const override; 114 115 int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI, 116 Register &SPReg) const; 117 StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI, 118 Register &SPReg, int Adjustment) const; 119 StackOffset 120 getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, 121 Register &FrameReg, 122 bool IgnoreSPUpdates) const override; 123 124 MachineBasicBlock::iterator 125 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 126 MachineBasicBlock::iterator MI) const override; 127 128 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override; 129 130 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 131 RegScavenger *RS) const override; 132 133 void 134 processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, 135 RegScavenger *RS) const override; 136 137 /// Check the instruction before/after the passed instruction. If 138 /// it is an ADD/SUB/LEA instruction it is deleted argument and the 139 /// stack adjustment is returned as a positive value for ADD/LEA and 140 /// a negative for SUB. 141 int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 142 bool doMergeWithPrevious) const; 143 144 /// Emit a series of instructions to increment / decrement the stack 145 /// pointer by a constant value. 146 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 147 const DebugLoc &DL, int64_t NumBytes, bool InEpilogue) const; 148 149 /// Check that LEA can be used on SP in an epilogue sequence for \p MF. 150 bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const; 151 152 /// Check whether or not the given \p MBB can be used as a prologue 153 /// for the target. 154 /// The prologue will be inserted first in this basic block. 155 /// This method is used by the shrink-wrapping pass to decide if 156 /// \p MBB will be correctly handled by the target. 157 /// As soon as the target enable shrink-wrapping without overriding 158 /// this method, we assume that each basic block is a valid 159 /// prologue. 160 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; 161 162 /// Check whether or not the given \p MBB can be used as a epilogue 163 /// for the target. 164 /// The epilogue will be inserted before the first terminator of that block. 165 /// This method is used by the shrink-wrapping pass to decide if 166 /// \p MBB will be correctly handled by the target. 167 bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override; 168 169 /// Returns true if the target will correctly handle shrink wrapping. 170 bool enableShrinkWrapping(const MachineFunction &MF) const override; 171 172 /// Order the symbols in the local stack. 173 /// We want to place the local stack objects in some sort of sensible order. 174 /// The heuristic we use is to try and pack them according to static number 175 /// of uses and size in order to minimize code size. 176 void orderFrameObjects(const MachineFunction &MF, 177 SmallVectorImpl<int> &ObjectsToAllocate) const override; 178 179 /// Wraps up getting a CFI index and building a MachineInstr for it. 180 void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 181 const DebugLoc &DL, const MCCFIInstruction &CFIInst, 182 MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; 183 184 /// Sets up EBP and optionally ESI based on the incoming EBP value. Only 185 /// needed for 32-bit. Used in funclet prologues and at catchret destinations. 186 MachineBasicBlock::iterator 187 restoreWin32EHStackPointers(MachineBasicBlock &MBB, 188 MachineBasicBlock::iterator MBBI, 189 const DebugLoc &DL, bool RestoreSP = false) const; 190 191 void restoreWinEHStackPointersInParent(MachineFunction &MF) const; 192 193 int getInitialCFAOffset(const MachineFunction &MF) const override; 194 195 Register getInitialCFARegister(const MachineFunction &MF) const override; 196 197 DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override; 198 199 /// Return true if the function has a redzone (accessible bytes past the 200 /// frame of the top of stack function) as part of it's ABI. 201 bool has128ByteRedZone(const MachineFunction& MF) const; 202 203 protected: 204 bool hasFPImpl(const MachineFunction &MF) const override; 205 206 private: 207 bool isWin64Prologue(const MachineFunction &MF) const; 208 209 bool needsDwarfCFI(const MachineFunction &MF) const; 210 211 uint64_t calculateMaxStackAlign(const MachineFunction &MF) const; 212 213 /// Emit target stack probe as a call to a helper function 214 void emitStackProbeCall( 215 MachineFunction &MF, MachineBasicBlock &MBB, 216 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog, 217 std::optional<MachineFunction::DebugInstrOperandPair> InstrNum) const; 218 219 /// Emit target stack probe as an inline sequence. 220 void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB, 221 MachineBasicBlock::iterator MBBI, 222 const DebugLoc &DL, bool InProlog) const; 223 void emitStackProbeInlineWindowsCoreCLR64(MachineFunction &MF, 224 MachineBasicBlock &MBB, 225 MachineBasicBlock::iterator MBBI, 226 const DebugLoc &DL, 227 bool InProlog) const; 228 void emitStackProbeInlineGeneric(MachineFunction &MF, MachineBasicBlock &MBB, 229 MachineBasicBlock::iterator MBBI, 230 const DebugLoc &DL, bool InProlog) const; 231 232 void emitStackProbeInlineGenericBlock(MachineFunction &MF, 233 MachineBasicBlock &MBB, 234 MachineBasicBlock::iterator MBBI, 235 const DebugLoc &DL, uint64_t Offset, 236 uint64_t Align) const; 237 238 void emitStackProbeInlineGenericLoop(MachineFunction &MF, 239 MachineBasicBlock &MBB, 240 MachineBasicBlock::iterator MBBI, 241 const DebugLoc &DL, uint64_t Offset, 242 uint64_t Align) const; 243 244 /// Emit target zero call-used regs. 245 void emitZeroCallUsedRegs(BitVector RegsToZero, 246 MachineBasicBlock &MBB) const override; 247 248 void adjustFrameForMsvcCxxEh(MachineFunction &MF) const; 249 250 /// Aligns the stack pointer by ANDing it with -MaxAlign. 251 void BuildStackAlignAND(MachineBasicBlock &MBB, 252 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 253 unsigned Reg, uint64_t MaxAlign) const; 254 255 /// Make small positive stack adjustments using POPs. 256 bool adjustStackWithPops(MachineBasicBlock &MBB, 257 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 258 int Offset) const; 259 260 /// Adjusts the stack pointer using LEA, SUB, or ADD. 261 MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB, 262 MachineBasicBlock::iterator MBBI, 263 const DebugLoc &DL, int64_t Offset, 264 bool InEpilogue) const; 265 266 unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const; 267 268 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const; 269 270 /// Materialize the catchret target MBB in RAX. 271 void emitCatchRetReturnValue(MachineBasicBlock &MBB, 272 MachineBasicBlock::iterator MBBI, 273 MachineInstr *CatchRet) const; 274 275 /// Issue instructions to allocate stack space and spill frame pointer and/or 276 /// base pointer to stack using stack pointer register. 277 void spillFPBPUsingSP(MachineFunction &MF, 278 const MachineBasicBlock::iterator BeforeMI, Register FP, 279 Register BP, int SPAdjust) const; 280 281 /// Issue instructions to restore frame pointer and/or base pointer from stack 282 /// using stack pointer register, and free stack space. 283 void restoreFPBPUsingSP(MachineFunction &MF, 284 const MachineBasicBlock::iterator AfterMI, 285 Register FP, Register BP, int SPAdjust) const; 286 287 void saveAndRestoreFPBPUsingSP(MachineFunction &MF, 288 MachineBasicBlock::iterator BeforeMI, 289 MachineBasicBlock::iterator AfterMI, 290 bool SpillFP, bool SpillBP) const; 291 292 void checkInterferedAccess(MachineFunction &MF, 293 MachineBasicBlock::reverse_iterator DefMI, 294 MachineBasicBlock::reverse_iterator KillMI, 295 bool SpillFP, bool SpillBP) const; 296 297 // If MI uses fp/bp, but target can handle it, and doesn't want to be spilled 298 // again, this function should return true, and update MI so we will not check 299 // any instructions from related sequence. 300 bool skipSpillFPBP(MachineFunction &MF, 301 MachineBasicBlock::reverse_iterator &MI) const; 302 }; 303 304 } // End llvm namespace 305 306 #endif 307