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