1 //==-- AArch64FrameLowering.h - TargetFrameLowering for AArch64 --*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
14 #define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
16 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
17 #include "llvm/CodeGen/TargetFrameLowering.h"
18 #include "llvm/Support/TypeSize.h"
22 class AArch64FrameLowering
: public TargetFrameLowering
{
24 explicit AArch64FrameLowering()
25 : TargetFrameLowering(StackGrowsDown
, Align(16), 0, Align(16),
26 true /*StackRealignable*/) {}
28 void resetCFIToInitialState(MachineBasicBlock
&MBB
) const override
;
30 MachineBasicBlock::iterator
31 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
32 MachineBasicBlock::iterator I
) const override
;
34 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
36 void emitPrologue(MachineFunction
&MF
, MachineBasicBlock
&MBB
) const override
;
37 void emitEpilogue(MachineFunction
&MF
, MachineBasicBlock
&MBB
) const override
;
39 bool enableCFIFixup(MachineFunction
&MF
) const override
;
41 bool canUseAsPrologue(const MachineBasicBlock
&MBB
) const override
;
43 StackOffset
getFrameIndexReference(const MachineFunction
&MF
, int FI
,
44 Register
&FrameReg
) const override
;
45 StackOffset
getFrameIndexReferenceFromSP(const MachineFunction
&MF
,
46 int FI
) const override
;
47 StackOffset
resolveFrameIndexReference(const MachineFunction
&MF
, int FI
,
48 Register
&FrameReg
, bool PreferFP
,
50 StackOffset
resolveFrameOffsetReference(const MachineFunction
&MF
,
51 int64_t ObjectOffset
, bool isFixed
,
52 bool isSVE
, Register
&FrameReg
,
53 bool PreferFP
, bool ForSimm
) const;
54 bool spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
55 MachineBasicBlock::iterator MI
,
56 ArrayRef
<CalleeSavedInfo
> CSI
,
57 const TargetRegisterInfo
*TRI
) const override
;
60 restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
61 MachineBasicBlock::iterator MI
,
62 MutableArrayRef
<CalleeSavedInfo
> CSI
,
63 const TargetRegisterInfo
*TRI
) const override
;
65 /// Can this function use the red zone for local allocations.
66 bool canUseRedZone(const MachineFunction
&MF
) const;
68 bool hasReservedCallFrame(const MachineFunction
&MF
) const override
;
70 bool assignCalleeSavedSpillSlots(MachineFunction
&MF
,
71 const TargetRegisterInfo
*TRI
,
72 std::vector
<CalleeSavedInfo
> &CSI
,
73 unsigned &MinCSFrameIndex
,
74 unsigned &MaxCSFrameIndex
) const override
;
76 void determineCalleeSaves(MachineFunction
&MF
, BitVector
&SavedRegs
,
77 RegScavenger
*RS
) const override
;
79 /// Returns true if the target will correctly handle shrink wrapping.
80 bool enableShrinkWrapping(const MachineFunction
&MF
) const override
{
84 bool enableStackSlotScavenging(const MachineFunction
&MF
) const override
;
85 TargetStackID::Value
getStackIDForScalableVectors() const override
;
87 void processFunctionBeforeFrameFinalized(MachineFunction
&MF
,
88 RegScavenger
*RS
) const override
;
91 processFunctionBeforeFrameIndicesReplaced(MachineFunction
&MF
,
92 RegScavenger
*RS
) const override
;
94 unsigned getWinEHParentFrameOffset(const MachineFunction
&MF
) const override
;
96 unsigned getWinEHFuncletFrameSize(const MachineFunction
&MF
) const;
99 getFrameIndexReferencePreferSP(const MachineFunction
&MF
, int FI
,
101 bool IgnoreSPUpdates
) const override
;
102 StackOffset
getNonLocalFrameIndexReference(const MachineFunction
&MF
,
103 int FI
) const override
;
104 int getSEHFrameIndexOffset(const MachineFunction
&MF
, int FI
) const;
106 bool isSupportedStackID(TargetStackID::Value ID
) const override
{
110 case TargetStackID::Default
:
111 case TargetStackID::ScalableVector
:
112 case TargetStackID::NoAlloc
:
117 bool isStackIdSafeForLocalArea(unsigned StackId
) const override
{
118 // We don't support putting SVE objects into the pre-allocated local
119 // frame block at the moment.
120 return StackId
!= TargetStackID::ScalableVector
;
124 orderFrameObjects(const MachineFunction
&MF
,
125 SmallVectorImpl
<int> &ObjectsToAllocate
) const override
;
128 bool hasFPImpl(const MachineFunction
&MF
) const override
;
131 /// Returns true if a homogeneous prolog or epilog code can be emitted
132 /// for the size optimization. If so, HOM_Prolog/HOM_Epilog pseudo
133 /// instructions are emitted in place. When Exit block is given, this check is
135 bool homogeneousPrologEpilog(MachineFunction
&MF
,
136 MachineBasicBlock
*Exit
= nullptr) const;
138 /// Returns true if CSRs should be paired.
139 bool producePairRegisters(MachineFunction
&MF
) const;
141 bool shouldCombineCSRLocalStackBump(MachineFunction
&MF
,
142 uint64_t StackBumpBytes
) const;
144 int64_t estimateSVEStackObjectOffsets(MachineFrameInfo
&MF
) const;
145 int64_t assignSVEStackObjectOffsets(MachineFrameInfo
&MF
,
146 int &MinCSFrameIndex
,
147 int &MaxCSFrameIndex
) const;
148 bool shouldCombineCSRLocalStackBumpInEpilogue(MachineBasicBlock
&MBB
,
149 uint64_t StackBumpBytes
) const;
150 void emitCalleeSavedGPRLocations(MachineBasicBlock
&MBB
,
151 MachineBasicBlock::iterator MBBI
) const;
152 void emitCalleeSavedSVELocations(MachineBasicBlock
&MBB
,
153 MachineBasicBlock::iterator MBBI
) const;
154 void emitCalleeSavedGPRRestores(MachineBasicBlock
&MBB
,
155 MachineBasicBlock::iterator MBBI
) const;
156 void emitCalleeSavedSVERestores(MachineBasicBlock
&MBB
,
157 MachineBasicBlock::iterator MBBI
) const;
158 void allocateStackSpace(MachineBasicBlock
&MBB
,
159 MachineBasicBlock::iterator MBBI
,
160 int64_t RealignmentPadding
, StackOffset AllocSize
,
161 bool NeedsWinCFI
, bool *HasWinCFI
, bool EmitCFI
,
162 StackOffset InitialOffset
, bool FollowupAllocs
) const;
163 /// Make a determination whether a Hazard slot is used and create it if
165 void determineStackHazardSlot(MachineFunction
&MF
,
166 BitVector
&SavedRegs
) const;
168 /// Emit target zero call-used regs.
169 void emitZeroCallUsedRegs(BitVector RegsToZero
,
170 MachineBasicBlock
&MBB
) const override
;
172 /// Replace a StackProbe stub (if any) with the actual probe code inline
173 void inlineStackProbe(MachineFunction
&MF
,
174 MachineBasicBlock
&PrologueMBB
) const override
;
176 void inlineStackProbeFixed(MachineBasicBlock::iterator MBBI
,
177 Register ScratchReg
, int64_t FrameSize
,
178 StackOffset CFAOffset
) const;
180 MachineBasicBlock::iterator
181 inlineStackProbeLoopExactMultiple(MachineBasicBlock::iterator MBBI
,
182 int64_t NegProbeSize
,
183 Register TargetReg
) const;
185 void emitRemarks(const MachineFunction
&MF
,
186 MachineOptimizationRemarkEmitter
*ORE
) const override
;
189 } // End llvm namespace