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