LLVM 22.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;
25
27public:
30 true /*StackRealignable*/) {}
31
32 void resetCFIToInitialState(MachineBasicBlock &MBB) const override;
33
36 MachineBasicBlock::iterator I) const override;
37
38 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
39 /// the function.
40 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
41 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
42
43 /// Harden the entire function with pac-ret.
44 ///
45 /// If pac-ret+leaf is requested, we want to harden as much code as possible.
46 /// This function inserts pac-ret hardening at the points where prologue and
47 /// epilogue are traditionally inserted, ignoring possible shrink-wrapping
48 /// optimization.
50
51 bool enableCFIFixup(const MachineFunction &MF) const override;
52
53 bool enableFullCFIFixup(const MachineFunction &MF) const override;
54
55 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
56
58 Register &FrameReg) const override;
60 int FI) const override;
62 Register &FrameReg, bool PreferFP,
63 bool ForSimm) const;
65 int64_t ObjectOffset, bool isFixed,
66 bool isSVE, Register &FrameReg,
67 bool PreferFP, bool ForSimm) const;
71 const TargetRegisterInfo *TRI) const override;
72
73 bool
77 const TargetRegisterInfo *TRI) const override;
78
79 /// Can this function use the red zone for local allocations.
80 bool canUseRedZone(const MachineFunction &MF) const;
81
82 bool hasReservedCallFrame(const MachineFunction &MF) const override;
83
86 std::vector<CalleeSavedInfo> &CSI,
87 unsigned &MinCSFrameIndex,
88 unsigned &MaxCSFrameIndex) const override;
89
91 RegScavenger *RS) const override;
92
93 /// Returns true if the target will correctly handle shrink wrapping.
94 bool enableShrinkWrapping(const MachineFunction &MF) const override {
95 return true;
96 }
97
98 bool enableStackSlotScavenging(const MachineFunction &MF) const override;
100
102 RegScavenger *RS) const override;
103
104 void
106 RegScavenger *RS) const override;
107
108 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;
109
110 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;
111
114 Register &FrameReg,
115 bool IgnoreSPUpdates) const override;
117 int FI) const override;
118 int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const;
119
121 switch (ID) {
122 default:
123 return false;
127 return true;
128 }
129 }
130
131 bool isStackIdSafeForLocalArea(unsigned StackId) const override {
132 // We don't support putting SVE objects into the pre-allocated local
133 // frame block at the moment.
134 return StackId != TargetStackID::ScalableVector;
135 }
136
138 void
140 SmallVectorImpl<int> &ObjectsToAllocate) const override;
141
142 bool isFPReserved(const MachineFunction &MF) const;
143
144 bool needsWinCFI(const MachineFunction &MF) const;
145
146 bool requiresSaveVG(const MachineFunction &MF) const;
147
149
150protected:
151 bool hasFPImpl(const MachineFunction &MF) const override;
152
153private:
154 /// Returns true if a homogeneous prolog or epilog code can be emitted
155 /// for the size optimization. If so, HOM_Prolog/HOM_Epilog pseudo
156 /// instructions are emitted in place. When Exit block is given, this check is
157 /// for epilog.
158 bool homogeneousPrologEpilog(MachineFunction &MF,
159 MachineBasicBlock *Exit = nullptr) const;
160
161 /// Returns true if CSRs should be paired.
162 bool producePairRegisters(MachineFunction &MF) const;
163
164 bool shouldCombineCSRLocalStackBump(MachineFunction &MF,
165 uint64_t StackBumpBytes) const;
166
167 int64_t estimateSVEStackObjectOffsets(MachineFrameInfo &MF) const;
168 int64_t assignSVEStackObjectOffsets(MachineFrameInfo &MF,
169 int &MinCSFrameIndex,
170 int &MaxCSFrameIndex) const;
171 bool shouldCombineCSRLocalStackBumpInEpilogue(MachineBasicBlock &MBB,
172 uint64_t StackBumpBytes) const;
173 void emitCalleeSavedGPRRestores(MachineBasicBlock &MBB,
175 void emitCalleeSavedSVERestores(MachineBasicBlock &MBB,
177 void allocateStackSpace(MachineBasicBlock &MBB,
179 int64_t RealignmentPadding, StackOffset AllocSize,
180 bool NeedsWinCFI, bool *HasWinCFI, bool EmitCFI,
181 StackOffset InitialOffset, bool FollowupAllocs) const;
182 /// Make a determination whether a Hazard slot is used and create it if
183 /// needed.
184 void determineStackHazardSlot(MachineFunction &MF,
185 BitVector &SavedRegs) const;
186
187 /// Emit target zero call-used regs.
188 void emitZeroCallUsedRegs(BitVector RegsToZero,
189 MachineBasicBlock &MBB) const override;
190
191 /// Replace a StackProbe stub (if any) with the actual probe code inline
192 void inlineStackProbe(MachineFunction &MF,
193 MachineBasicBlock &PrologueMBB) const override;
194
195 void inlineStackProbeFixed(MachineBasicBlock::iterator MBBI,
196 Register ScratchReg, int64_t FrameSize,
197 StackOffset CFAOffset) const;
198
200 inlineStackProbeLoopExactMultiple(MachineBasicBlock::iterator MBBI,
201 int64_t NegProbeSize,
202 Register TargetReg) const;
203
204 void emitRemarks(const MachineFunction &MF,
205 MachineOptimizationRemarkEmitter *ORE) const override;
206
207 bool windowsRequiresStackProbe(const MachineFunction &MF,
208 uint64_t StackSizeInBytes) const;
209
210 bool shouldSignReturnAddressEverywhere(const MachineFunction &MF) const;
211
212 StackOffset getFPOffset(const MachineFunction &MF,
213 int64_t ObjectOffset) const;
214
215 StackOffset getStackOffset(const MachineFunction &MF,
216 int64_t ObjectOffset) const;
217
218 // Find a scratch register that we can use at the start of the prologue to
219 // re-align the stack pointer. We avoid using callee-save registers since
220 // they may appear to be free when this is called from canUseAsPrologue
221 // (during shrink wrapping), but then no longer be free when this is called
222 // from emitPrologue.
223 //
224 // FIXME: This is a bit conservative, since in the above case we could use one
225 // of the callee-save registers as a scratch temp to re-align the stack
226 // pointer, but we would then have to make sure that we were in fact saving at
227 // least one callee-save register in the prologue, which is additional
228 // complexity that doesn't seem worth the benefit.
230 bool HasCall = false) const;
231
232 // Convert callee-save register save/restore instruction to do stack pointer
233 // decrement/increment to allocate/deallocate the callee-save stack area by
234 // converting store/load to use pre/post increment version.
235 MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(
237 const DebugLoc &DL, const TargetInstrInfo *TII, int CSStackSizeInc,
238 bool NeedsWinCFI, bool *HasWinCFI, bool EmitCFI,
240 int CFAOffset = 0) const;
241
242 // Fixup callee-save register save/restore instructions to take into account
243 // combined SP bump by adding the local stack size to the stack offsets.
244 void fixupCalleeSaveRestoreStackOffset(MachineInstr &MI,
245 uint64_t LocalStackSize,
246 bool NeedsWinCFI,
247 bool *HasWinCFI) const;
248
249 bool isSVECalleeSave(MachineBasicBlock::iterator I) const;
250
251 /// Returns the size of the fixed object area (allocated next to sp on entry)
252 /// On Win64 this may include a var args area and an UnwindHelp object for EH.
253 unsigned getFixedObjectSize(const MachineFunction &MF,
254 const AArch64FunctionInfo *AFI, bool IsWin64,
255 bool IsFunclet) const;
256
257 bool isVGInstruction(MachineBasicBlock::iterator MBBI,
258 const TargetLowering &TLI) const;
259
260 bool requiresGetVGCall(const MachineFunction &MF) const;
261};
262
263} // End llvm namespace
264
265#endif
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:58
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
Register const TargetRegisterInfo * TRI
static MCRegister findScratchNonCalleeSaveRegister(MachineRegisterInfo &MRI, LiveRegUnits &LiveUnits, const TargetRegisterClass &RC, bool Unused=false)
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 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 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 needsWinCFI(const MachineFunction &MF) const
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
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
StackOffset getSVEStackSize(const MachineFunction &MF) const
Returns the size of the entire SVE stackframe (calleesaves + spills).
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
StackOffset resolveFrameOffsetReference(const MachineFunction &MF, int64_t ObjectOffset, bool isFixed, bool isSVE, Register &FrameReg, bool PreferFP, bool ForSimm) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI, unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
A debug info location.
Definition DebugLoc.h:124
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Representation of each machine instruction.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition ArrayRef.h:303
Wrapper class representing virtual and physical registers.
Definition Register.h:19
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)
TargetInstrInfo - Interface to description of machine instruction set.
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...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
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