LLVM 24.0.0git
AArch64FrameLowering.h
Go to the documentation of this file.
1//==-- AArch64FrameLowering.h - TargetFrameLowering for AArch64 --*- 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//
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
14#define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
15
19
20namespace llvm {
21
22class TargetLowering;
27
32
34public:
37 true /*StackRealignable*/) {}
38
39 void resetCFIToInitialState(MachineBasicBlock &MBB) const override;
40
43 MachineBasicBlock::iterator I) const override;
44
45 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
46 /// the function.
47 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
48 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
49
50 /// Harden the entire function with pac-ret.
51 ///
52 /// If pac-ret+leaf is requested, we want to harden as much code as possible.
53 /// This function inserts pac-ret hardening at the points where prologue and
54 /// epilogue are traditionally inserted, ignoring possible shrink-wrapping
55 /// optimization.
57
58 bool enableCFIFixup(const MachineFunction &MF) const override;
59
60 bool enableFullCFIFixup(const MachineFunction &MF) const override;
61
62 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
63
65 Register &FrameReg) const override;
67 int FI) const override;
69 Register &FrameReg, bool PreferFP,
70 bool ForSimm) const;
72 int64_t ObjectOffset, bool isFixed,
74 Register &FrameReg, bool PreferFP,
75 bool ForSimm) const;
79 const TargetRegisterInfo *TRI) const override;
80
81 bool
85 const TargetRegisterInfo *TRI) const override;
86
87 /// Can this function use the red zone for local allocations.
88 bool canUseRedZone(const MachineFunction &MF) const;
89
90 /// Returns how much of the incoming argument stack area (in bytes) we should
91 /// clean up in an epilogue. For the C calling convention this will be 0, for
92 /// guaranteed tail call conventions it can be positive (a normal return or a
93 /// tail call to a function that uses less stack space for arguments) or
94 /// negative (for a tail call to a function that needs more stack space than
95 /// us for arguments).
97 MachineBasicBlock &MBB) const;
98
99 /// Whether the return address is authenticated before the epilogue starts,
100 /// in the return block MBB, with the authenticated value then kept in LR
101 /// instead of being restored from the stack by the epilogue.
102 ///
103 /// We need to do this on Windows when doing tail calls where the caller
104 /// and callee use different amounts of stack space for arguments.
106 MachineBasicBlock &MBB) const;
107
108 bool hasReservedCallFrame(const MachineFunction &MF) const override;
109
110 bool
112 const TargetRegisterInfo *TRI,
113 std::vector<CalleeSavedInfo> &CSI) const override;
114
116 RegScavenger *RS) const override;
117
118 /// Returns true if the target will correctly handle shrink wrapping.
119 bool enableShrinkWrapping(const MachineFunction &MF) const override {
120 return true;
121 }
122
123 bool enableStackSlotScavenging(const MachineFunction &MF) const override;
125
127 RegScavenger *RS) const override;
128
129 void
131 RegScavenger *RS) const override;
132
133 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;
134
135 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;
136
139 Register &FrameReg,
140 bool IgnoreSPUpdates) const override;
142 int FI) const override;
143 int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const;
144
145 bool isSupportedStackID(TargetStackID::Value ID) const override {
146 switch (ID) {
147 default:
148 return false;
153 return true;
154 }
155 }
156
157 bool isStackIdSafeForLocalArea(unsigned StackId) const override {
158 // We don't support putting SVE objects into the pre-allocated local
159 // frame block at the moment.
160 return (StackId != TargetStackID::ScalableVector &&
162 }
163
164 void
166 SmallVectorImpl<int> &ObjectsToAllocate) const override;
167
168 bool isFPReserved(const MachineFunction &MF) const;
169
170 bool requiresSaveVG(const MachineFunction &MF) const;
171
172 /// Returns the size of the entire ZPR stackframe (calleesaves + spills).
174
175 /// Returns the size of the entire PPR stackframe (calleesaves + spills +
176 /// hazard padding).
178
179 /// Returns the size of the entire SVE stackframe (PPRs + ZPRs).
181 return getZPRStackSize(MF) + getPPRStackSize(MF);
182 }
183
187
188 // Windows unwind can't represent the required stack adjustments if we have
189 // both SVE callee-saves and dynamic stack allocations, and the frame
190 // pointer is before the SVE spills. The allocation of the frame pointer
191 // must be the last instruction in the prologue so the unwinder can restore
192 // the stack pointer correctly. (And there isn't any unwind opcode for
193 // `addvl sp, x29, -17`.)
194 //
195 // Because of this, we do spills in the opposite order on Windows: first SVE,
196 // then GPRs. The main side-effect of this is that it makes accessing
197 // parameters passed on the stack more expensive.
198 //
199 // We could consider rearranging the spills for simpler cases.
201
202protected:
203 bool hasFPImpl(const MachineFunction &MF) const override;
204
205private:
206 /// Returns true if a homogeneous prolog or epilog code can be emitted
207 /// for the size optimization. If so, HOM_Prolog/HOM_Epilog pseudo
208 /// instructions are emitted in place. When Exit block is given, this check is
209 /// for epilog.
210 bool homogeneousPrologEpilog(MachineFunction &MF,
211 MachineBasicBlock *Exit = nullptr) const;
212
213 /// Returns true if CSRs should be paired.
214 bool producePairRegisters(MachineFunction &MF) const;
215
216 /// Make a determination whether a Hazard slot is used and create it if
217 /// needed.
218 void determineStackHazardSlot(MachineFunction &MF,
219 BitVector &SavedRegs) const;
220
221 /// Emit target zero call-used regs.
222 void emitZeroCallUsedRegs(BitVector RegsToZero, MachineBasicBlock &MBB,
223 RegScavenger *RS) const override;
224
225 /// Replace a StackProbe stub (if any) with the actual probe code inline
226 void inlineStackProbe(MachineFunction &MF,
227 MachineBasicBlock &PrologueMBB) const override;
228
229 void inlineStackProbeFixed(MachineBasicBlock::iterator MBBI,
230 Register ScratchReg, int64_t FrameSize,
231 StackOffset CFAOffset) const;
232
234 inlineStackProbeLoopExactMultiple(MachineBasicBlock::iterator MBBI,
235 int64_t NegProbeSize,
236 Register TargetReg) const;
237
238 void emitRemarks(const MachineFunction &MF,
239 MachineOptimizationRemarkEmitter *ORE) const override;
240
241 bool windowsRequiresStackProbe(const MachineFunction &MF,
242 uint64_t StackSizeInBytes) const;
243
244 bool shouldSignReturnAddressEverywhere(const MachineFunction &MF) const;
245
246 StackOffset getFPOffset(const MachineFunction &MF,
247 int64_t ObjectOffset) const;
248
249 StackOffset getStackOffset(const MachineFunction &MF,
250 int64_t ObjectOffset) const;
251
252 // Given a load or a store instruction, generate an appropriate unwinding SEH
253 // code on Windows.
255 const AArch64InstrInfo &TII,
256 MachineInstr::MIFlag Flag) const;
257
258 // Find a scratch register that we can use at the start of the prologue to
259 // re-align the stack pointer. We avoid using callee-save registers since
260 // they may appear to be free when this is called from canUseAsPrologue
261 // (during shrink wrapping), but then no longer be free when this is called
262 // from emitPrologue.
263 //
264 // FIXME: This is a bit conservative, since in the above case we could use one
265 // of the callee-save registers as a scratch temp to re-align the stack
266 // pointer, but we would then have to make sure that we were in fact saving at
267 // least one callee-save register in the prologue, which is additional
268 // complexity that doesn't seem worth the benefit.
270 bool HasCall = false) const;
271
272 /// Returns the size of the fixed object area (allocated next to sp on entry)
273 /// On Win64 this may include a var args area and an UnwindHelp object for EH.
274 unsigned getFixedObjectSize(const MachineFunction &MF,
275 const AArch64FunctionInfo *AFI, bool IsWin64,
276 bool IsFunclet) const;
277};
278
279} // End llvm namespace
280
281#endif
uint64_t uint64_t
static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI, const TargetInstrInfo &TII, unsigned Flags)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
Register const TargetRegisterInfo * TRI
static MCRegister findScratchNonCalleeSaveRegister(MachineRegisterInfo &MRI, LiveRegUnits &LiveUnits, const TargetRegisterClass &RC, bool Unused=false)
A helper class for emitting the epilogue.
StackOffset getSVEStackSize(const MachineFunction &MF) const
Returns the size of the entire SVE stackframe (PPRs + ZPRs).
StackOffset getZPRStackSize(const MachineFunction &MF) const
Returns the size of the entire ZPR stackframe (calleesaves + spills).
void processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameIndicesReplaced - This method is called immediately before MO_FrameIndex op...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
bool enableStackSlotScavenging(const MachineFunction &MF) const override
Returns true if the stack slot holes in the fixed and callee-save stack area should be used when allo...
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
bool enableFullCFIFixup(const MachineFunction &MF) const override
enableFullCFIFixup - Returns true if we may need to fix the unwind information such that it is accura...
StackOffset getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI) const override
getFrameIndexReferenceFromSP - This method returns the offset from the stack pointer to the slot of t...
bool enableCFIFixup(const MachineFunction &MF) const override
Returns true if we may need to fix the unwind information for the function.
StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const override
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
TargetStackID::Value getStackIDForScalableVectors() const override
Returns the StackID that scalable vectors should be associated with.
bool hasFPImpl(const MachineFunction &MF) const override
hasFPImpl - Return true if the specified function should have a dedicated frame pointer register.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void resetCFIToInitialState(MachineBasicBlock &MBB) const override
Emit CFI instructions that recreate the state of the unwind information upon function entry.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool hasSVECalleeSavesAboveFrameRecord(const MachineFunction &MF) const
StackOffset resolveFrameOffsetReference(const MachineFunction &MF, int64_t ObjectOffset, bool isFixed, TargetStackID::Value StackID, Register &FrameReg, bool PreferFP, bool ForSimm) const
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
bool canUseRedZone(const MachineFunction &MF) const
Can this function use the red zone for local allocations.
bool isSupportedStackID(TargetStackID::Value ID) const override
bool isFPReserved(const MachineFunction &MF) const
Should the Frame Pointer be reserved for the current function?
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const
unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const
Funclets only need to account for space for the callee saved registers, as the locals are accounted f...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
StackOffset getPPRStackSize(const MachineFunction &MF) const
Returns the size of the entire PPR stackframe (calleesaves + spills + hazard padding).
int64_t getArgumentStackToRestore(MachineFunction &MF, MachineBasicBlock &MBB) const
Returns how much of the incoming argument stack area (in bytes) we should clean up in an epilogue.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
bool authenticatesReturnAddressEarly(MachineFunction &MF, MachineBasicBlock &MBB) const
Whether the return address is authenticated before the epilogue starts, in the return block MBB,...
StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const override
For Win64 AArch64 EH, the offset to the Unwind object is from the SP before the update.
bool isStackIdSafeForLocalArea(unsigned StackId) const override
This method returns whether or not it is safe for an object with the given stack id to be bundled int...
StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP, bool ForSimm) const
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override
The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve the parent's frame pointer...
bool requiresSaveVG(const MachineFunction &MF) const
void emitPacRetPlusLeafHardening(MachineFunction &MF) const
Harden the entire function with pac-ret.
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
A helper class for emitting the prologue.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
MachineInstrBundleIterator< MachineInstr > iterator
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:31
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This is an optimization pass for GlobalISel generic memory operations.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39