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 18 namespace llvm { 19 20 class MachineInstrBuilder; 21 class MCCFIInstruction; 22 class X86InstrInfo; 23 class X86Subtarget; 24 class X86RegisterInfo; 25 26 class X86FrameLowering : public TargetFrameLowering { 27 public: 28 X86FrameLowering(const X86Subtarget &STI, MaybeAlign StackAlignOverride); 29 30 // Cached subtarget predicates. 31 32 const X86Subtarget &STI; 33 const X86InstrInfo &TII; 34 const X86RegisterInfo *TRI; 35 36 unsigned SlotSize; 37 38 /// Is64Bit implies that x86_64 instructions are available. 39 bool Is64Bit; 40 41 bool IsLP64; 42 43 /// True if the 64-bit frame or stack pointer should be used. True for most 44 /// 64-bit targets with the exception of x32. If this is false, 32-bit 45 /// instruction operands should be used to manipulate StackPtr and FramePtr. 46 bool Uses64BitFramePtr; 47 48 unsigned StackPtr; 49 50 /// Emit target stack probe code. This is required for all 51 /// large stack allocations on Windows. The caller is required to materialize 52 /// the number of bytes to probe in RAX/EAX. 53 void emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB, 54 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 55 bool InProlog) const; 56 57 /// Replace a StackProbe inline-stub with the actual probe code inline. 58 void inlineStackProbe(MachineFunction &MF, 59 MachineBasicBlock &PrologMBB) const override; 60 61 void 62 emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, 63 MachineBasicBlock::iterator MBBI) const override; 64 65 void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, 66 MachineBasicBlock::iterator MBBI, 67 const DebugLoc &DL, 68 bool IsPrologue) const override; 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 int 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 int getFrameIndexReferenceSP(const MachineFunction &MF, int FI, 111 Register &SPReg, int Adjustment) const; 112 int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, 113 Register &FrameReg, 114 bool IgnoreSPUpdates) const override; 115 116 MachineBasicBlock::iterator 117 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 118 MachineBasicBlock::iterator MI) const override; 119 120 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override; 121 122 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 123 RegScavenger *RS) const override; 124 125 void 126 processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, 127 RegScavenger *RS) const override; 128 129 /// Check the instruction before/after the passed instruction. If 130 /// it is an ADD/SUB/LEA instruction it is deleted argument and the 131 /// stack adjustment is returned as a positive value for ADD/LEA and 132 /// a negative for SUB. 133 int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 134 bool doMergeWithPrevious) const; 135 136 /// Emit a series of instructions to increment / decrement the stack 137 /// pointer by a constant value. 138 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 139 const DebugLoc &DL, int64_t NumBytes, bool InEpilogue) const; 140 141 /// Check that LEA can be used on SP in an epilogue sequence for \p MF. 142 bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const; 143 144 /// Check whether or not the given \p MBB can be used as a prologue 145 /// for the target. 146 /// The prologue will be inserted first in this basic block. 147 /// This method is used by the shrink-wrapping pass to decide if 148 /// \p MBB will be correctly handled by the target. 149 /// As soon as the target enable shrink-wrapping without overriding 150 /// this method, we assume that each basic block is a valid 151 /// prologue. 152 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; 153 154 /// Check whether or not the given \p MBB can be used as a epilogue 155 /// for the target. 156 /// The epilogue will be inserted before the first terminator of that block. 157 /// This method is used by the shrink-wrapping pass to decide if 158 /// \p MBB will be correctly handled by the target. 159 bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override; 160 161 /// Returns true if the target will correctly handle shrink wrapping. 162 bool enableShrinkWrapping(const MachineFunction &MF) const override; 163 164 /// Order the symbols in the local stack. 165 /// We want to place the local stack objects in some sort of sensible order. 166 /// The heuristic we use is to try and pack them according to static number 167 /// of uses and size in order to minimize code size. 168 void orderFrameObjects(const MachineFunction &MF, 169 SmallVectorImpl<int> &ObjectsToAllocate) const override; 170 171 /// Wraps up getting a CFI index and building a MachineInstr for it. 172 void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 173 const DebugLoc &DL, const MCCFIInstruction &CFIInst) const; 174 175 /// Sets up EBP and optionally ESI based on the incoming EBP value. Only 176 /// needed for 32-bit. Used in funclet prologues and at catchret destinations. 177 MachineBasicBlock::iterator 178 restoreWin32EHStackPointers(MachineBasicBlock &MBB, 179 MachineBasicBlock::iterator MBBI, 180 const DebugLoc &DL, bool RestoreSP = false) const; 181 182 void restoreWinEHStackPointersInParent(MachineFunction &MF) const; 183 184 int getInitialCFAOffset(const MachineFunction &MF) const override; 185 186 Register getInitialCFARegister(const MachineFunction &MF) const override; 187 188 /// Return true if the function has a redzone (accessible bytes past the 189 /// frame of the top of stack function) as part of it's ABI. 190 bool has128ByteRedZone(const MachineFunction& MF) const; 191 192 private: 193 uint64_t calculateMaxStackAlign(const MachineFunction &MF) const; 194 195 /// Emit target stack probe as a call to a helper function 196 void emitStackProbeCall(MachineFunction &MF, MachineBasicBlock &MBB, 197 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 198 bool InProlog) const; 199 200 /// Emit target stack probe as an inline sequence. 201 void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB, 202 MachineBasicBlock::iterator MBBI, 203 const DebugLoc &DL, bool InProlog) const; 204 void emitStackProbeInlineWindowsCoreCLR64(MachineFunction &MF, 205 MachineBasicBlock &MBB, 206 MachineBasicBlock::iterator MBBI, 207 const DebugLoc &DL, 208 bool InProlog) const; 209 void emitStackProbeInlineGeneric(MachineFunction &MF, MachineBasicBlock &MBB, 210 MachineBasicBlock::iterator MBBI, 211 const DebugLoc &DL, bool InProlog) const; 212 213 void emitStackProbeInlineGenericBlock(MachineFunction &MF, 214 MachineBasicBlock &MBB, 215 MachineBasicBlock::iterator MBBI, 216 const DebugLoc &DL, uint64_t Offset, 217 uint64_t Align) const; 218 219 void emitStackProbeInlineGenericLoop(MachineFunction &MF, 220 MachineBasicBlock &MBB, 221 MachineBasicBlock::iterator MBBI, 222 const DebugLoc &DL, uint64_t Offset, 223 uint64_t Align) const; 224 225 /// Emit a stub to later inline the target stack probe. 226 MachineInstr *emitStackProbeInlineStub(MachineFunction &MF, 227 MachineBasicBlock &MBB, 228 MachineBasicBlock::iterator MBBI, 229 const DebugLoc &DL, 230 bool InProlog) 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