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