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( 58 MachineFunction &MF, MachineBasicBlock &MBB, 59 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog, 60 Optional<MachineFunction::DebugInstrOperandPair> InstrNum = None) const; 61 62 bool stackProbeFunctionModifiesSP() const override; 63 64 /// Replace a StackProbe inline-stub with the actual probe code inline. 65 void inlineStackProbe(MachineFunction &MF, 66 MachineBasicBlock &PrologMBB) const override; 67 68 void emitCalleeSavedFrameMovesFullCFA( 69 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override; 70 71 void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, 72 MachineBasicBlock::iterator MBBI, 73 const DebugLoc &DL, bool IsPrologue) const; 74 75 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into 76 /// the function. 77 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 78 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 79 80 void adjustForSegmentedStacks(MachineFunction &MF, 81 MachineBasicBlock &PrologueMBB) const override; 82 83 void adjustForHiPEPrologue(MachineFunction &MF, 84 MachineBasicBlock &PrologueMBB) const override; 85 86 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 87 RegScavenger *RS = nullptr) const override; 88 89 bool 90 assignCalleeSavedSpillSlots(MachineFunction &MF, 91 const TargetRegisterInfo *TRI, 92 std::vector<CalleeSavedInfo> &CSI) const override; 93 94 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 95 MachineBasicBlock::iterator MI, 96 ArrayRef<CalleeSavedInfo> CSI, 97 const TargetRegisterInfo *TRI) const override; 98 99 bool 100 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 101 MachineBasicBlock::iterator MI, 102 MutableArrayRef<CalleeSavedInfo> CSI, 103 const TargetRegisterInfo *TRI) const override; 104 105 bool hasFP(const MachineFunction &MF) const override; 106 bool hasReservedCallFrame(const MachineFunction &MF) const override; 107 bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; 108 bool needsFrameIndexResolution(const MachineFunction &MF) const override; 109 110 StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 111 Register &FrameReg) const override; 112 113 int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI, 114 Register &SPReg) const; 115 StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI, 116 Register &SPReg, int Adjustment) const; 117 StackOffset 118 getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, 119 Register &FrameReg, 120 bool IgnoreSPUpdates) const override; 121 122 MachineBasicBlock::iterator 123 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 124 MachineBasicBlock::iterator MI) const override; 125 126 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override; 127 128 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 129 RegScavenger *RS) const override; 130 131 void 132 processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, 133 RegScavenger *RS) const override; 134 135 /// Check the instruction before/after the passed instruction. If 136 /// it is an ADD/SUB/LEA instruction it is deleted argument and the 137 /// stack adjustment is returned as a positive value for ADD/LEA and 138 /// a negative for SUB. 139 int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 140 bool doMergeWithPrevious) const; 141 142 /// Emit a series of instructions to increment / decrement the stack 143 /// pointer by a constant value. 144 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 145 const DebugLoc &DL, int64_t NumBytes, bool InEpilogue) const; 146 147 /// Check that LEA can be used on SP in an epilogue sequence for \p MF. 148 bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const; 149 150 /// Check whether or not the given \p MBB can be used as a prologue 151 /// for the target. 152 /// The prologue will be inserted first in this basic block. 153 /// This method is used by the shrink-wrapping pass to decide if 154 /// \p MBB will be correctly handled by the target. 155 /// As soon as the target enable shrink-wrapping without overriding 156 /// this method, we assume that each basic block is a valid 157 /// prologue. 158 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; 159 160 /// Check whether or not the given \p MBB can be used as a epilogue 161 /// for the target. 162 /// The epilogue will be inserted before the first terminator of that block. 163 /// This method is used by the shrink-wrapping pass to decide if 164 /// \p MBB will be correctly handled by the target. 165 bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override; 166 167 /// Returns true if the target will correctly handle shrink wrapping. 168 bool enableShrinkWrapping(const MachineFunction &MF) const override; 169 170 /// Order the symbols in the local stack. 171 /// We want to place the local stack objects in some sort of sensible order. 172 /// The heuristic we use is to try and pack them according to static number 173 /// of uses and size in order to minimize code size. 174 void orderFrameObjects(const MachineFunction &MF, 175 SmallVectorImpl<int> &ObjectsToAllocate) const override; 176 177 /// Wraps up getting a CFI index and building a MachineInstr for it. 178 void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 179 const DebugLoc &DL, const MCCFIInstruction &CFIInst) const; 180 181 /// Sets up EBP and optionally ESI based on the incoming EBP value. Only 182 /// needed for 32-bit. Used in funclet prologues and at catchret destinations. 183 MachineBasicBlock::iterator 184 restoreWin32EHStackPointers(MachineBasicBlock &MBB, 185 MachineBasicBlock::iterator MBBI, 186 const DebugLoc &DL, bool RestoreSP = false) const; 187 188 void restoreWinEHStackPointersInParent(MachineFunction &MF) const; 189 190 int getInitialCFAOffset(const MachineFunction &MF) const override; 191 192 Register getInitialCFARegister(const MachineFunction &MF) const override; 193 194 /// Return true if the function has a redzone (accessible bytes past the 195 /// frame of the top of stack function) as part of it's ABI. 196 bool has128ByteRedZone(const MachineFunction& MF) const; 197 198 private: 199 bool isWin64Prologue(const MachineFunction &MF) const; 200 201 bool needsDwarfCFI(const MachineFunction &MF) const; 202 203 uint64_t calculateMaxStackAlign(const MachineFunction &MF) const; 204 205 /// Emit target stack probe as a call to a helper function 206 void emitStackProbeCall( 207 MachineFunction &MF, MachineBasicBlock &MBB, 208 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog, 209 Optional<MachineFunction::DebugInstrOperandPair> InstrNum) const; 210 211 /// Emit target stack probe as an inline sequence. 212 void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB, 213 MachineBasicBlock::iterator MBBI, 214 const DebugLoc &DL, bool InProlog) const; 215 void emitStackProbeInlineWindowsCoreCLR64(MachineFunction &MF, 216 MachineBasicBlock &MBB, 217 MachineBasicBlock::iterator MBBI, 218 const DebugLoc &DL, 219 bool InProlog) const; 220 void emitStackProbeInlineGeneric(MachineFunction &MF, MachineBasicBlock &MBB, 221 MachineBasicBlock::iterator MBBI, 222 const DebugLoc &DL, bool InProlog) const; 223 224 void emitStackProbeInlineGenericBlock(MachineFunction &MF, 225 MachineBasicBlock &MBB, 226 MachineBasicBlock::iterator MBBI, 227 const DebugLoc &DL, uint64_t Offset, 228 uint64_t Align) const; 229 230 void emitStackProbeInlineGenericLoop(MachineFunction &MF, 231 MachineBasicBlock &MBB, 232 MachineBasicBlock::iterator MBBI, 233 const DebugLoc &DL, uint64_t Offset, 234 uint64_t Align) const; 235 236 void adjustFrameForMsvcCxxEh(MachineFunction &MF) const; 237 238 /// Aligns the stack pointer by ANDing it with -MaxAlign. 239 void BuildStackAlignAND(MachineBasicBlock &MBB, 240 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 241 unsigned Reg, uint64_t MaxAlign) const; 242 243 /// Make small positive stack adjustments using POPs. 244 bool adjustStackWithPops(MachineBasicBlock &MBB, 245 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 246 int Offset) const; 247 248 /// Adjusts the stack pointer using LEA, SUB, or ADD. 249 MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB, 250 MachineBasicBlock::iterator MBBI, 251 const DebugLoc &DL, int64_t Offset, 252 bool InEpilogue) const; 253 254 unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const; 255 256 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const; 257 258 /// Materialize the catchret target MBB in RAX. 259 void emitCatchRetReturnValue(MachineBasicBlock &MBB, 260 MachineBasicBlock::iterator MBBI, 261 MachineInstr *CatchRet) const; 262 }; 263 264 } // End llvm namespace 265 266 #endif 267