xref: /aosp_15_r20/external/llvm/lib/Target/X86/X86FrameLowering.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- X86TargetFrameLowering.h - Define frame lowering for X86 -*- C++ -*-==//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This class implements X86-specific bits of TargetFrameLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetFrameLowering.h"
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker namespace llvm {
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker class MachineInstrBuilder;
22*9880d681SAndroid Build Coastguard Worker class MCCFIInstruction;
23*9880d681SAndroid Build Coastguard Worker class X86Subtarget;
24*9880d681SAndroid Build Coastguard Worker class X86RegisterInfo;
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker class X86FrameLowering : public TargetFrameLowering {
27*9880d681SAndroid Build Coastguard Worker public:
28*9880d681SAndroid Build Coastguard Worker   X86FrameLowering(const X86Subtarget &STI, unsigned StackAlignOverride);
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker   // Cached subtarget predicates.
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker   const X86Subtarget &STI;
33*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII;
34*9880d681SAndroid Build Coastguard Worker   const X86RegisterInfo *TRI;
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker   unsigned SlotSize;
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker   /// Is64Bit implies that x86_64 instructions are available.
39*9880d681SAndroid Build Coastguard Worker   bool Is64Bit;
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker   bool IsLP64;
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker   /// True if the 64-bit frame or stack pointer should be used. True for most
44*9880d681SAndroid Build Coastguard Worker   /// 64-bit targets with the exception of x32. If this is false, 32-bit
45*9880d681SAndroid Build Coastguard Worker   /// instruction operands should be used to manipulate StackPtr and FramePtr.
46*9880d681SAndroid Build Coastguard Worker   bool Uses64BitFramePtr;
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   unsigned StackPtr;
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker   /// Emit target stack probe code. This is required for all
51*9880d681SAndroid Build Coastguard Worker   /// large stack allocations on Windows. The caller is required to materialize
52*9880d681SAndroid Build Coastguard Worker   /// the number of bytes to probe in RAX/EAX. Returns instruction just
53*9880d681SAndroid Build Coastguard Worker   /// after the expansion.
54*9880d681SAndroid Build Coastguard Worker   MachineInstr *emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB,
55*9880d681SAndroid Build Coastguard Worker                                MachineBasicBlock::iterator MBBI,
56*9880d681SAndroid Build Coastguard Worker                                const DebugLoc &DL, bool InProlog) const;
57*9880d681SAndroid Build Coastguard Worker 
58*9880d681SAndroid Build Coastguard Worker   /// Replace a StackProbe inline-stub with the actual probe code inline.
59*9880d681SAndroid Build Coastguard Worker   void inlineStackProbe(MachineFunction &MF,
60*9880d681SAndroid Build Coastguard Worker                         MachineBasicBlock &PrologMBB) const override;
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker   void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
63*9880d681SAndroid Build Coastguard Worker                                  MachineBasicBlock::iterator MBBI,
64*9880d681SAndroid Build Coastguard Worker                                  const DebugLoc &DL) const;
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker   /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
67*9880d681SAndroid Build Coastguard Worker   /// the function.
68*9880d681SAndroid Build Coastguard Worker   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
69*9880d681SAndroid Build Coastguard Worker   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   void adjustForSegmentedStacks(MachineFunction &MF,
72*9880d681SAndroid Build Coastguard Worker                                 MachineBasicBlock &PrologueMBB) const override;
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   void adjustForHiPEPrologue(MachineFunction &MF,
75*9880d681SAndroid Build Coastguard Worker                              MachineBasicBlock &PrologueMBB) const override;
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
78*9880d681SAndroid Build Coastguard Worker                             RegScavenger *RS = nullptr) const override;
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   bool
81*9880d681SAndroid Build Coastguard Worker   assignCalleeSavedSpillSlots(MachineFunction &MF,
82*9880d681SAndroid Build Coastguard Worker                               const TargetRegisterInfo *TRI,
83*9880d681SAndroid Build Coastguard Worker                               std::vector<CalleeSavedInfo> &CSI) const override;
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
86*9880d681SAndroid Build Coastguard Worker                                  MachineBasicBlock::iterator MI,
87*9880d681SAndroid Build Coastguard Worker                                  const std::vector<CalleeSavedInfo> &CSI,
88*9880d681SAndroid Build Coastguard Worker                                  const TargetRegisterInfo *TRI) const override;
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
91*9880d681SAndroid Build Coastguard Worker                                   MachineBasicBlock::iterator MI,
92*9880d681SAndroid Build Coastguard Worker                                   const std::vector<CalleeSavedInfo> &CSI,
93*9880d681SAndroid Build Coastguard Worker                                   const TargetRegisterInfo *TRI) const override;
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   bool hasFP(const MachineFunction &MF) const override;
96*9880d681SAndroid Build Coastguard Worker   bool hasReservedCallFrame(const MachineFunction &MF) const override;
97*9880d681SAndroid Build Coastguard Worker   bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
98*9880d681SAndroid Build Coastguard Worker   bool needsFrameIndexResolution(const MachineFunction &MF) const override;
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   int getFrameIndexReference(const MachineFunction &MF, int FI,
101*9880d681SAndroid Build Coastguard Worker                              unsigned &FrameReg) const override;
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker   int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
104*9880d681SAndroid Build Coastguard Worker                                      unsigned &FrameReg,
105*9880d681SAndroid Build Coastguard Worker                                      bool IgnoreSPUpdates) const override;
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator
108*9880d681SAndroid Build Coastguard Worker   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
109*9880d681SAndroid Build Coastguard Worker                                 MachineBasicBlock::iterator MI) const override;
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
114*9880d681SAndroid Build Coastguard Worker                                            RegScavenger *RS) const override;
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   /// Check the instruction before/after the passed instruction. If
117*9880d681SAndroid Build Coastguard Worker   /// it is an ADD/SUB/LEA instruction it is deleted argument and the
118*9880d681SAndroid Build Coastguard Worker   /// stack adjustment is returned as a positive value for ADD/LEA and
119*9880d681SAndroid Build Coastguard Worker   /// a negative for SUB.
120*9880d681SAndroid Build Coastguard Worker   int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
121*9880d681SAndroid Build Coastguard Worker                      bool doMergeWithPrevious) const;
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker   /// Emit a series of instructions to increment / decrement the stack
124*9880d681SAndroid Build Coastguard Worker   /// pointer by a constant value.
125*9880d681SAndroid Build Coastguard Worker   void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
126*9880d681SAndroid Build Coastguard Worker                     int64_t NumBytes, bool InEpilogue) const;
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   /// Check that LEA can be used on SP in an epilogue sequence for \p MF.
129*9880d681SAndroid Build Coastguard Worker   bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const;
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   /// Check whether or not the given \p MBB can be used as a prologue
132*9880d681SAndroid Build Coastguard Worker   /// for the target.
133*9880d681SAndroid Build Coastguard Worker   /// The prologue will be inserted first in this basic block.
134*9880d681SAndroid Build Coastguard Worker   /// This method is used by the shrink-wrapping pass to decide if
135*9880d681SAndroid Build Coastguard Worker   /// \p MBB will be correctly handled by the target.
136*9880d681SAndroid Build Coastguard Worker   /// As soon as the target enable shrink-wrapping without overriding
137*9880d681SAndroid Build Coastguard Worker   /// this method, we assume that each basic block is a valid
138*9880d681SAndroid Build Coastguard Worker   /// prologue.
139*9880d681SAndroid Build Coastguard Worker   bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
140*9880d681SAndroid Build Coastguard Worker 
141*9880d681SAndroid Build Coastguard Worker   /// Check whether or not the given \p MBB can be used as a epilogue
142*9880d681SAndroid Build Coastguard Worker   /// for the target.
143*9880d681SAndroid Build Coastguard Worker   /// The epilogue will be inserted before the first terminator of that block.
144*9880d681SAndroid Build Coastguard Worker   /// This method is used by the shrink-wrapping pass to decide if
145*9880d681SAndroid Build Coastguard Worker   /// \p MBB will be correctly handled by the target.
146*9880d681SAndroid Build Coastguard Worker   bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker   /// Returns true if the target will correctly handle shrink wrapping.
149*9880d681SAndroid Build Coastguard Worker   bool enableShrinkWrapping(const MachineFunction &MF) const override;
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker   /// Order the symbols in the local stack.
152*9880d681SAndroid Build Coastguard Worker   /// We want to place the local stack objects in some sort of sensible order.
153*9880d681SAndroid Build Coastguard Worker   /// The heuristic we use is to try and pack them according to static number
154*9880d681SAndroid Build Coastguard Worker   /// of uses and size in order to minimize code size.
155*9880d681SAndroid Build Coastguard Worker   void orderFrameObjects(const MachineFunction &MF,
156*9880d681SAndroid Build Coastguard Worker                          SmallVectorImpl<int> &ObjectsToAllocate) const override;
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   /// convertArgMovsToPushes - This method tries to convert a call sequence
159*9880d681SAndroid Build Coastguard Worker   /// that uses sub and mov instructions to put the argument onto the stack
160*9880d681SAndroid Build Coastguard Worker   /// into a series of pushes.
161*9880d681SAndroid Build Coastguard Worker   /// Returns true if the transformation succeeded, false if not.
162*9880d681SAndroid Build Coastguard Worker   bool convertArgMovsToPushes(MachineFunction &MF,
163*9880d681SAndroid Build Coastguard Worker                               MachineBasicBlock &MBB,
164*9880d681SAndroid Build Coastguard Worker                               MachineBasicBlock::iterator I,
165*9880d681SAndroid Build Coastguard Worker                               uint64_t Amount) const;
166*9880d681SAndroid Build Coastguard Worker 
167*9880d681SAndroid Build Coastguard Worker   /// Wraps up getting a CFI index and building a MachineInstr for it.
168*9880d681SAndroid Build Coastguard Worker   void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
169*9880d681SAndroid Build Coastguard Worker                 const DebugLoc &DL, const MCCFIInstruction &CFIInst) const;
170*9880d681SAndroid Build Coastguard Worker 
171*9880d681SAndroid Build Coastguard Worker   /// Sets up EBP and optionally ESI based on the incoming EBP value.  Only
172*9880d681SAndroid Build Coastguard Worker   /// needed for 32-bit. Used in funclet prologues and at catchret destinations.
173*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator
174*9880d681SAndroid Build Coastguard Worker   restoreWin32EHStackPointers(MachineBasicBlock &MBB,
175*9880d681SAndroid Build Coastguard Worker                               MachineBasicBlock::iterator MBBI,
176*9880d681SAndroid Build Coastguard Worker                               const DebugLoc &DL, bool RestoreSP = false) const;
177*9880d681SAndroid Build Coastguard Worker 
178*9880d681SAndroid Build Coastguard Worker private:
179*9880d681SAndroid Build Coastguard Worker   uint64_t calculateMaxStackAlign(const MachineFunction &MF) const;
180*9880d681SAndroid Build Coastguard Worker 
181*9880d681SAndroid Build Coastguard Worker   /// Emit target stack probe as a call to a helper function
182*9880d681SAndroid Build Coastguard Worker   MachineInstr *emitStackProbeCall(MachineFunction &MF, MachineBasicBlock &MBB,
183*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock::iterator MBBI,
184*9880d681SAndroid Build Coastguard Worker                                    const DebugLoc &DL, bool InProlog) const;
185*9880d681SAndroid Build Coastguard Worker 
186*9880d681SAndroid Build Coastguard Worker   /// Emit target stack probe as an inline sequence.
187*9880d681SAndroid Build Coastguard Worker   MachineInstr *emitStackProbeInline(MachineFunction &MF,
188*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock &MBB,
189*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock::iterator MBBI,
190*9880d681SAndroid Build Coastguard Worker                                      const DebugLoc &DL, bool InProlog) const;
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker   /// Emit a stub to later inline the target stack probe.
193*9880d681SAndroid Build Coastguard Worker   MachineInstr *emitStackProbeInlineStub(MachineFunction &MF,
194*9880d681SAndroid Build Coastguard Worker                                          MachineBasicBlock &MBB,
195*9880d681SAndroid Build Coastguard Worker                                          MachineBasicBlock::iterator MBBI,
196*9880d681SAndroid Build Coastguard Worker                                          const DebugLoc &DL,
197*9880d681SAndroid Build Coastguard Worker                                          bool InProlog) const;
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker   /// Aligns the stack pointer by ANDing it with -MaxAlign.
200*9880d681SAndroid Build Coastguard Worker   void BuildStackAlignAND(MachineBasicBlock &MBB,
201*9880d681SAndroid Build Coastguard Worker                           MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
202*9880d681SAndroid Build Coastguard Worker                           unsigned Reg, uint64_t MaxAlign) const;
203*9880d681SAndroid Build Coastguard Worker 
204*9880d681SAndroid Build Coastguard Worker   /// Make small positive stack adjustments using POPs.
205*9880d681SAndroid Build Coastguard Worker   bool adjustStackWithPops(MachineBasicBlock &MBB,
206*9880d681SAndroid Build Coastguard Worker                            MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
207*9880d681SAndroid Build Coastguard Worker                            int Offset) const;
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker   /// Adjusts the stack pointer using LEA, SUB, or ADD.
210*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB,
211*9880d681SAndroid Build Coastguard Worker                                            MachineBasicBlock::iterator MBBI,
212*9880d681SAndroid Build Coastguard Worker                                            const DebugLoc &DL, int64_t Offset,
213*9880d681SAndroid Build Coastguard Worker                                            bool InEpilogue) const;
214*9880d681SAndroid Build Coastguard Worker 
215*9880d681SAndroid Build Coastguard Worker   unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const;
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker   unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;
218*9880d681SAndroid Build Coastguard Worker };
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker } // End llvm namespace
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker #endif
223