1 | //===-- ARMBaseRegisterInfo.cpp - ARM Register Information ----------------===// |
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 | // This file contains the base ARM implementation of TargetRegisterInfo class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "ARMBaseRegisterInfo.h" |
14 | #include "ARM.h" |
15 | #include "ARMBaseInstrInfo.h" |
16 | #include "ARMFrameLowering.h" |
17 | #include "ARMMachineFunctionInfo.h" |
18 | #include "ARMSubtarget.h" |
19 | #include "MCTargetDesc/ARMAddressingModes.h" |
20 | #include "MCTargetDesc/ARMBaseInfo.h" |
21 | #include "llvm/ADT/BitVector.h" |
22 | #include "llvm/ADT/STLExtras.h" |
23 | #include "llvm/ADT/SmallVector.h" |
24 | #include "llvm/CodeGen/MachineBasicBlock.h" |
25 | #include "llvm/CodeGen/MachineConstantPool.h" |
26 | #include "llvm/CodeGen/MachineFrameInfo.h" |
27 | #include "llvm/CodeGen/MachineFunction.h" |
28 | #include "llvm/CodeGen/MachineInstr.h" |
29 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
30 | #include "llvm/CodeGen/MachineOperand.h" |
31 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
32 | #include "llvm/CodeGen/RegisterScavenging.h" |
33 | #include "llvm/CodeGen/TargetInstrInfo.h" |
34 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
35 | #include "llvm/CodeGen/VirtRegMap.h" |
36 | #include "llvm/IR/Attributes.h" |
37 | #include "llvm/IR/Constants.h" |
38 | #include "llvm/IR/DebugLoc.h" |
39 | #include "llvm/IR/Function.h" |
40 | #include "llvm/IR/Type.h" |
41 | #include "llvm/MC/MCInstrDesc.h" |
42 | #include "llvm/Support/Debug.h" |
43 | #include "llvm/Support/ErrorHandling.h" |
44 | #include "llvm/Support/raw_ostream.h" |
45 | #include "llvm/Target/TargetMachine.h" |
46 | #include "llvm/Target/TargetOptions.h" |
47 | #include <cassert> |
48 | #include <utility> |
49 | |
50 | #define DEBUG_TYPE "arm-register-info" |
51 | |
52 | #define GET_REGINFO_TARGET_DESC |
53 | #include "ARMGenRegisterInfo.inc" |
54 | |
55 | using namespace llvm; |
56 | |
57 | ARMBaseRegisterInfo::ARMBaseRegisterInfo() |
58 | : ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC) { |
59 | ARM_MC::initLLVMToCVRegMapping(this); |
60 | } |
61 | |
62 | const MCPhysReg* |
63 | ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { |
64 | const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>(); |
65 | bool UseSplitPush = STI.splitFramePushPop(MF: *MF); |
66 | const Function &F = MF->getFunction(); |
67 | |
68 | if (F.getCallingConv() == CallingConv::GHC) { |
69 | // GHC set of callee saved regs is empty as all those regs are |
70 | // used for passing STG regs around |
71 | return CSR_NoRegs_SaveList; |
72 | } else if (STI.splitFramePointerPush(MF: *MF)) { |
73 | return CSR_Win_SplitFP_SaveList; |
74 | } else if (F.getCallingConv() == CallingConv::CFGuard_Check) { |
75 | return CSR_Win_AAPCS_CFGuard_Check_SaveList; |
76 | } else if (F.getCallingConv() == CallingConv::SwiftTail) { |
77 | return STI.isTargetDarwin() |
78 | ? CSR_iOS_SwiftTail_SaveList |
79 | : (UseSplitPush ? CSR_ATPCS_SplitPush_SwiftTail_SaveList |
80 | : CSR_AAPCS_SwiftTail_SaveList); |
81 | } else if (F.hasFnAttribute(Kind: "interrupt" )) { |
82 | if (STI.isMClass()) { |
83 | // M-class CPUs have hardware which saves the registers needed to allow a |
84 | // function conforming to the AAPCS to function as a handler. |
85 | return UseSplitPush ? CSR_ATPCS_SplitPush_SaveList : CSR_AAPCS_SaveList; |
86 | } else if (F.getFnAttribute(Kind: "interrupt" ).getValueAsString() == "FIQ" ) { |
87 | // Fast interrupt mode gives the handler a private copy of R8-R14, so less |
88 | // need to be saved to restore user-mode state. |
89 | return CSR_FIQ_SaveList; |
90 | } else { |
91 | // Generally only R13-R14 (i.e. SP, LR) are automatically preserved by |
92 | // exception handling. |
93 | return CSR_GenericInt_SaveList; |
94 | } |
95 | } |
96 | |
97 | if (STI.getTargetLowering()->supportSwiftError() && |
98 | F.getAttributes().hasAttrSomewhere(Attribute::Kind: SwiftError)) { |
99 | if (STI.isTargetDarwin()) |
100 | return CSR_iOS_SwiftError_SaveList; |
101 | |
102 | return UseSplitPush ? CSR_ATPCS_SplitPush_SwiftError_SaveList : |
103 | CSR_AAPCS_SwiftError_SaveList; |
104 | } |
105 | |
106 | if (STI.isTargetDarwin() && F.getCallingConv() == CallingConv::CXX_FAST_TLS) |
107 | return MF->getInfo<ARMFunctionInfo>()->isSplitCSR() |
108 | ? CSR_iOS_CXX_TLS_PE_SaveList |
109 | : CSR_iOS_CXX_TLS_SaveList; |
110 | |
111 | if (STI.isTargetDarwin()) |
112 | return CSR_iOS_SaveList; |
113 | |
114 | if (UseSplitPush) |
115 | return STI.createAAPCSFrameChain() ? CSR_AAPCS_SplitPush_SaveList |
116 | : CSR_ATPCS_SplitPush_SaveList; |
117 | |
118 | return CSR_AAPCS_SaveList; |
119 | } |
120 | |
121 | const MCPhysReg *ARMBaseRegisterInfo::getCalleeSavedRegsViaCopy( |
122 | const MachineFunction *MF) const { |
123 | assert(MF && "Invalid MachineFunction pointer." ); |
124 | if (MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS && |
125 | MF->getInfo<ARMFunctionInfo>()->isSplitCSR()) |
126 | return CSR_iOS_CXX_TLS_ViaCopy_SaveList; |
127 | return nullptr; |
128 | } |
129 | |
130 | const uint32_t * |
131 | ARMBaseRegisterInfo::getCallPreservedMask(const MachineFunction &MF, |
132 | CallingConv::ID CC) const { |
133 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
134 | if (CC == CallingConv::GHC) |
135 | // This is academic because all GHC calls are (supposed to be) tail calls |
136 | return CSR_NoRegs_RegMask; |
137 | if (CC == CallingConv::CFGuard_Check) |
138 | return CSR_Win_AAPCS_CFGuard_Check_RegMask; |
139 | if (CC == CallingConv::SwiftTail) { |
140 | return STI.isTargetDarwin() ? CSR_iOS_SwiftTail_RegMask |
141 | : CSR_AAPCS_SwiftTail_RegMask; |
142 | } |
143 | if (STI.getTargetLowering()->supportSwiftError() && |
144 | MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::Kind: SwiftError)) |
145 | return STI.isTargetDarwin() ? CSR_iOS_SwiftError_RegMask |
146 | : CSR_AAPCS_SwiftError_RegMask; |
147 | |
148 | if (STI.isTargetDarwin() && CC == CallingConv::CXX_FAST_TLS) |
149 | return CSR_iOS_CXX_TLS_RegMask; |
150 | return STI.isTargetDarwin() ? CSR_iOS_RegMask : CSR_AAPCS_RegMask; |
151 | } |
152 | |
153 | const uint32_t* |
154 | ARMBaseRegisterInfo::getNoPreservedMask() const { |
155 | return CSR_NoRegs_RegMask; |
156 | } |
157 | |
158 | const uint32_t * |
159 | ARMBaseRegisterInfo::getTLSCallPreservedMask(const MachineFunction &MF) const { |
160 | assert(MF.getSubtarget<ARMSubtarget>().isTargetDarwin() && |
161 | "only know about special TLS call on Darwin" ); |
162 | return CSR_iOS_TLSCall_RegMask; |
163 | } |
164 | |
165 | const uint32_t * |
166 | ARMBaseRegisterInfo::getSjLjDispatchPreservedMask(const MachineFunction &MF) const { |
167 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
168 | if (!STI.useSoftFloat() && STI.hasVFP2Base() && !STI.isThumb1Only()) |
169 | return CSR_NoRegs_RegMask; |
170 | else |
171 | return CSR_FPRegs_RegMask; |
172 | } |
173 | |
174 | const uint32_t * |
175 | ARMBaseRegisterInfo::getThisReturnPreservedMask(const MachineFunction &MF, |
176 | CallingConv::ID CC) const { |
177 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
178 | // This should return a register mask that is the same as that returned by |
179 | // getCallPreservedMask but that additionally preserves the register used for |
180 | // the first i32 argument (which must also be the register used to return a |
181 | // single i32 return value) |
182 | // |
183 | // In case that the calling convention does not use the same register for |
184 | // both or otherwise does not want to enable this optimization, the function |
185 | // should return NULL |
186 | if (CC == CallingConv::GHC) |
187 | // This is academic because all GHC calls are (supposed to be) tail calls |
188 | return nullptr; |
189 | return STI.isTargetDarwin() ? CSR_iOS_ThisReturn_RegMask |
190 | : CSR_AAPCS_ThisReturn_RegMask; |
191 | } |
192 | |
193 | ArrayRef<MCPhysReg> ARMBaseRegisterInfo::getIntraCallClobberedRegs( |
194 | const MachineFunction *MF) const { |
195 | static const MCPhysReg IntraCallClobberedRegs[] = {ARM::R12}; |
196 | return ArrayRef<MCPhysReg>(IntraCallClobberedRegs); |
197 | } |
198 | |
199 | BitVector ARMBaseRegisterInfo:: |
200 | getReservedRegs(const MachineFunction &MF) const { |
201 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
202 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
203 | |
204 | // FIXME: avoid re-calculating this every time. |
205 | BitVector Reserved(getNumRegs()); |
206 | markSuperRegs(Reserved, ARM::SP); |
207 | markSuperRegs(Reserved, ARM::PC); |
208 | markSuperRegs(Reserved, ARM::FPSCR); |
209 | markSuperRegs(Reserved, ARM::APSR_NZCV); |
210 | if (TFI->hasFP(MF)) |
211 | markSuperRegs(Reserved, STI.getFramePointerReg()); |
212 | if (hasBasePointer(MF)) |
213 | markSuperRegs(Reserved, BasePtr); |
214 | // Some targets reserve R9. |
215 | if (STI.isR9Reserved()) |
216 | markSuperRegs(Reserved, ARM::R9); |
217 | // Reserve D16-D31 if the subtarget doesn't support them. |
218 | if (!STI.hasD32()) { |
219 | static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!" ); |
220 | for (unsigned R = 0; R < 16; ++R) |
221 | markSuperRegs(Reserved, ARM::D16 + R); |
222 | } |
223 | const TargetRegisterClass &RC = ARM::GPRPairRegClass; |
224 | for (unsigned Reg : RC) |
225 | for (MCPhysReg S : subregs(Reg)) |
226 | if (Reserved.test(S)) |
227 | markSuperRegs(Reserved, Reg); |
228 | // For v8.1m architecture |
229 | markSuperRegs(Reserved, ARM::ZR); |
230 | |
231 | assert(checkAllSuperRegsMarked(Reserved)); |
232 | return Reserved; |
233 | } |
234 | |
235 | bool ARMBaseRegisterInfo:: |
236 | isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const { |
237 | return !getReservedRegs(MF).test(Idx: PhysReg); |
238 | } |
239 | |
240 | bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF, |
241 | unsigned PhysReg) const { |
242 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
243 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
244 | |
245 | BitVector Reserved(getNumRegs()); |
246 | markSuperRegs(Reserved, ARM::PC); |
247 | if (TFI->isFPReserved(MF)) |
248 | markSuperRegs(Reserved, STI.getFramePointerReg()); |
249 | if (hasBasePointer(MF)) |
250 | markSuperRegs(Reserved, BasePtr); |
251 | assert(checkAllSuperRegsMarked(Reserved)); |
252 | return Reserved.test(Idx: PhysReg); |
253 | } |
254 | |
255 | const TargetRegisterClass * |
256 | ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, |
257 | const MachineFunction &MF) const { |
258 | const TargetRegisterClass *Super = RC; |
259 | TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); |
260 | do { |
261 | switch (Super->getID()) { |
262 | case ARM::GPRRegClassID: |
263 | case ARM::SPRRegClassID: |
264 | case ARM::DPRRegClassID: |
265 | case ARM::GPRPairRegClassID: |
266 | return Super; |
267 | case ARM::QPRRegClassID: |
268 | case ARM::QQPRRegClassID: |
269 | case ARM::QQQQPRRegClassID: |
270 | if (MF.getSubtarget<ARMSubtarget>().hasNEON()) |
271 | return Super; |
272 | break; |
273 | case ARM::MQPRRegClassID: |
274 | case ARM::MQQPRRegClassID: |
275 | case ARM::MQQQQPRRegClassID: |
276 | if (MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps()) |
277 | return Super; |
278 | break; |
279 | } |
280 | Super = *I++; |
281 | } while (Super); |
282 | return RC; |
283 | } |
284 | |
285 | const TargetRegisterClass * |
286 | ARMBaseRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) |
287 | const { |
288 | return &ARM::GPRRegClass; |
289 | } |
290 | |
291 | const TargetRegisterClass * |
292 | ARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { |
293 | if (RC == &ARM::CCRRegClass) |
294 | return &ARM::rGPRRegClass; // Can't copy CCR registers. |
295 | return RC; |
296 | } |
297 | |
298 | unsigned |
299 | ARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, |
300 | MachineFunction &MF) const { |
301 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
302 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
303 | |
304 | switch (RC->getID()) { |
305 | default: |
306 | return 0; |
307 | case ARM::tGPRRegClassID: { |
308 | // hasFP ends up calling getMaxCallFrameComputed() which may not be |
309 | // available when getPressureLimit() is called as part of |
310 | // ScheduleDAGRRList. |
311 | bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() |
312 | ? TFI->hasFP(MF) : true; |
313 | return 5 - HasFP; |
314 | } |
315 | case ARM::GPRRegClassID: { |
316 | bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() |
317 | ? TFI->hasFP(MF) : true; |
318 | return 10 - HasFP - (STI.isR9Reserved() ? 1 : 0); |
319 | } |
320 | case ARM::SPRRegClassID: // Currently not used as 'rep' register class. |
321 | case ARM::DPRRegClassID: |
322 | return 32 - 10; |
323 | } |
324 | } |
325 | |
326 | // Get the other register in a GPRPair. |
327 | static MCPhysReg getPairedGPR(MCPhysReg Reg, bool Odd, |
328 | const MCRegisterInfo *RI) { |
329 | for (MCPhysReg Super : RI->superregs(Reg)) |
330 | if (ARM::GPRPairRegClass.contains(Super)) |
331 | return RI->getSubReg(Super, Odd ? ARM::gsub_1 : ARM::gsub_0); |
332 | return 0; |
333 | } |
334 | |
335 | // Resolve the RegPairEven / RegPairOdd register allocator hints. |
336 | bool ARMBaseRegisterInfo::getRegAllocationHints( |
337 | Register VirtReg, ArrayRef<MCPhysReg> Order, |
338 | SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF, |
339 | const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const { |
340 | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
341 | std::pair<unsigned, Register> Hint = MRI.getRegAllocationHint(VReg: VirtReg); |
342 | |
343 | unsigned Odd; |
344 | switch (Hint.first) { |
345 | case ARMRI::RegPairEven: |
346 | Odd = 0; |
347 | break; |
348 | case ARMRI::RegPairOdd: |
349 | Odd = 1; |
350 | break; |
351 | case ARMRI::RegLR: |
352 | TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM); |
353 | if (MRI.getRegClass(VirtReg)->contains(ARM::LR)) |
354 | Hints.push_back(ARM::LR); |
355 | return false; |
356 | default: |
357 | return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM); |
358 | } |
359 | |
360 | // This register should preferably be even (Odd == 0) or odd (Odd == 1). |
361 | // Check if the other part of the pair has already been assigned, and provide |
362 | // the paired register as the first hint. |
363 | Register Paired = Hint.second; |
364 | if (!Paired) |
365 | return false; |
366 | |
367 | Register PairedPhys; |
368 | if (Paired.isPhysical()) { |
369 | PairedPhys = Paired; |
370 | } else if (VRM && VRM->hasPhys(virtReg: Paired)) { |
371 | PairedPhys = getPairedGPR(VRM->getPhys(virtReg: Paired), Odd, this); |
372 | } |
373 | |
374 | // First prefer the paired physreg. |
375 | if (PairedPhys && is_contained(Range&: Order, Element: PairedPhys)) |
376 | Hints.push_back(Elt: PairedPhys); |
377 | |
378 | // Then prefer even or odd registers. |
379 | for (MCPhysReg Reg : Order) { |
380 | if (Reg == PairedPhys || (getEncodingValue(Reg) & 1) != Odd) |
381 | continue; |
382 | // Don't provide hints that are paired to a reserved register. |
383 | MCPhysReg Paired = getPairedGPR(Reg, !Odd, this); |
384 | if (!Paired || MRI.isReserved(PhysReg: Paired)) |
385 | continue; |
386 | Hints.push_back(Elt: Reg); |
387 | } |
388 | return false; |
389 | } |
390 | |
391 | void ARMBaseRegisterInfo::updateRegAllocHint(Register Reg, Register NewReg, |
392 | MachineFunction &MF) const { |
393 | MachineRegisterInfo *MRI = &MF.getRegInfo(); |
394 | std::pair<unsigned, Register> Hint = MRI->getRegAllocationHint(VReg: Reg); |
395 | if ((Hint.first == ARMRI::RegPairOdd || Hint.first == ARMRI::RegPairEven) && |
396 | Hint.second.isVirtual()) { |
397 | // If 'Reg' is one of the even / odd register pair and it's now changed |
398 | // (e.g. coalesced) into a different register. The other register of the |
399 | // pair allocation hint must be updated to reflect the relationship |
400 | // change. |
401 | Register OtherReg = Hint.second; |
402 | Hint = MRI->getRegAllocationHint(VReg: OtherReg); |
403 | // Make sure the pair has not already divorced. |
404 | if (Hint.second == Reg) { |
405 | MRI->setRegAllocationHint(VReg: OtherReg, Type: Hint.first, PrefReg: NewReg); |
406 | if (NewReg.isVirtual()) |
407 | MRI->setRegAllocationHint(VReg: NewReg, |
408 | Type: Hint.first == ARMRI::RegPairOdd |
409 | ? ARMRI::RegPairEven |
410 | : ARMRI::RegPairOdd, |
411 | PrefReg: OtherReg); |
412 | } |
413 | } |
414 | } |
415 | |
416 | bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { |
417 | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
418 | const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
419 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
420 | |
421 | // If we have stack realignment and VLAs, we have no pointer to use to |
422 | // access the stack. If we have stack realignment, and a large call frame, |
423 | // we have no place to allocate the emergency spill slot. |
424 | if (hasStackRealignment(MF) && !TFI->hasReservedCallFrame(MF)) |
425 | return true; |
426 | |
427 | // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited |
428 | // negative range for ldr/str (255), and Thumb1 is positive offsets only. |
429 | // |
430 | // It's going to be better to use the SP or Base Pointer instead. When there |
431 | // are variable sized objects, we can't reference off of the SP, so we |
432 | // reserve a Base Pointer. |
433 | // |
434 | // For Thumb2, estimate whether a negative offset from the frame pointer |
435 | // will be sufficient to reach the whole stack frame. If a function has a |
436 | // smallish frame, it's less likely to have lots of spills and callee saved |
437 | // space, so it's all more likely to be within range of the frame pointer. |
438 | // If it's wrong, the scavenger will still enable access to work, it just |
439 | // won't be optimal. (We should always be able to reach the emergency |
440 | // spill slot from the frame pointer.) |
441 | if (AFI->isThumb2Function() && MFI.hasVarSizedObjects() && |
442 | MFI.getLocalFrameSize() >= 128) |
443 | return true; |
444 | // For Thumb1, if sp moves, nothing is in range, so force a base pointer. |
445 | // This is necessary for correctness in cases where we need an emergency |
446 | // spill slot. (In Thumb1, we can't use a negative offset from the frame |
447 | // pointer.) |
448 | if (AFI->isThumb1OnlyFunction() && !TFI->hasReservedCallFrame(MF)) |
449 | return true; |
450 | return false; |
451 | } |
452 | |
453 | bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { |
454 | const MachineRegisterInfo *MRI = &MF.getRegInfo(); |
455 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
456 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
457 | // We can't realign the stack if: |
458 | // 1. Dynamic stack realignment is explicitly disabled, |
459 | // 2. There are VLAs in the function and the base pointer is disabled. |
460 | if (!TargetRegisterInfo::canRealignStack(MF)) |
461 | return false; |
462 | // Stack realignment requires a frame pointer. If we already started |
463 | // register allocation with frame pointer elimination, it is too late now. |
464 | if (!MRI->canReserveReg(PhysReg: STI.getFramePointerReg())) |
465 | return false; |
466 | // We may also need a base pointer if there are dynamic allocas or stack |
467 | // pointer adjustments around calls. |
468 | if (TFI->hasReservedCallFrame(MF)) |
469 | return true; |
470 | // A base pointer is required and allowed. Check that it isn't too late to |
471 | // reserve it. |
472 | return MRI->canReserveReg(BasePtr); |
473 | } |
474 | |
475 | bool ARMBaseRegisterInfo:: |
476 | cannotEliminateFrame(const MachineFunction &MF) const { |
477 | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
478 | if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI.adjustsStack()) |
479 | return true; |
480 | return MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() || |
481 | hasStackRealignment(MF); |
482 | } |
483 | |
484 | Register |
485 | ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const { |
486 | const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); |
487 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
488 | |
489 | if (TFI->hasFP(MF)) |
490 | return STI.getFramePointerReg(); |
491 | return ARM::SP; |
492 | } |
493 | |
494 | /// emitLoadConstPool - Emits a load from constpool to materialize the |
495 | /// specified immediate. |
496 | void ARMBaseRegisterInfo::emitLoadConstPool( |
497 | MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, |
498 | const DebugLoc &dl, Register DestReg, unsigned SubIdx, int Val, |
499 | ARMCC::CondCodes Pred, Register PredReg, unsigned MIFlags) const { |
500 | MachineFunction &MF = *MBB.getParent(); |
501 | const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); |
502 | MachineConstantPool *ConstantPool = MF.getConstantPool(); |
503 | const Constant *C = |
504 | ConstantInt::get(Ty: Type::getInt32Ty(C&: MF.getFunction().getContext()), V: Val); |
505 | unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment: Align(4)); |
506 | |
507 | BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp)) |
508 | .addReg(DestReg, getDefRegState(true), SubIdx) |
509 | .addConstantPoolIndex(Idx) |
510 | .addImm(0) |
511 | .add(predOps(Pred, PredReg)) |
512 | .setMIFlags(MIFlags); |
513 | } |
514 | |
515 | bool ARMBaseRegisterInfo:: |
516 | requiresRegisterScavenging(const MachineFunction &MF) const { |
517 | return true; |
518 | } |
519 | |
520 | bool ARMBaseRegisterInfo:: |
521 | requiresFrameIndexScavenging(const MachineFunction &MF) const { |
522 | return true; |
523 | } |
524 | |
525 | bool ARMBaseRegisterInfo:: |
526 | requiresVirtualBaseRegisters(const MachineFunction &MF) const { |
527 | return true; |
528 | } |
529 | |
530 | int64_t ARMBaseRegisterInfo:: |
531 | getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const { |
532 | const MCInstrDesc &Desc = MI->getDesc(); |
533 | unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); |
534 | int64_t InstrOffs = 0; |
535 | int Scale = 1; |
536 | unsigned ImmIdx = 0; |
537 | switch (AddrMode) { |
538 | case ARMII::AddrModeT2_i8: |
539 | case ARMII::AddrModeT2_i8neg: |
540 | case ARMII::AddrModeT2_i8pos: |
541 | case ARMII::AddrModeT2_i12: |
542 | case ARMII::AddrMode_i12: |
543 | InstrOffs = MI->getOperand(i: Idx+1).getImm(); |
544 | Scale = 1; |
545 | break; |
546 | case ARMII::AddrMode5: { |
547 | // VFP address mode. |
548 | const MachineOperand &OffOp = MI->getOperand(i: Idx+1); |
549 | InstrOffs = ARM_AM::getAM5Offset(AM5Opc: OffOp.getImm()); |
550 | if (ARM_AM::getAM5Op(AM5Opc: OffOp.getImm()) == ARM_AM::sub) |
551 | InstrOffs = -InstrOffs; |
552 | Scale = 4; |
553 | break; |
554 | } |
555 | case ARMII::AddrMode2: |
556 | ImmIdx = Idx+2; |
557 | InstrOffs = ARM_AM::getAM2Offset(AM2Opc: MI->getOperand(i: ImmIdx).getImm()); |
558 | if (ARM_AM::getAM2Op(AM2Opc: MI->getOperand(i: ImmIdx).getImm()) == ARM_AM::sub) |
559 | InstrOffs = -InstrOffs; |
560 | break; |
561 | case ARMII::AddrMode3: |
562 | ImmIdx = Idx+2; |
563 | InstrOffs = ARM_AM::getAM3Offset(AM3Opc: MI->getOperand(i: ImmIdx).getImm()); |
564 | if (ARM_AM::getAM3Op(AM3Opc: MI->getOperand(i: ImmIdx).getImm()) == ARM_AM::sub) |
565 | InstrOffs = -InstrOffs; |
566 | break; |
567 | case ARMII::AddrModeT1_s: |
568 | ImmIdx = Idx+1; |
569 | InstrOffs = MI->getOperand(i: ImmIdx).getImm(); |
570 | Scale = 4; |
571 | break; |
572 | default: |
573 | llvm_unreachable("Unsupported addressing mode!" ); |
574 | } |
575 | |
576 | return InstrOffs * Scale; |
577 | } |
578 | |
579 | /// needsFrameBaseReg - Returns true if the instruction's frame index |
580 | /// reference would be better served by a base register other than FP |
581 | /// or SP. Used by LocalStackFrameAllocation to determine which frame index |
582 | /// references it should create new base registers for. |
583 | bool ARMBaseRegisterInfo:: |
584 | needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { |
585 | for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) { |
586 | assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!" ); |
587 | } |
588 | |
589 | // It's the load/store FI references that cause issues, as it can be difficult |
590 | // to materialize the offset if it won't fit in the literal field. Estimate |
591 | // based on the size of the local frame and some conservative assumptions |
592 | // about the rest of the stack frame (note, this is pre-regalloc, so |
593 | // we don't know everything for certain yet) whether this offset is likely |
594 | // to be out of range of the immediate. Return true if so. |
595 | |
596 | // We only generate virtual base registers for loads and stores, so |
597 | // return false for everything else. |
598 | unsigned Opc = MI->getOpcode(); |
599 | switch (Opc) { |
600 | case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12: |
601 | case ARM::STRi12: case ARM::STRH: case ARM::STRBi12: |
602 | case ARM::t2LDRi12: case ARM::t2LDRi8: |
603 | case ARM::t2STRi12: case ARM::t2STRi8: |
604 | case ARM::VLDRS: case ARM::VLDRD: |
605 | case ARM::VSTRS: case ARM::VSTRD: |
606 | case ARM::tSTRspi: case ARM::tLDRspi: |
607 | break; |
608 | default: |
609 | return false; |
610 | } |
611 | |
612 | // Without a virtual base register, if the function has variable sized |
613 | // objects, all fixed-size local references will be via the frame pointer, |
614 | // Approximate the offset and see if it's legal for the instruction. |
615 | // Note that the incoming offset is based on the SP value at function entry, |
616 | // so it'll be negative. |
617 | MachineFunction &MF = *MI->getParent()->getParent(); |
618 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
619 | MachineFrameInfo &MFI = MF.getFrameInfo(); |
620 | ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
621 | |
622 | // Estimate an offset from the frame pointer. |
623 | // Conservatively assume all callee-saved registers get pushed. R4-R6 |
624 | // will be earlier than the FP, so we ignore those. |
625 | // R7, LR |
626 | int64_t FPOffset = Offset - 8; |
627 | // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15 |
628 | if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction()) |
629 | FPOffset -= 80; |
630 | // Estimate an offset from the stack pointer. |
631 | // The incoming offset is relating to the SP at the start of the function, |
632 | // but when we access the local it'll be relative to the SP after local |
633 | // allocation, so adjust our SP-relative offset by that allocation size. |
634 | Offset += MFI.getLocalFrameSize(); |
635 | // Assume that we'll have at least some spill slots allocated. |
636 | // FIXME: This is a total SWAG number. We should run some statistics |
637 | // and pick a real one. |
638 | Offset += 128; // 128 bytes of spill slots |
639 | |
640 | // If there's a frame pointer and the addressing mode allows it, try using it. |
641 | // The FP is only available if there is no dynamic realignment. We |
642 | // don't know for sure yet whether we'll need that, so we guess based |
643 | // on whether there are any local variables that would trigger it. |
644 | if (TFI->hasFP(MF) && |
645 | !((MFI.getLocalFrameMaxAlign() > TFI->getStackAlign()) && |
646 | canRealignStack(MF))) { |
647 | if (isFrameOffsetLegal(MI, BaseReg: getFrameRegister(MF), Offset: FPOffset)) |
648 | return false; |
649 | } |
650 | // If we can reference via the stack pointer, try that. |
651 | // FIXME: This (and the code that resolves the references) can be improved |
652 | // to only disallow SP relative references in the live range of |
653 | // the VLA(s). In practice, it's unclear how much difference that |
654 | // would make, but it may be worth doing. |
655 | if (!MFI.hasVarSizedObjects() && isFrameOffsetLegal(MI, ARM::SP, Offset)) |
656 | return false; |
657 | |
658 | // The offset likely isn't legal, we want to allocate a virtual base register. |
659 | return true; |
660 | } |
661 | |
662 | /// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to |
663 | /// be a pointer to FrameIdx at the beginning of the basic block. |
664 | Register |
665 | ARMBaseRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB, |
666 | int FrameIdx, |
667 | int64_t Offset) const { |
668 | ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>(); |
669 | unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : |
670 | (AFI->isThumb1OnlyFunction() ? ARM::tADDframe : ARM::t2ADDri); |
671 | |
672 | MachineBasicBlock::iterator Ins = MBB->begin(); |
673 | DebugLoc DL; // Defaults to "unknown" |
674 | if (Ins != MBB->end()) |
675 | DL = Ins->getDebugLoc(); |
676 | |
677 | const MachineFunction &MF = *MBB->getParent(); |
678 | MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); |
679 | const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); |
680 | const MCInstrDesc &MCID = TII.get(Opcode: ADDriOpc); |
681 | Register BaseReg = MRI.createVirtualRegister(&ARM::GPRRegClass); |
682 | MRI.constrainRegClass(Reg: BaseReg, RC: TII.getRegClass(MCID, 0, this, MF)); |
683 | |
684 | MachineInstrBuilder MIB = BuildMI(BB&: *MBB, I: Ins, MIMD: DL, MCID, DestReg: BaseReg) |
685 | .addFrameIndex(Idx: FrameIdx).addImm(Val: Offset); |
686 | |
687 | if (!AFI->isThumb1OnlyFunction()) |
688 | MIB.add(MOs: predOps(Pred: ARMCC::AL)).add(MO: condCodeOp()); |
689 | |
690 | return BaseReg; |
691 | } |
692 | |
693 | void ARMBaseRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg, |
694 | int64_t Offset) const { |
695 | MachineBasicBlock &MBB = *MI.getParent(); |
696 | MachineFunction &MF = *MBB.getParent(); |
697 | const ARMBaseInstrInfo &TII = |
698 | *static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo()); |
699 | ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
700 | int Off = Offset; // ARM doesn't need the general 64-bit offsets |
701 | unsigned i = 0; |
702 | |
703 | assert(!AFI->isThumb1OnlyFunction() && |
704 | "This resolveFrameIndex does not support Thumb1!" ); |
705 | |
706 | while (!MI.getOperand(i).isFI()) { |
707 | ++i; |
708 | assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!" ); |
709 | } |
710 | bool Done = false; |
711 | if (!AFI->isThumbFunction()) |
712 | Done = rewriteARMFrameIndex(MI, FrameRegIdx: i, FrameReg: BaseReg, Offset&: Off, TII); |
713 | else { |
714 | assert(AFI->isThumb2Function()); |
715 | Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII, this); |
716 | } |
717 | assert(Done && "Unable to resolve frame index!" ); |
718 | (void)Done; |
719 | } |
720 | |
721 | bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI, |
722 | Register BaseReg, |
723 | int64_t Offset) const { |
724 | const MCInstrDesc &Desc = MI->getDesc(); |
725 | unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); |
726 | unsigned i = 0; |
727 | for (; !MI->getOperand(i).isFI(); ++i) |
728 | assert(i+1 < MI->getNumOperands() && "Instr doesn't have FrameIndex operand!" ); |
729 | |
730 | // AddrMode4 and AddrMode6 cannot handle any offset. |
731 | if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) |
732 | return Offset == 0; |
733 | |
734 | unsigned NumBits = 0; |
735 | unsigned Scale = 1; |
736 | bool isSigned = true; |
737 | switch (AddrMode) { |
738 | case ARMII::AddrModeT2_i8: |
739 | case ARMII::AddrModeT2_i8pos: |
740 | case ARMII::AddrModeT2_i8neg: |
741 | case ARMII::AddrModeT2_i12: |
742 | // i8 supports only negative, and i12 supports only positive, so |
743 | // based on Offset sign, consider the appropriate instruction |
744 | Scale = 1; |
745 | if (Offset < 0) { |
746 | NumBits = 8; |
747 | Offset = -Offset; |
748 | } else { |
749 | NumBits = 12; |
750 | } |
751 | break; |
752 | case ARMII::AddrMode5: |
753 | // VFP address mode. |
754 | NumBits = 8; |
755 | Scale = 4; |
756 | break; |
757 | case ARMII::AddrMode_i12: |
758 | case ARMII::AddrMode2: |
759 | NumBits = 12; |
760 | break; |
761 | case ARMII::AddrMode3: |
762 | NumBits = 8; |
763 | break; |
764 | case ARMII::AddrModeT1_s: |
765 | NumBits = (BaseReg == ARM::SP ? 8 : 5); |
766 | Scale = 4; |
767 | isSigned = false; |
768 | break; |
769 | default: |
770 | llvm_unreachable("Unsupported addressing mode!" ); |
771 | } |
772 | |
773 | Offset += getFrameIndexInstrOffset(MI, Idx: i); |
774 | // Make sure the offset is encodable for instructions that scale the |
775 | // immediate. |
776 | if ((Offset & (Scale-1)) != 0) |
777 | return false; |
778 | |
779 | if (isSigned && Offset < 0) |
780 | Offset = -Offset; |
781 | |
782 | unsigned Mask = (1 << NumBits) - 1; |
783 | if ((unsigned)Offset <= Mask * Scale) |
784 | return true; |
785 | |
786 | return false; |
787 | } |
788 | |
789 | bool |
790 | ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, |
791 | int SPAdj, unsigned FIOperandNum, |
792 | RegScavenger *RS) const { |
793 | MachineInstr &MI = *II; |
794 | MachineBasicBlock &MBB = *MI.getParent(); |
795 | MachineFunction &MF = *MBB.getParent(); |
796 | const ARMBaseInstrInfo &TII = |
797 | *static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo()); |
798 | const ARMFrameLowering *TFI = getFrameLowering(MF); |
799 | ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
800 | assert(!AFI->isThumb1OnlyFunction() && |
801 | "This eliminateFrameIndex does not support Thumb1!" ); |
802 | int FrameIndex = MI.getOperand(i: FIOperandNum).getIndex(); |
803 | Register FrameReg; |
804 | |
805 | int Offset = TFI->ResolveFrameIndexReference(MF, FI: FrameIndex, FrameReg, SPAdj); |
806 | |
807 | // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the |
808 | // call frame setup/destroy instructions have already been eliminated. That |
809 | // means the stack pointer cannot be used to access the emergency spill slot |
810 | // when !hasReservedCallFrame(). |
811 | #ifndef NDEBUG |
812 | if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){ |
813 | assert(TFI->hasReservedCallFrame(MF) && |
814 | "Cannot use SP to access the emergency spill slot in " |
815 | "functions without a reserved call frame" ); |
816 | assert(!MF.getFrameInfo().hasVarSizedObjects() && |
817 | "Cannot use SP to access the emergency spill slot in " |
818 | "functions with variable sized frame objects" ); |
819 | } |
820 | #endif // NDEBUG |
821 | |
822 | assert(!MI.isDebugValue() && "DBG_VALUEs should be handled in target-independent code" ); |
823 | |
824 | // Modify MI as necessary to handle as much of 'Offset' as possible |
825 | bool Done = false; |
826 | if (!AFI->isThumbFunction()) |
827 | Done = rewriteARMFrameIndex(MI, FrameRegIdx: FIOperandNum, FrameReg, Offset, TII); |
828 | else { |
829 | assert(AFI->isThumb2Function()); |
830 | Done = rewriteT2FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII, this); |
831 | } |
832 | if (Done) |
833 | return false; |
834 | |
835 | // If we get here, the immediate doesn't fit into the instruction. We folded |
836 | // as much as possible above, handle the rest, providing a register that is |
837 | // SP+LargeImm. |
838 | assert( |
839 | (Offset || |
840 | (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 || |
841 | (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6 || |
842 | (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrModeT2_i7 || |
843 | (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrModeT2_i7s2 || |
844 | (MI.getDesc().TSFlags & ARMII::AddrModeMask) == |
845 | ARMII::AddrModeT2_i7s4) && |
846 | "This code isn't needed if offset already handled!" ); |
847 | |
848 | unsigned ScratchReg = 0; |
849 | int PIdx = MI.findFirstPredOperandIdx(); |
850 | ARMCC::CondCodes Pred = (PIdx == -1) |
851 | ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(i: PIdx).getImm(); |
852 | Register PredReg = (PIdx == -1) ? Register() : MI.getOperand(i: PIdx+1).getReg(); |
853 | |
854 | const MCInstrDesc &MCID = MI.getDesc(); |
855 | const TargetRegisterClass *RegClass = |
856 | TII.getRegClass(MCID, FIOperandNum, this, *MI.getParent()->getParent()); |
857 | |
858 | if (Offset == 0 && (FrameReg.isVirtual() || RegClass->contains(Reg: FrameReg))) |
859 | // Must be addrmode4/6. |
860 | MI.getOperand(i: FIOperandNum).ChangeToRegister(Reg: FrameReg, isDef: false, isImp: false, isKill: false); |
861 | else { |
862 | ScratchReg = MF.getRegInfo().createVirtualRegister(RegClass); |
863 | if (!AFI->isThumbFunction()) |
864 | emitARMRegPlusImmediate(MBB, MBBI&: II, dl: MI.getDebugLoc(), DestReg: ScratchReg, BaseReg: FrameReg, |
865 | NumBytes: Offset, Pred, PredReg, TII); |
866 | else { |
867 | assert(AFI->isThumb2Function()); |
868 | emitT2RegPlusImmediate(MBB, MBBI&: II, dl: MI.getDebugLoc(), DestReg: ScratchReg, BaseReg: FrameReg, |
869 | NumBytes: Offset, Pred, PredReg, TII); |
870 | } |
871 | // Update the original instruction to use the scratch register. |
872 | MI.getOperand(i: FIOperandNum).ChangeToRegister(Reg: ScratchReg, isDef: false, isImp: false,isKill: true); |
873 | } |
874 | return false; |
875 | } |
876 | |
877 | bool ARMBaseRegisterInfo::shouldCoalesce(MachineInstr *MI, |
878 | const TargetRegisterClass *SrcRC, |
879 | unsigned SubReg, |
880 | const TargetRegisterClass *DstRC, |
881 | unsigned DstSubReg, |
882 | const TargetRegisterClass *NewRC, |
883 | LiveIntervals &LIS) const { |
884 | auto MBB = MI->getParent(); |
885 | auto MF = MBB->getParent(); |
886 | const MachineRegisterInfo &MRI = MF->getRegInfo(); |
887 | // If not copying into a sub-register this should be ok because we shouldn't |
888 | // need to split the reg. |
889 | if (!DstSubReg) |
890 | return true; |
891 | // Small registers don't frequently cause a problem, so we can coalesce them. |
892 | if (getRegSizeInBits(*NewRC) < 256 && getRegSizeInBits(*DstRC) < 256 && |
893 | getRegSizeInBits(*SrcRC) < 256) |
894 | return true; |
895 | |
896 | auto NewRCWeight = |
897 | MRI.getTargetRegisterInfo()->getRegClassWeight(RC: NewRC); |
898 | auto SrcRCWeight = |
899 | MRI.getTargetRegisterInfo()->getRegClassWeight(RC: SrcRC); |
900 | auto DstRCWeight = |
901 | MRI.getTargetRegisterInfo()->getRegClassWeight(RC: DstRC); |
902 | // If the source register class is more expensive than the destination, the |
903 | // coalescing is probably profitable. |
904 | if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight) |
905 | return true; |
906 | if (DstRCWeight.RegWeight > NewRCWeight.RegWeight) |
907 | return true; |
908 | |
909 | // If the register allocator isn't constrained, we can always allow coalescing |
910 | // unfortunately we don't know yet if we will be constrained. |
911 | // The goal of this heuristic is to restrict how many expensive registers |
912 | // we allow to coalesce in a given basic block. |
913 | auto AFI = MF->getInfo<ARMFunctionInfo>(); |
914 | auto It = AFI->getCoalescedWeight(MBB); |
915 | |
916 | LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Coalesced Weight: " |
917 | << It->second << "\n" ); |
918 | LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Reg Weight: " |
919 | << NewRCWeight.RegWeight << "\n" ); |
920 | |
921 | // This number is the largest round number that which meets the criteria: |
922 | // (1) addresses PR18825 |
923 | // (2) generates better code in some test cases (like vldm-shed-a9.ll) |
924 | // (3) Doesn't regress any test cases (in-tree, test-suite, and SPEC) |
925 | // In practice the SizeMultiplier will only factor in for straight line code |
926 | // that uses a lot of NEON vectors, which isn't terribly common. |
927 | unsigned SizeMultiplier = MBB->size()/100; |
928 | SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1; |
929 | if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) { |
930 | It->second += NewRCWeight.RegWeight; |
931 | return true; |
932 | } |
933 | return false; |
934 | } |
935 | |
936 | bool ARMBaseRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC, |
937 | unsigned DefSubReg, |
938 | const TargetRegisterClass *SrcRC, |
939 | unsigned SrcSubReg) const { |
940 | // We can't extract an SPR from an arbitary DPR (as opposed to a DPR_VFP2). |
941 | if (DefRC == &ARM::SPRRegClass && DefSubReg == 0 && |
942 | SrcRC == &ARM::DPRRegClass && |
943 | (SrcSubReg == ARM::ssub_0 || SrcSubReg == ARM::ssub_1)) |
944 | return false; |
945 | |
946 | return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, |
947 | SrcRC, SrcSubReg); |
948 | } |
949 | |