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