1 //===-- X86TargetFrameLowering.h - Define frame lowering for X86 -*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
9 // This class implements X86-specific bits of TargetFrameLowering class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H
14 #define LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H
16 #include "llvm/CodeGen/MachineFunction.h"
17 #include "llvm/CodeGen/TargetFrameLowering.h"
18 #include "llvm/Support/TypeSize.h"
22 class MachineInstrBuilder
;
23 class MCCFIInstruction
;
26 class X86RegisterInfo
;
28 class X86FrameLowering
: public TargetFrameLowering
{
30 X86FrameLowering(const X86Subtarget
&STI
, MaybeAlign StackAlignOverride
);
32 // Cached subtarget predicates.
34 const X86Subtarget
&STI
;
35 const X86InstrInfo
&TII
;
36 const X86RegisterInfo
*TRI
;
40 /// Is64Bit implies that x86_64 instructions are available.
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
;
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(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
58 MachineBasicBlock::iterator MBBI
, const DebugLoc
&DL
,
60 std::optional
<MachineFunction::DebugInstrOperandPair
>
61 InstrNum
= std::nullopt
) const;
63 bool stackProbeFunctionModifiesSP() const override
;
65 /// Replace a StackProbe inline-stub with the actual probe code inline.
66 void inlineStackProbe(MachineFunction
&MF
,
67 MachineBasicBlock
&PrologMBB
) const override
;
69 void emitCalleeSavedFrameMovesFullCFA(
70 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
) const override
;
72 void emitCalleeSavedFrameMoves(MachineBasicBlock
&MBB
,
73 MachineBasicBlock::iterator MBBI
,
74 const DebugLoc
&DL
, bool IsPrologue
) const;
76 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
78 void emitPrologue(MachineFunction
&MF
, MachineBasicBlock
&MBB
) const override
;
79 void emitEpilogue(MachineFunction
&MF
, MachineBasicBlock
&MBB
) const override
;
81 void adjustForSegmentedStacks(MachineFunction
&MF
,
82 MachineBasicBlock
&PrologueMBB
) const override
;
84 void adjustForHiPEPrologue(MachineFunction
&MF
,
85 MachineBasicBlock
&PrologueMBB
) const override
;
87 void determineCalleeSaves(MachineFunction
&MF
, BitVector
&SavedRegs
,
88 RegScavenger
*RS
= nullptr) const override
;
91 assignCalleeSavedSpillSlots(MachineFunction
&MF
,
92 const TargetRegisterInfo
*TRI
,
93 std::vector
<CalleeSavedInfo
> &CSI
) const override
;
95 bool spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
96 MachineBasicBlock::iterator MI
,
97 ArrayRef
<CalleeSavedInfo
> CSI
,
98 const TargetRegisterInfo
*TRI
) const override
;
101 restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
102 MachineBasicBlock::iterator MI
,
103 MutableArrayRef
<CalleeSavedInfo
> CSI
,
104 const TargetRegisterInfo
*TRI
) const override
;
106 void spillFPBP(MachineFunction
&MF
) const override
;
108 bool hasReservedCallFrame(const MachineFunction
&MF
) const override
;
109 bool canSimplifyCallFramePseudos(const MachineFunction
&MF
) const override
;
110 bool needsFrameIndexResolution(const MachineFunction
&MF
) const override
;
112 StackOffset
getFrameIndexReference(const MachineFunction
&MF
, int FI
,
113 Register
&FrameReg
) const override
;
115 int getWin64EHFrameIndexRef(const MachineFunction
&MF
, int FI
,
116 Register
&SPReg
) const;
117 StackOffset
getFrameIndexReferenceSP(const MachineFunction
&MF
, int FI
,
118 Register
&SPReg
, int Adjustment
) const;
120 getFrameIndexReferencePreferSP(const MachineFunction
&MF
, int FI
,
122 bool IgnoreSPUpdates
) const override
;
124 MachineBasicBlock::iterator
125 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
126 MachineBasicBlock::iterator MI
) const override
;
128 unsigned getWinEHParentFrameOffset(const MachineFunction
&MF
) const override
;
130 void processFunctionBeforeFrameFinalized(MachineFunction
&MF
,
131 RegScavenger
*RS
) const override
;
134 processFunctionBeforeFrameIndicesReplaced(MachineFunction
&MF
,
135 RegScavenger
*RS
) const override
;
137 /// Check the instruction before/after the passed instruction. If
138 /// it is an ADD/SUB/LEA instruction it is deleted argument and the
139 /// stack adjustment is returned as a positive value for ADD/LEA and
140 /// a negative for SUB.
141 int mergeSPUpdates(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator
&MBBI
,
142 bool doMergeWithPrevious
) const;
144 /// Emit a series of instructions to increment / decrement the stack
145 /// pointer by a constant value.
146 void emitSPUpdate(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator
&MBBI
,
147 const DebugLoc
&DL
, int64_t NumBytes
, bool InEpilogue
) const;
149 /// Check that LEA can be used on SP in an epilogue sequence for \p MF.
150 bool canUseLEAForSPInEpilogue(const MachineFunction
&MF
) const;
152 /// Check whether or not the given \p MBB can be used as a prologue
154 /// The prologue will be inserted first in this basic block.
155 /// This method is used by the shrink-wrapping pass to decide if
156 /// \p MBB will be correctly handled by the target.
157 /// As soon as the target enable shrink-wrapping without overriding
158 /// this method, we assume that each basic block is a valid
160 bool canUseAsPrologue(const MachineBasicBlock
&MBB
) const override
;
162 /// Check whether or not the given \p MBB can be used as a epilogue
164 /// The epilogue will be inserted before the first terminator of that block.
165 /// This method is used by the shrink-wrapping pass to decide if
166 /// \p MBB will be correctly handled by the target.
167 bool canUseAsEpilogue(const MachineBasicBlock
&MBB
) const override
;
169 /// Returns true if the target will correctly handle shrink wrapping.
170 bool enableShrinkWrapping(const MachineFunction
&MF
) const override
;
172 /// Order the symbols in the local stack.
173 /// We want to place the local stack objects in some sort of sensible order.
174 /// The heuristic we use is to try and pack them according to static number
175 /// of uses and size in order to minimize code size.
176 void orderFrameObjects(const MachineFunction
&MF
,
177 SmallVectorImpl
<int> &ObjectsToAllocate
) const override
;
179 /// Wraps up getting a CFI index and building a MachineInstr for it.
180 void BuildCFI(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
181 const DebugLoc
&DL
, const MCCFIInstruction
&CFIInst
,
182 MachineInstr::MIFlag Flag
= MachineInstr::NoFlags
) const;
184 /// Sets up EBP and optionally ESI based on the incoming EBP value. Only
185 /// needed for 32-bit. Used in funclet prologues and at catchret destinations.
186 MachineBasicBlock::iterator
187 restoreWin32EHStackPointers(MachineBasicBlock
&MBB
,
188 MachineBasicBlock::iterator MBBI
,
189 const DebugLoc
&DL
, bool RestoreSP
= false) const;
191 void restoreWinEHStackPointersInParent(MachineFunction
&MF
) const;
193 int getInitialCFAOffset(const MachineFunction
&MF
) const override
;
195 Register
getInitialCFARegister(const MachineFunction
&MF
) const override
;
197 DwarfFrameBase
getDwarfFrameBase(const MachineFunction
&MF
) const override
;
199 /// Return true if the function has a redzone (accessible bytes past the
200 /// frame of the top of stack function) as part of it's ABI.
201 bool has128ByteRedZone(const MachineFunction
& MF
) const;
204 bool hasFPImpl(const MachineFunction
&MF
) const override
;
207 bool isWin64Prologue(const MachineFunction
&MF
) const;
209 bool needsDwarfCFI(const MachineFunction
&MF
) const;
211 uint64_t calculateMaxStackAlign(const MachineFunction
&MF
) const;
213 /// Emit target stack probe as a call to a helper function
214 void emitStackProbeCall(
215 MachineFunction
&MF
, MachineBasicBlock
&MBB
,
216 MachineBasicBlock::iterator MBBI
, const DebugLoc
&DL
, bool InProlog
,
217 std::optional
<MachineFunction::DebugInstrOperandPair
> InstrNum
) const;
219 /// Emit target stack probe as an inline sequence.
220 void emitStackProbeInline(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
221 MachineBasicBlock::iterator MBBI
,
222 const DebugLoc
&DL
, bool InProlog
) const;
223 void emitStackProbeInlineWindowsCoreCLR64(MachineFunction
&MF
,
224 MachineBasicBlock
&MBB
,
225 MachineBasicBlock::iterator MBBI
,
227 bool InProlog
) const;
228 void emitStackProbeInlineGeneric(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
229 MachineBasicBlock::iterator MBBI
,
230 const DebugLoc
&DL
, bool InProlog
) const;
232 void emitStackProbeInlineGenericBlock(MachineFunction
&MF
,
233 MachineBasicBlock
&MBB
,
234 MachineBasicBlock::iterator MBBI
,
235 const DebugLoc
&DL
, uint64_t Offset
,
236 uint64_t Align
) const;
238 void emitStackProbeInlineGenericLoop(MachineFunction
&MF
,
239 MachineBasicBlock
&MBB
,
240 MachineBasicBlock::iterator MBBI
,
241 const DebugLoc
&DL
, uint64_t Offset
,
242 uint64_t Align
) const;
244 /// Emit target zero call-used regs.
245 void emitZeroCallUsedRegs(BitVector RegsToZero
,
246 MachineBasicBlock
&MBB
) const override
;
248 void adjustFrameForMsvcCxxEh(MachineFunction
&MF
) const;
250 /// Aligns the stack pointer by ANDing it with -MaxAlign.
251 void BuildStackAlignAND(MachineBasicBlock
&MBB
,
252 MachineBasicBlock::iterator MBBI
, const DebugLoc
&DL
,
253 unsigned Reg
, uint64_t MaxAlign
) const;
255 /// Make small positive stack adjustments using POPs.
256 bool adjustStackWithPops(MachineBasicBlock
&MBB
,
257 MachineBasicBlock::iterator MBBI
, const DebugLoc
&DL
,
260 /// Adjusts the stack pointer using LEA, SUB, or ADD.
261 MachineInstrBuilder
BuildStackAdjustment(MachineBasicBlock
&MBB
,
262 MachineBasicBlock::iterator MBBI
,
263 const DebugLoc
&DL
, int64_t Offset
,
264 bool InEpilogue
) const;
266 unsigned getPSPSlotOffsetFromSP(const MachineFunction
&MF
) const;
268 unsigned getWinEHFuncletFrameSize(const MachineFunction
&MF
) const;
270 /// Materialize the catchret target MBB in RAX.
271 void emitCatchRetReturnValue(MachineBasicBlock
&MBB
,
272 MachineBasicBlock::iterator MBBI
,
273 MachineInstr
*CatchRet
) const;
275 /// Issue instructions to allocate stack space and spill frame pointer and/or
276 /// base pointer to stack using stack pointer register.
277 void spillFPBPUsingSP(MachineFunction
&MF
,
278 const MachineBasicBlock::iterator BeforeMI
, Register FP
,
279 Register BP
, int SPAdjust
) const;
281 /// Issue instructions to restore frame pointer and/or base pointer from stack
282 /// using stack pointer register, and free stack space.
283 void restoreFPBPUsingSP(MachineFunction
&MF
,
284 const MachineBasicBlock::iterator AfterMI
,
285 Register FP
, Register BP
, int SPAdjust
) const;
287 void saveAndRestoreFPBPUsingSP(MachineFunction
&MF
,
288 MachineBasicBlock::iterator BeforeMI
,
289 MachineBasicBlock::iterator AfterMI
,
290 bool SpillFP
, bool SpillBP
) const;
292 void checkInterferedAccess(MachineFunction
&MF
,
293 MachineBasicBlock::reverse_iterator DefMI
,
294 MachineBasicBlock::reverse_iterator KillMI
,
295 bool SpillFP
, bool SpillBP
) const;
297 // If MI uses fp/bp, but target can handle it, and doesn't want to be spilled
298 // again, this function should return true, and update MI so we will not check
299 // any instructions from related sequence.
300 bool skipSpillFPBP(MachineFunction
&MF
,
301 MachineBasicBlock::reverse_iterator
&MI
) const;
304 } // End llvm namespace