xref: /openbsd-src/gnu/llvm/llvm/lib/Target/X86/X86FrameLowering.h (revision a96b36398fcfb4953e8190127da8bf074c7552f1)
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 
21 namespace llvm {
22 
23 class MachineInstrBuilder;
24 class MCCFIInstruction;
25 class X86InstrInfo;
26 class X86Subtarget;
27 class X86RegisterInfo;
28 class X86ReturnProtectorLowering;
29 
30 class X86FrameLowering : public TargetFrameLowering {
31 public:
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 
207 private:
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