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/TargetFrameLowering.h"
17 #include "llvm/Support/TypeSize.h"
21 class MachineInstrBuilder
;
22 class MCCFIInstruction
;
25 class X86RegisterInfo
;
27 class X86FrameLowering
: public TargetFrameLowering
{
29 X86FrameLowering(const X86Subtarget
&STI
, MaybeAlign StackAlignOverride
);
31 // Cached subtarget predicates.
33 const X86Subtarget
&STI
;
34 const X86InstrInfo
&TII
;
35 const X86RegisterInfo
*TRI
;
39 /// Is64Bit implies that x86_64 instructions are available.
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
;
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
,
58 /// Replace a StackProbe inline-stub with the actual probe code inline.
59 void inlineStackProbe(MachineFunction
&MF
,
60 MachineBasicBlock
&PrologMBB
) const override
;
63 emitCalleeSavedFrameMoves(MachineBasicBlock
&MBB
,
64 MachineBasicBlock::iterator MBBI
) const override
;
66 void emitCalleeSavedFrameMoves(MachineBasicBlock
&MBB
,
67 MachineBasicBlock::iterator MBBI
,
68 const DebugLoc
&DL
, bool IsPrologue
) const;
70 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
72 void emitPrologue(MachineFunction
&MF
, MachineBasicBlock
&MBB
) const override
;
73 void emitEpilogue(MachineFunction
&MF
, MachineBasicBlock
&MBB
) const override
;
75 void adjustForSegmentedStacks(MachineFunction
&MF
,
76 MachineBasicBlock
&PrologueMBB
) const override
;
78 void adjustForHiPEPrologue(MachineFunction
&MF
,
79 MachineBasicBlock
&PrologueMBB
) const override
;
81 void determineCalleeSaves(MachineFunction
&MF
, BitVector
&SavedRegs
,
82 RegScavenger
*RS
= nullptr) const override
;
85 assignCalleeSavedSpillSlots(MachineFunction
&MF
,
86 const TargetRegisterInfo
*TRI
,
87 std::vector
<CalleeSavedInfo
> &CSI
) const override
;
89 bool spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
90 MachineBasicBlock::iterator MI
,
91 ArrayRef
<CalleeSavedInfo
> CSI
,
92 const TargetRegisterInfo
*TRI
) const override
;
95 restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
96 MachineBasicBlock::iterator MI
,
97 MutableArrayRef
<CalleeSavedInfo
> CSI
,
98 const TargetRegisterInfo
*TRI
) const override
;
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
;
105 StackOffset
getFrameIndexReference(const MachineFunction
&MF
, int FI
,
106 Register
&FrameReg
) const override
;
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;
113 getFrameIndexReferencePreferSP(const MachineFunction
&MF
, int FI
,
115 bool IgnoreSPUpdates
) const override
;
117 MachineBasicBlock::iterator
118 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
119 MachineBasicBlock::iterator MI
) const override
;
121 unsigned getWinEHParentFrameOffset(const MachineFunction
&MF
) const override
;
123 void processFunctionBeforeFrameFinalized(MachineFunction
&MF
,
124 RegScavenger
*RS
) const override
;
127 processFunctionBeforeFrameIndicesReplaced(MachineFunction
&MF
,
128 RegScavenger
*RS
) const override
;
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;
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;
142 /// Check that LEA can be used on SP in an epilogue sequence for \p MF.
143 bool canUseLEAForSPInEpilogue(const MachineFunction
&MF
) const;
145 /// Check whether or not the given \p MBB can be used as a prologue
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
153 bool canUseAsPrologue(const MachineBasicBlock
&MBB
) const override
;
155 /// Check whether or not the given \p MBB can be used as a epilogue
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
;
162 /// Returns true if the target will correctly handle shrink wrapping.
163 bool enableShrinkWrapping(const MachineFunction
&MF
) const override
;
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
;
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;
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;
183 void restoreWinEHStackPointersInParent(MachineFunction
&MF
) const;
185 int getInitialCFAOffset(const MachineFunction
&MF
) const override
;
187 Register
getInitialCFARegister(const MachineFunction
&MF
) const override
;
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;
194 bool isWin64Prologue(const MachineFunction
&MF
) const;
196 bool needsDwarfCFI(const MachineFunction
&MF
) const;
198 uint64_t calculateMaxStackAlign(const MachineFunction
&MF
) const;
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;
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
,
213 bool InProlog
) const;
214 void emitStackProbeInlineGeneric(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
215 MachineBasicBlock::iterator MBBI
,
216 const DebugLoc
&DL
, bool InProlog
) const;
218 void emitStackProbeInlineGenericBlock(MachineFunction
&MF
,
219 MachineBasicBlock
&MBB
,
220 MachineBasicBlock::iterator MBBI
,
221 const DebugLoc
&DL
, uint64_t Offset
,
222 uint64_t Align
) const;
224 void emitStackProbeInlineGenericLoop(MachineFunction
&MF
,
225 MachineBasicBlock
&MBB
,
226 MachineBasicBlock::iterator MBBI
,
227 const DebugLoc
&DL
, uint64_t Offset
,
228 uint64_t Align
) const;
230 void adjustFrameForMsvcCxxEh(MachineFunction
&MF
) const;
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;
237 /// Make small positive stack adjustments using POPs.
238 bool adjustStackWithPops(MachineBasicBlock
&MBB
,
239 MachineBasicBlock::iterator MBBI
, const DebugLoc
&DL
,
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;
248 unsigned getPSPSlotOffsetFromSP(const MachineFunction
&MF
) const;
250 unsigned getWinEHFuncletFrameSize(const MachineFunction
&MF
) const;
252 /// Materialize the catchret target MBB in RAX.
253 void emitCatchRetReturnValue(MachineBasicBlock
&MBB
,
254 MachineBasicBlock::iterator MBBI
,
255 MachineInstr
*CatchRet
) const;
258 } // End llvm namespace