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

source code of llvm/lib/Target/AArch64/AArch64FrameLowering.h