1*9880d681SAndroid Build Coastguard Worker //===- AArch64RegisterInfo.cpp - AArch64 Register Information -------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the AArch64 implementation of the TargetRegisterInfo
11*9880d681SAndroid Build Coastguard Worker // class.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "AArch64RegisterInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "AArch64FrameLowering.h"
17*9880d681SAndroid Build Coastguard Worker #include "AArch64InstrInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "AArch64MachineFunctionInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "AArch64Subtarget.h"
20*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AArch64AddressingModes.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterScavenging.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetFrameLowering.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker using namespace llvm;
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker #define GET_REGINFO_TARGET_DESC
35*9880d681SAndroid Build Coastguard Worker #include "AArch64GenRegisterInfo.inc"
36*9880d681SAndroid Build Coastguard Worker
AArch64RegisterInfo(const Triple & TT)37*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::AArch64RegisterInfo(const Triple &TT)
38*9880d681SAndroid Build Coastguard Worker : AArch64GenRegisterInfo(AArch64::LR), TT(TT) {}
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const41*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
42*9880d681SAndroid Build Coastguard Worker assert(MF && "Invalid MachineFunction pointer.");
43*9880d681SAndroid Build Coastguard Worker if (MF->getFunction()->getCallingConv() == CallingConv::GHC)
44*9880d681SAndroid Build Coastguard Worker // GHC set of callee saved regs is empty as all those regs are
45*9880d681SAndroid Build Coastguard Worker // used for passing STG regs around
46*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_NoRegs_SaveList;
47*9880d681SAndroid Build Coastguard Worker if (MF->getFunction()->getCallingConv() == CallingConv::AnyReg)
48*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_AllRegs_SaveList;
49*9880d681SAndroid Build Coastguard Worker if (MF->getFunction()->getCallingConv() == CallingConv::CXX_FAST_TLS)
50*9880d681SAndroid Build Coastguard Worker return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR() ?
51*9880d681SAndroid Build Coastguard Worker CSR_AArch64_CXX_TLS_Darwin_PE_SaveList :
52*9880d681SAndroid Build Coastguard Worker CSR_AArch64_CXX_TLS_Darwin_SaveList;
53*9880d681SAndroid Build Coastguard Worker if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
54*9880d681SAndroid Build Coastguard Worker ->supportSwiftError() &&
55*9880d681SAndroid Build Coastguard Worker MF->getFunction()->getAttributes().hasAttrSomewhere(
56*9880d681SAndroid Build Coastguard Worker Attribute::SwiftError))
57*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_AAPCS_SwiftError_SaveList;
58*9880d681SAndroid Build Coastguard Worker if (MF->getFunction()->getCallingConv() == CallingConv::PreserveMost)
59*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_RT_MostRegs_SaveList;
60*9880d681SAndroid Build Coastguard Worker else
61*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_AAPCS_SaveList;
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker
getCalleeSavedRegsViaCopy(const MachineFunction * MF) const64*9880d681SAndroid Build Coastguard Worker const MCPhysReg *AArch64RegisterInfo::getCalleeSavedRegsViaCopy(
65*9880d681SAndroid Build Coastguard Worker const MachineFunction *MF) const {
66*9880d681SAndroid Build Coastguard Worker assert(MF && "Invalid MachineFunction pointer.");
67*9880d681SAndroid Build Coastguard Worker if (MF->getFunction()->getCallingConv() == CallingConv::CXX_FAST_TLS &&
68*9880d681SAndroid Build Coastguard Worker MF->getInfo<AArch64FunctionInfo>()->isSplitCSR())
69*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_CXX_TLS_Darwin_ViaCopy_SaveList;
70*9880d681SAndroid Build Coastguard Worker return nullptr;
71*9880d681SAndroid Build Coastguard Worker }
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker const uint32_t *
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID CC) const74*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
75*9880d681SAndroid Build Coastguard Worker CallingConv::ID CC) const {
76*9880d681SAndroid Build Coastguard Worker if (CC == CallingConv::GHC)
77*9880d681SAndroid Build Coastguard Worker // This is academic becase all GHC calls are (supposed to be) tail calls
78*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_NoRegs_RegMask;
79*9880d681SAndroid Build Coastguard Worker if (CC == CallingConv::AnyReg)
80*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_AllRegs_RegMask;
81*9880d681SAndroid Build Coastguard Worker if (CC == CallingConv::CXX_FAST_TLS)
82*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_CXX_TLS_Darwin_RegMask;
83*9880d681SAndroid Build Coastguard Worker if (MF.getSubtarget<AArch64Subtarget>().getTargetLowering()
84*9880d681SAndroid Build Coastguard Worker ->supportSwiftError() &&
85*9880d681SAndroid Build Coastguard Worker MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
86*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_AAPCS_SwiftError_RegMask;
87*9880d681SAndroid Build Coastguard Worker if (CC == CallingConv::PreserveMost)
88*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_RT_MostRegs_RegMask;
89*9880d681SAndroid Build Coastguard Worker else
90*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_AAPCS_RegMask;
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker
getTLSCallPreservedMask() const93*9880d681SAndroid Build Coastguard Worker const uint32_t *AArch64RegisterInfo::getTLSCallPreservedMask() const {
94*9880d681SAndroid Build Coastguard Worker if (TT.isOSDarwin())
95*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_TLS_Darwin_RegMask;
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker assert(TT.isOSBinFormatELF() && "only expect Darwin or ELF TLS");
98*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_TLS_ELF_RegMask;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker const uint32_t *
getThisReturnPreservedMask(const MachineFunction & MF,CallingConv::ID CC) const102*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::getThisReturnPreservedMask(const MachineFunction &MF,
103*9880d681SAndroid Build Coastguard Worker CallingConv::ID CC) const {
104*9880d681SAndroid Build Coastguard Worker // This should return a register mask that is the same as that returned by
105*9880d681SAndroid Build Coastguard Worker // getCallPreservedMask but that additionally preserves the register used for
106*9880d681SAndroid Build Coastguard Worker // the first i64 argument (which must also be the register used to return a
107*9880d681SAndroid Build Coastguard Worker // single i64 return value)
108*9880d681SAndroid Build Coastguard Worker //
109*9880d681SAndroid Build Coastguard Worker // In case that the calling convention does not use the same register for
110*9880d681SAndroid Build Coastguard Worker // both, the function should return NULL (does not currently apply)
111*9880d681SAndroid Build Coastguard Worker assert(CC != CallingConv::GHC && "should not be GHC calling convention.");
112*9880d681SAndroid Build Coastguard Worker return CSR_AArch64_AAPCS_ThisReturn_RegMask;
113*9880d681SAndroid Build Coastguard Worker }
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker BitVector
getReservedRegs(const MachineFunction & MF) const116*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
117*9880d681SAndroid Build Coastguard Worker const AArch64FrameLowering *TFI = getFrameLowering(MF);
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker // FIXME: avoid re-calculating this every time.
120*9880d681SAndroid Build Coastguard Worker BitVector Reserved(getNumRegs());
121*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::SP);
122*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::XZR);
123*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::WSP);
124*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::WZR);
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker if (TFI->hasFP(MF) || TT.isOSDarwin()) {
127*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::FP);
128*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::W29);
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker if (MF.getSubtarget<AArch64Subtarget>().isX18Reserved()) {
132*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::X18); // Platform register
133*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::W18);
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker if (hasBasePointer(MF)) {
137*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::X19);
138*9880d681SAndroid Build Coastguard Worker Reserved.set(AArch64::W19);
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker return Reserved;
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker
isReservedReg(const MachineFunction & MF,unsigned Reg) const144*9880d681SAndroid Build Coastguard Worker bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
145*9880d681SAndroid Build Coastguard Worker unsigned Reg) const {
146*9880d681SAndroid Build Coastguard Worker const AArch64FrameLowering *TFI = getFrameLowering(MF);
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker switch (Reg) {
149*9880d681SAndroid Build Coastguard Worker default:
150*9880d681SAndroid Build Coastguard Worker break;
151*9880d681SAndroid Build Coastguard Worker case AArch64::SP:
152*9880d681SAndroid Build Coastguard Worker case AArch64::XZR:
153*9880d681SAndroid Build Coastguard Worker case AArch64::WSP:
154*9880d681SAndroid Build Coastguard Worker case AArch64::WZR:
155*9880d681SAndroid Build Coastguard Worker return true;
156*9880d681SAndroid Build Coastguard Worker case AArch64::X18:
157*9880d681SAndroid Build Coastguard Worker case AArch64::W18:
158*9880d681SAndroid Build Coastguard Worker return MF.getSubtarget<AArch64Subtarget>().isX18Reserved();
159*9880d681SAndroid Build Coastguard Worker case AArch64::FP:
160*9880d681SAndroid Build Coastguard Worker case AArch64::W29:
161*9880d681SAndroid Build Coastguard Worker return TFI->hasFP(MF) || TT.isOSDarwin();
162*9880d681SAndroid Build Coastguard Worker case AArch64::W19:
163*9880d681SAndroid Build Coastguard Worker case AArch64::X19:
164*9880d681SAndroid Build Coastguard Worker return hasBasePointer(MF);
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker return false;
168*9880d681SAndroid Build Coastguard Worker }
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *
getPointerRegClass(const MachineFunction & MF,unsigned Kind) const171*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::getPointerRegClass(const MachineFunction &MF,
172*9880d681SAndroid Build Coastguard Worker unsigned Kind) const {
173*9880d681SAndroid Build Coastguard Worker return &AArch64::GPR64RegClass;
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *
getCrossCopyRegClass(const TargetRegisterClass * RC) const177*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
178*9880d681SAndroid Build Coastguard Worker if (RC == &AArch64::CCRRegClass)
179*9880d681SAndroid Build Coastguard Worker return &AArch64::GPR64RegClass; // Only MSR & MRS copy NZCV.
180*9880d681SAndroid Build Coastguard Worker return RC;
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker
getBaseRegister() const183*9880d681SAndroid Build Coastguard Worker unsigned AArch64RegisterInfo::getBaseRegister() const { return AArch64::X19; }
184*9880d681SAndroid Build Coastguard Worker
hasBasePointer(const MachineFunction & MF) const185*9880d681SAndroid Build Coastguard Worker bool AArch64RegisterInfo::hasBasePointer(const MachineFunction &MF) const {
186*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Worker // In the presence of variable sized objects, if the fixed stack size is
189*9880d681SAndroid Build Coastguard Worker // large enough that referencing from the FP won't result in things being
190*9880d681SAndroid Build Coastguard Worker // in range relatively often, we can use a base pointer to allow access
191*9880d681SAndroid Build Coastguard Worker // from the other direction like the SP normally works.
192*9880d681SAndroid Build Coastguard Worker // Furthermore, if both variable sized objects are present, and the
193*9880d681SAndroid Build Coastguard Worker // stack needs to be dynamically re-aligned, the base pointer is the only
194*9880d681SAndroid Build Coastguard Worker // reliable way to reference the locals.
195*9880d681SAndroid Build Coastguard Worker if (MFI->hasVarSizedObjects()) {
196*9880d681SAndroid Build Coastguard Worker if (needsStackRealignment(MF))
197*9880d681SAndroid Build Coastguard Worker return true;
198*9880d681SAndroid Build Coastguard Worker // Conservatively estimate whether the negative offset from the frame
199*9880d681SAndroid Build Coastguard Worker // pointer will be sufficient to reach. If a function has a smallish
200*9880d681SAndroid Build Coastguard Worker // frame, it's less likely to have lots of spills and callee saved
201*9880d681SAndroid Build Coastguard Worker // space, so it's all more likely to be within range of the frame pointer.
202*9880d681SAndroid Build Coastguard Worker // If it's wrong, we'll materialize the constant and still get to the
203*9880d681SAndroid Build Coastguard Worker // object; it's just suboptimal. Negative offsets use the unscaled
204*9880d681SAndroid Build Coastguard Worker // load/store instructions, which have a 9-bit signed immediate.
205*9880d681SAndroid Build Coastguard Worker return MFI->getLocalFrameSize() >= 256;
206*9880d681SAndroid Build Coastguard Worker }
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker return false;
209*9880d681SAndroid Build Coastguard Worker }
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker unsigned
getFrameRegister(const MachineFunction & MF) const212*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
213*9880d681SAndroid Build Coastguard Worker const AArch64FrameLowering *TFI = getFrameLowering(MF);
214*9880d681SAndroid Build Coastguard Worker return TFI->hasFP(MF) ? AArch64::FP : AArch64::SP;
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker
requiresRegisterScavenging(const MachineFunction & MF) const217*9880d681SAndroid Build Coastguard Worker bool AArch64RegisterInfo::requiresRegisterScavenging(
218*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF) const {
219*9880d681SAndroid Build Coastguard Worker return true;
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker
requiresVirtualBaseRegisters(const MachineFunction & MF) const222*9880d681SAndroid Build Coastguard Worker bool AArch64RegisterInfo::requiresVirtualBaseRegisters(
223*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF) const {
224*9880d681SAndroid Build Coastguard Worker return true;
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker bool
useFPForScavengingIndex(const MachineFunction & MF) const228*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
229*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
230*9880d681SAndroid Build Coastguard Worker // AArch64FrameLowering::resolveFrameIndexReference() can always fall back
231*9880d681SAndroid Build Coastguard Worker // to the stack pointer, so only put the emergency spill slot next to the
232*9880d681SAndroid Build Coastguard Worker // FP when there's no better way to access it (SP or base pointer).
233*9880d681SAndroid Build Coastguard Worker return MFI->hasVarSizedObjects() && !hasBasePointer(MF);
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
requiresFrameIndexScavenging(const MachineFunction & MF) const236*9880d681SAndroid Build Coastguard Worker bool AArch64RegisterInfo::requiresFrameIndexScavenging(
237*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF) const {
238*9880d681SAndroid Build Coastguard Worker return true;
239*9880d681SAndroid Build Coastguard Worker }
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Worker bool
cannotEliminateFrame(const MachineFunction & MF) const242*9880d681SAndroid Build Coastguard Worker AArch64RegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const {
243*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
244*9880d681SAndroid Build Coastguard Worker if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI->adjustsStack())
245*9880d681SAndroid Build Coastguard Worker return true;
246*9880d681SAndroid Build Coastguard Worker return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken();
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker /// needsFrameBaseReg - Returns true if the instruction's frame index
250*9880d681SAndroid Build Coastguard Worker /// reference would be better served by a base register other than FP
251*9880d681SAndroid Build Coastguard Worker /// or SP. Used by LocalStackFrameAllocation to determine which frame index
252*9880d681SAndroid Build Coastguard Worker /// references it should create new base registers for.
needsFrameBaseReg(MachineInstr * MI,int64_t Offset) const253*9880d681SAndroid Build Coastguard Worker bool AArch64RegisterInfo::needsFrameBaseReg(MachineInstr *MI,
254*9880d681SAndroid Build Coastguard Worker int64_t Offset) const {
255*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i)
256*9880d681SAndroid Build Coastguard Worker assert(i < MI->getNumOperands() &&
257*9880d681SAndroid Build Coastguard Worker "Instr doesn't have FrameIndex operand!");
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker // It's the load/store FI references that cause issues, as it can be difficult
260*9880d681SAndroid Build Coastguard Worker // to materialize the offset if it won't fit in the literal field. Estimate
261*9880d681SAndroid Build Coastguard Worker // based on the size of the local frame and some conservative assumptions
262*9880d681SAndroid Build Coastguard Worker // about the rest of the stack frame (note, this is pre-regalloc, so
263*9880d681SAndroid Build Coastguard Worker // we don't know everything for certain yet) whether this offset is likely
264*9880d681SAndroid Build Coastguard Worker // to be out of range of the immediate. Return true if so.
265*9880d681SAndroid Build Coastguard Worker
266*9880d681SAndroid Build Coastguard Worker // We only generate virtual base registers for loads and stores, so
267*9880d681SAndroid Build Coastguard Worker // return false for everything else.
268*9880d681SAndroid Build Coastguard Worker if (!MI->mayLoad() && !MI->mayStore())
269*9880d681SAndroid Build Coastguard Worker return false;
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker // Without a virtual base register, if the function has variable sized
272*9880d681SAndroid Build Coastguard Worker // objects, all fixed-size local references will be via the frame pointer,
273*9880d681SAndroid Build Coastguard Worker // Approximate the offset and see if it's legal for the instruction.
274*9880d681SAndroid Build Coastguard Worker // Note that the incoming offset is based on the SP value at function entry,
275*9880d681SAndroid Build Coastguard Worker // so it'll be negative.
276*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MI->getParent()->getParent();
277*9880d681SAndroid Build Coastguard Worker const AArch64FrameLowering *TFI = getFrameLowering(MF);
278*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker // Estimate an offset from the frame pointer.
281*9880d681SAndroid Build Coastguard Worker // Conservatively assume all GPR callee-saved registers get pushed.
282*9880d681SAndroid Build Coastguard Worker // FP, LR, X19-X28, D8-D15. 64-bits each.
283*9880d681SAndroid Build Coastguard Worker int64_t FPOffset = Offset - 16 * 20;
284*9880d681SAndroid Build Coastguard Worker // Estimate an offset from the stack pointer.
285*9880d681SAndroid Build Coastguard Worker // The incoming offset is relating to the SP at the start of the function,
286*9880d681SAndroid Build Coastguard Worker // but when we access the local it'll be relative to the SP after local
287*9880d681SAndroid Build Coastguard Worker // allocation, so adjust our SP-relative offset by that allocation size.
288*9880d681SAndroid Build Coastguard Worker Offset += MFI->getLocalFrameSize();
289*9880d681SAndroid Build Coastguard Worker // Assume that we'll have at least some spill slots allocated.
290*9880d681SAndroid Build Coastguard Worker // FIXME: This is a total SWAG number. We should run some statistics
291*9880d681SAndroid Build Coastguard Worker // and pick a real one.
292*9880d681SAndroid Build Coastguard Worker Offset += 128; // 128 bytes of spill slots
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker // If there is a frame pointer, try using it.
295*9880d681SAndroid Build Coastguard Worker // The FP is only available if there is no dynamic realignment. We
296*9880d681SAndroid Build Coastguard Worker // don't know for sure yet whether we'll need that, so we guess based
297*9880d681SAndroid Build Coastguard Worker // on whether there are any local variables that would trigger it.
298*9880d681SAndroid Build Coastguard Worker if (TFI->hasFP(MF) && isFrameOffsetLegal(MI, AArch64::FP, FPOffset))
299*9880d681SAndroid Build Coastguard Worker return false;
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker // If we can reference via the stack pointer or base pointer, try that.
302*9880d681SAndroid Build Coastguard Worker // FIXME: This (and the code that resolves the references) can be improved
303*9880d681SAndroid Build Coastguard Worker // to only disallow SP relative references in the live range of
304*9880d681SAndroid Build Coastguard Worker // the VLA(s). In practice, it's unclear how much difference that
305*9880d681SAndroid Build Coastguard Worker // would make, but it may be worth doing.
306*9880d681SAndroid Build Coastguard Worker if (isFrameOffsetLegal(MI, AArch64::SP, Offset))
307*9880d681SAndroid Build Coastguard Worker return false;
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker // The offset likely isn't legal; we want to allocate a virtual base register.
310*9880d681SAndroid Build Coastguard Worker return true;
311*9880d681SAndroid Build Coastguard Worker }
312*9880d681SAndroid Build Coastguard Worker
isFrameOffsetLegal(const MachineInstr * MI,unsigned BaseReg,int64_t Offset) const313*9880d681SAndroid Build Coastguard Worker bool AArch64RegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
314*9880d681SAndroid Build Coastguard Worker unsigned BaseReg,
315*9880d681SAndroid Build Coastguard Worker int64_t Offset) const {
316*9880d681SAndroid Build Coastguard Worker assert(Offset <= INT_MAX && "Offset too big to fit in int.");
317*9880d681SAndroid Build Coastguard Worker assert(MI && "Unable to get the legal offset for nil instruction.");
318*9880d681SAndroid Build Coastguard Worker int SaveOffset = Offset;
319*9880d681SAndroid Build Coastguard Worker return isAArch64FrameOffsetLegal(*MI, SaveOffset) & AArch64FrameOffsetIsLegal;
320*9880d681SAndroid Build Coastguard Worker }
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Worker /// Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx
323*9880d681SAndroid Build Coastguard Worker /// at the beginning of the basic block.
materializeFrameBaseRegister(MachineBasicBlock * MBB,unsigned BaseReg,int FrameIdx,int64_t Offset) const324*9880d681SAndroid Build Coastguard Worker void AArch64RegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
325*9880d681SAndroid Build Coastguard Worker unsigned BaseReg,
326*9880d681SAndroid Build Coastguard Worker int FrameIdx,
327*9880d681SAndroid Build Coastguard Worker int64_t Offset) const {
328*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Ins = MBB->begin();
329*9880d681SAndroid Build Coastguard Worker DebugLoc DL; // Defaults to "unknown"
330*9880d681SAndroid Build Coastguard Worker if (Ins != MBB->end())
331*9880d681SAndroid Build Coastguard Worker DL = Ins->getDebugLoc();
332*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF = *MBB->getParent();
333*9880d681SAndroid Build Coastguard Worker const AArch64InstrInfo *TII =
334*9880d681SAndroid Build Coastguard Worker MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
335*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &MCID = TII->get(AArch64::ADDXri);
336*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
337*9880d681SAndroid Build Coastguard Worker MRI.constrainRegClass(BaseReg, TII->getRegClass(MCID, 0, this, MF));
338*9880d681SAndroid Build Coastguard Worker unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0);
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker BuildMI(*MBB, Ins, DL, MCID, BaseReg)
341*9880d681SAndroid Build Coastguard Worker .addFrameIndex(FrameIdx)
342*9880d681SAndroid Build Coastguard Worker .addImm(Offset)
343*9880d681SAndroid Build Coastguard Worker .addImm(Shifter);
344*9880d681SAndroid Build Coastguard Worker }
345*9880d681SAndroid Build Coastguard Worker
resolveFrameIndex(MachineInstr & MI,unsigned BaseReg,int64_t Offset) const346*9880d681SAndroid Build Coastguard Worker void AArch64RegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
347*9880d681SAndroid Build Coastguard Worker int64_t Offset) const {
348*9880d681SAndroid Build Coastguard Worker int Off = Offset; // ARM doesn't need the general 64-bit offsets
349*9880d681SAndroid Build Coastguard Worker unsigned i = 0;
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Worker while (!MI.getOperand(i).isFI()) {
352*9880d681SAndroid Build Coastguard Worker ++i;
353*9880d681SAndroid Build Coastguard Worker assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker const MachineFunction *MF = MI.getParent()->getParent();
356*9880d681SAndroid Build Coastguard Worker const AArch64InstrInfo *TII =
357*9880d681SAndroid Build Coastguard Worker MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
358*9880d681SAndroid Build Coastguard Worker bool Done = rewriteAArch64FrameIndex(MI, i, BaseReg, Off, TII);
359*9880d681SAndroid Build Coastguard Worker assert(Done && "Unable to resolve frame index!");
360*9880d681SAndroid Build Coastguard Worker (void)Done;
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const363*9880d681SAndroid Build Coastguard Worker void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
364*9880d681SAndroid Build Coastguard Worker int SPAdj, unsigned FIOperandNum,
365*9880d681SAndroid Build Coastguard Worker RegScavenger *RS) const {
366*9880d681SAndroid Build Coastguard Worker assert(SPAdj == 0 && "Unexpected");
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Worker MachineInstr &MI = *II;
369*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB = *MI.getParent();
370*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
371*9880d681SAndroid Build Coastguard Worker const AArch64InstrInfo *TII =
372*9880d681SAndroid Build Coastguard Worker MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
373*9880d681SAndroid Build Coastguard Worker const AArch64FrameLowering *TFI = getFrameLowering(MF);
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
376*9880d681SAndroid Build Coastguard Worker unsigned FrameReg;
377*9880d681SAndroid Build Coastguard Worker int Offset;
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker // Special handling of dbg_value, stackmap and patchpoint instructions.
380*9880d681SAndroid Build Coastguard Worker if (MI.isDebugValue() || MI.getOpcode() == TargetOpcode::STACKMAP ||
381*9880d681SAndroid Build Coastguard Worker MI.getOpcode() == TargetOpcode::PATCHPOINT) {
382*9880d681SAndroid Build Coastguard Worker Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg,
383*9880d681SAndroid Build Coastguard Worker /*PreferFP=*/true);
384*9880d681SAndroid Build Coastguard Worker Offset += MI.getOperand(FIOperandNum + 1).getImm();
385*9880d681SAndroid Build Coastguard Worker MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
386*9880d681SAndroid Build Coastguard Worker MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
387*9880d681SAndroid Build Coastguard Worker return;
388*9880d681SAndroid Build Coastguard Worker }
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker // Modify MI as necessary to handle as much of 'Offset' as possible
391*9880d681SAndroid Build Coastguard Worker Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg);
392*9880d681SAndroid Build Coastguard Worker if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
393*9880d681SAndroid Build Coastguard Worker return;
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker assert((!RS || !RS->isScavengingFrameIndex(FrameIndex)) &&
396*9880d681SAndroid Build Coastguard Worker "Emergency spill slot is out of reach");
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker // If we get here, the immediate doesn't fit into the instruction. We folded
399*9880d681SAndroid Build Coastguard Worker // as much as possible above. Handle the rest, providing a register that is
400*9880d681SAndroid Build Coastguard Worker // SP+LargeImm.
401*9880d681SAndroid Build Coastguard Worker unsigned ScratchReg =
402*9880d681SAndroid Build Coastguard Worker MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
403*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset, TII);
404*9880d681SAndroid Build Coastguard Worker MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg, false, false, true);
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker
getRegPressureLimit(const TargetRegisterClass * RC,MachineFunction & MF) const407*9880d681SAndroid Build Coastguard Worker unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
408*9880d681SAndroid Build Coastguard Worker MachineFunction &MF) const {
409*9880d681SAndroid Build Coastguard Worker const AArch64FrameLowering *TFI = getFrameLowering(MF);
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker switch (RC->getID()) {
412*9880d681SAndroid Build Coastguard Worker default:
413*9880d681SAndroid Build Coastguard Worker return 0;
414*9880d681SAndroid Build Coastguard Worker case AArch64::GPR32RegClassID:
415*9880d681SAndroid Build Coastguard Worker case AArch64::GPR32spRegClassID:
416*9880d681SAndroid Build Coastguard Worker case AArch64::GPR32allRegClassID:
417*9880d681SAndroid Build Coastguard Worker case AArch64::GPR64spRegClassID:
418*9880d681SAndroid Build Coastguard Worker case AArch64::GPR64allRegClassID:
419*9880d681SAndroid Build Coastguard Worker case AArch64::GPR64RegClassID:
420*9880d681SAndroid Build Coastguard Worker case AArch64::GPR32commonRegClassID:
421*9880d681SAndroid Build Coastguard Worker case AArch64::GPR64commonRegClassID:
422*9880d681SAndroid Build Coastguard Worker return 32 - 1 // XZR/SP
423*9880d681SAndroid Build Coastguard Worker - (TFI->hasFP(MF) || TT.isOSDarwin()) // FP
424*9880d681SAndroid Build Coastguard Worker - MF.getSubtarget<AArch64Subtarget>()
425*9880d681SAndroid Build Coastguard Worker .isX18Reserved() // X18 reserved as platform register
426*9880d681SAndroid Build Coastguard Worker - hasBasePointer(MF); // X19
427*9880d681SAndroid Build Coastguard Worker case AArch64::FPR8RegClassID:
428*9880d681SAndroid Build Coastguard Worker case AArch64::FPR16RegClassID:
429*9880d681SAndroid Build Coastguard Worker case AArch64::FPR32RegClassID:
430*9880d681SAndroid Build Coastguard Worker case AArch64::FPR64RegClassID:
431*9880d681SAndroid Build Coastguard Worker case AArch64::FPR128RegClassID:
432*9880d681SAndroid Build Coastguard Worker return 32;
433*9880d681SAndroid Build Coastguard Worker
434*9880d681SAndroid Build Coastguard Worker case AArch64::DDRegClassID:
435*9880d681SAndroid Build Coastguard Worker case AArch64::DDDRegClassID:
436*9880d681SAndroid Build Coastguard Worker case AArch64::DDDDRegClassID:
437*9880d681SAndroid Build Coastguard Worker case AArch64::QQRegClassID:
438*9880d681SAndroid Build Coastguard Worker case AArch64::QQQRegClassID:
439*9880d681SAndroid Build Coastguard Worker case AArch64::QQQQRegClassID:
440*9880d681SAndroid Build Coastguard Worker return 32;
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Worker case AArch64::FPR128_loRegClassID:
443*9880d681SAndroid Build Coastguard Worker return 16;
444*9880d681SAndroid Build Coastguard Worker }
445*9880d681SAndroid Build Coastguard Worker }
446