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
16#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
17#include "llvm/CodeGen/TargetFrameLowering.h"
18#include "llvm/Support/TypeSize.h"
19
20namespace llvm {
21
22class AArch64FrameLowering : public TargetFrameLowering {
23public:
24 explicit AArch64FrameLowering()
25 : TargetFrameLowering(StackGrowsDown, Align(16), 0, Align(16),
26 true /*StackRealignable*/) {}
27
28 void resetCFIToInitialState(MachineBasicBlock &MBB) const override;
29
30 MachineBasicBlock::iterator
31 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
32 MachineBasicBlock::iterator I) const override;
33
34 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
35 /// the function.
36 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
37 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
38
39 bool enableCFIFixup(MachineFunction &MF) const override;
40
41 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
42
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,
49 bool ForSimm) const;
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;
58
59 bool
60 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
61 MachineBasicBlock::iterator MI,
62 MutableArrayRef<CalleeSavedInfo> CSI,
63 const TargetRegisterInfo *TRI) const override;
64
65 /// Can this function use the red zone for local allocations.
66 bool canUseRedZone(const MachineFunction &MF) const;
67
68 bool hasFP(const MachineFunction &MF) const override;
69 bool hasReservedCallFrame(const MachineFunction &MF) const override;
70
71 bool assignCalleeSavedSpillSlots(MachineFunction &MF,
72 const TargetRegisterInfo *TRI,
73 std::vector<CalleeSavedInfo> &CSI,
74 unsigned &MinCSFrameIndex,
75 unsigned &MaxCSFrameIndex) const override;
76
77 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
78 RegScavenger *RS) const override;
79
80 /// Returns true if the target will correctly handle shrink wrapping.
81 bool enableShrinkWrapping(const MachineFunction &MF) const override {
82 return true;
83 }
84
85 bool enableStackSlotScavenging(const MachineFunction &MF) const override;
86 TargetStackID::Value getStackIDForScalableVectors() const override;
87
88 void processFunctionBeforeFrameFinalized(MachineFunction &MF,
89 RegScavenger *RS) const override;
90
91 void
92 processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF,
93 RegScavenger *RS) const override;
94
95 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;
96
97 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;
98
99 StackOffset
100 getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
101 Register &FrameReg,
102 bool IgnoreSPUpdates) const override;
103 StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF,
104 int FI) const override;
105 int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const;
106
107 bool isSupportedStackID(TargetStackID::Value ID) const override {
108 switch (ID) {
109 default:
110 return false;
111 case TargetStackID::Default:
112 case TargetStackID::ScalableVector:
113 case TargetStackID::NoAlloc:
114 return true;
115 }
116 }
117
118 bool isStackIdSafeForLocalArea(unsigned StackId) const override {
119 // We don't support putting SVE objects into the pre-allocated local
120 // frame block at the moment.
121 return StackId != TargetStackID::ScalableVector;
122 }
123
124 void
125 orderFrameObjects(const MachineFunction &MF,
126 SmallVectorImpl<int> &ObjectsToAllocate) const override;
127
128private:
129 /// Returns true if a homogeneous prolog or epilog code can be emitted
130 /// for the size optimization. If so, HOM_Prolog/HOM_Epilog pseudo
131 /// instructions are emitted in place. When Exit block is given, this check is
132 /// for epilog.
133 bool homogeneousPrologEpilog(MachineFunction &MF,
134 MachineBasicBlock *Exit = nullptr) const;
135
136 /// Returns true if CSRs should be paired.
137 bool producePairRegisters(MachineFunction &MF) const;
138
139 bool shouldCombineCSRLocalStackBump(MachineFunction &MF,
140 uint64_t StackBumpBytes) const;
141
142 int64_t estimateSVEStackObjectOffsets(MachineFrameInfo &MF) const;
143 int64_t assignSVEStackObjectOffsets(MachineFrameInfo &MF,
144 int &MinCSFrameIndex,
145 int &MaxCSFrameIndex) const;
146 bool shouldCombineCSRLocalStackBumpInEpilogue(MachineBasicBlock &MBB,
147 unsigned StackBumpBytes) const;
148 void emitCalleeSavedGPRLocations(MachineBasicBlock &MBB,
149 MachineBasicBlock::iterator MBBI) const;
150 void emitCalleeSavedSVELocations(MachineBasicBlock &MBB,
151 MachineBasicBlock::iterator MBBI) const;
152 void emitCalleeSavedGPRRestores(MachineBasicBlock &MBB,
153 MachineBasicBlock::iterator MBBI) const;
154 void emitCalleeSavedSVERestores(MachineBasicBlock &MBB,
155 MachineBasicBlock::iterator MBBI) const;
156 void allocateStackSpace(MachineBasicBlock &MBB,
157 MachineBasicBlock::iterator MBBI,
158 int64_t RealignmentPadding, StackOffset AllocSize,
159 bool NeedsWinCFI, bool *HasWinCFI, bool EmitCFI,
160 StackOffset InitialOffset, bool FollowupAllocs) const;
161 /// Make a determination whether a Hazard slot is used and create it if
162 /// needed.
163 void determineStackHazardSlot(MachineFunction &MF,
164 BitVector &SavedRegs) const;
165
166 /// Emit target zero call-used regs.
167 void emitZeroCallUsedRegs(BitVector RegsToZero,
168 MachineBasicBlock &MBB) const override;
169
170 /// Replace a StackProbe stub (if any) with the actual probe code inline
171 void inlineStackProbe(MachineFunction &MF,
172 MachineBasicBlock &PrologueMBB) const override;
173
174 void inlineStackProbeFixed(MachineBasicBlock::iterator MBBI,
175 Register ScratchReg, int64_t FrameSize,
176 StackOffset CFAOffset) const;
177
178 MachineBasicBlock::iterator
179 inlineStackProbeLoopExactMultiple(MachineBasicBlock::iterator MBBI,
180 int64_t NegProbeSize,
181 Register TargetReg) const;
182
183 void emitRemarks(const MachineFunction &MF,
184 MachineOptimizationRemarkEmitter *ORE) const override;
185};
186
187} // End llvm namespace
188
189#endif
190