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