LLVM 24.0.0git
AArch64RegisterInfo.cpp
Go to the documentation of this file.
1//===- AArch64RegisterInfo.cpp - AArch64 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 AArch64 implementation of the TargetRegisterInfo
10// class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AArch64RegisterInfo.h"
16#include "AArch64InstrInfo.h"
19#include "AArch64Subtarget.h"
22#include "llvm/ADT/BitVector.h"
32#include "llvm/IR/Function.h"
34
35using namespace llvm;
36
37#define GET_CC_REGISTER_LISTS
38#include "AArch64GenCallingConv.inc"
39#define GET_REGINFO_TARGET_DESC
40#include "AArch64GenRegisterInfo.inc"
41
43 : AArch64GenRegisterInfo(AArch64::LR, 0, 0, 0, HwMode), TT(TT) {
45}
46
47/// Return whether the register needs a CFI entry. Not all unwinders may know
48/// about SVE registers, so we assume the lowest common denominator, i.e. the
49/// callee-saves required by the base ABI. For the SVE registers z8-z15 only the
50/// lower 64-bits (d8-d15) need to be saved. The lower 64-bits subreg is
51/// returned in \p RegToUseForCFI.
53 MCRegister &RegToUseForCFI) const {
54 if (AArch64::PPRRegClass.contains(Reg))
55 return false;
56
57 if (AArch64::ZPRRegClass.contains(Reg)) {
58 RegToUseForCFI = getSubReg(Reg, AArch64::dsub);
59 for (int I = 0; CSR_AArch64_AAPCS_SaveList[I]; ++I) {
60 if (CSR_AArch64_AAPCS_SaveList[I] == RegToUseForCFI)
61 return true;
62 }
63 return false;
64 }
65
66 RegToUseForCFI = Reg;
67 return true;
68}
69
70const MCPhysReg *
72 assert(MF && "Invalid MachineFunction pointer.");
73
74 auto &AFI = *MF->getInfo<AArch64FunctionInfo>();
75 const auto &F = MF->getFunction();
76 const auto *TLI = MF->getSubtarget<AArch64Subtarget>().getTargetLowering();
77 const bool Darwin = MF->getSubtarget<AArch64Subtarget>().isTargetDarwin();
78 const bool Windows =
79 MF->getSubtarget<AArch64Subtarget>().isTargetWindowsOrUEFI();
80
81 if (TLI->supportSwiftError() &&
82 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) {
83 if (Darwin)
84 return CSR_Darwin_AArch64_AAPCS_SwiftError_SaveList;
85 if (Windows)
86 return CSR_Win_AArch64_AAPCS_SwiftError_SaveList;
87 return CSR_AArch64_AAPCS_SwiftError_SaveList;
88 }
89
90 switch (F.getCallingConv()) {
92 // GHC set of callee saved regs is empty as all those regs are
93 // used for passing STG regs around
94 return CSR_AArch64_NoRegs_SaveList;
95
97 // FIXME: Windows likely need this to be altered for properly unwinding.
98 return CSR_AArch64_NoneRegs_SaveList;
99
101 return CSR_AArch64_AllRegs_SaveList;
102
104 return CSR_Win_AArch64_Arm64EC_Thunk_SaveList;
105
107 if (Darwin)
108 return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
109 if (Windows)
110 return CSR_Win_AArch64_RT_MostRegs_SaveList;
111 return CSR_AArch64_RT_MostRegs_SaveList;
112
114 if (Darwin)
115 return CSR_Darwin_AArch64_RT_AllRegs_SaveList;
116 if (Windows)
117 return CSR_Win_AArch64_RT_AllRegs_SaveList;
118 return CSR_AArch64_RT_AllRegs_SaveList;
119
121 if (Darwin)
123 "Calling convention CFGuard_Check is unsupported on Darwin.");
124 return CSR_Win_AArch64_CFGuard_Check_SaveList;
125
127 if (Darwin)
128 return CSR_Darwin_AArch64_AAPCS_SwiftTail_SaveList;
129 if (Windows)
130 return CSR_Win_AArch64_AAPCS_SwiftTail_SaveList;
131 return CSR_AArch64_AAPCS_SwiftTail_SaveList;
132
134 if (Darwin)
135 return CSR_Darwin_AArch64_AAVPCS_SaveList;
136 if (Windows)
137 return CSR_Win_AArch64_AAVPCS_SaveList;
138 return CSR_AArch64_AAVPCS_SaveList;
139
141 if (Darwin)
143 "Calling convention SVE_VectorCall is unsupported on Darwin.");
144 if (Windows)
145 return CSR_Win_AArch64_SVE_AAPCS_SaveList;
146 return CSR_AArch64_SVE_AAPCS_SaveList;
147
150 "Calling convention "
151 "AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is only "
152 "supported to improve calls to SME ACLE save/restore/disable-za "
153 "functions, and is not intended to be used beyond that scope.");
154
157 "Calling convention "
158 "AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
159 "only supported to improve calls to SME ACLE __arm_get_current_vg "
160 "function, and is not intended to be used beyond that scope.");
161
164 "Calling convention "
165 "AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
166 "only supported to improve calls to SME ACLE __arm_sme_state "
167 "and is not intended to be used beyond that scope.");
168
170 if (Darwin)
171 return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
172 if (Windows)
173 return CSR_Win_AArch64_AAPCS_SaveList;
174 return CSR_AArch64_AAPCS_X18_SaveList;
175
177 if (Darwin)
178 return AFI.isSplitCSR() ? CSR_Darwin_AArch64_CXX_TLS_PE_SaveList
179 : CSR_Darwin_AArch64_CXX_TLS_SaveList;
180 // FIXME: this likely should be a `report_fatal_error` condition, however,
181 // that would be a departure from the previously implemented behaviour.
183
184 default:
185 if (Darwin)
186 return AFI.hasSVE_AAPCS(*MF) ? CSR_Darwin_AArch64_SVE_AAPCS_SaveList
187 : CSR_Darwin_AArch64_AAPCS_SaveList;
188 if (Windows)
189 return AFI.hasSVE_AAPCS(*MF) ? CSR_Win_AArch64_SVE_AAPCS_SaveList
190 : CSR_Win_AArch64_AAPCS_SaveList;
191 return AFI.hasSVE_AAPCS(*MF) ? CSR_AArch64_SVE_AAPCS_SaveList
192 : CSR_AArch64_AAPCS_SaveList;
193 }
194}
195
197 const MachineFunction *MF) const {
198 assert(MF && "Invalid MachineFunction pointer.");
201 return CSR_Darwin_AArch64_CXX_TLS_ViaCopy_SaveList;
202 return nullptr;
203}
204
206 MachineFunction &MF) const {
207 const MCPhysReg *CSRs = getCalleeSavedRegs(&MF);
208 SmallVector<MCPhysReg, 32> UpdatedCSRs;
209 for (const MCPhysReg *I = CSRs; *I; ++I)
210 UpdatedCSRs.push_back(*I);
211
212 for (size_t i = 0; i < AArch64::GPR64commonRegClass.getNumRegs(); ++i) {
214 UpdatedCSRs.push_back(AArch64::GPR64commonRegClass.getRegister(i));
215 }
216 }
217 // Register lists are zero-terminated.
218 UpdatedCSRs.push_back(0);
219 MF.getRegInfo().setCalleeSavedRegs(UpdatedCSRs);
220}
221
224 unsigned Idx) const {
225 // edge case for GPR/FPR register classes
226 if (RC == &AArch64::GPR32allRegClass && Idx == AArch64::hsub)
227 return &AArch64::FPR32RegClass;
228 else if (RC == &AArch64::GPR64allRegClass && Idx == AArch64::hsub)
229 return &AArch64::FPR64RegClass;
230
231 // Forward to TableGen's default version.
232 return AArch64GenRegisterInfo::getSubClassWithSubReg(RC, Idx);
233}
234
235const uint32_t *
237 CallingConv::ID CC) const {
239 "Invalid subtarget for getDarwinCallPreservedMask");
240
242 return CSR_Darwin_AArch64_CXX_TLS_RegMask;
244 return CSR_Darwin_AArch64_AAVPCS_RegMask;
246 return CSR_Darwin_AArch64_SVE_AAPCS_RegMask;
248 return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
250 return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1_RegMask;
252 return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2_RegMask;
255 "Calling convention CFGuard_Check is unsupported on Darwin.");
258 ->supportSwiftError() &&
259 MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError))
260 return CSR_Darwin_AArch64_AAPCS_SwiftError_RegMask;
261 if (CC == CallingConv::SwiftTail)
262 return CSR_Darwin_AArch64_AAPCS_SwiftTail_RegMask;
264 return CSR_Darwin_AArch64_RT_MostRegs_RegMask;
265 if (CC == CallingConv::PreserveAll)
266 return CSR_Darwin_AArch64_RT_AllRegs_RegMask;
267 return CSR_Darwin_AArch64_AAPCS_RegMask;
268}
269
270const uint32_t *
272 CallingConv::ID CC) const {
273 bool SCS = MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
274 if (CC == CallingConv::GHC)
275 // This is academic because all GHC calls are (supposed to be) tail calls
276 return SCS ? CSR_AArch64_NoRegs_SCS_RegMask : CSR_AArch64_NoRegs_RegMask;
278 return SCS ? CSR_AArch64_NoneRegs_SCS_RegMask
279 : CSR_AArch64_NoneRegs_RegMask;
280 if (CC == CallingConv::AnyReg)
281 return SCS ? CSR_AArch64_AllRegs_SCS_RegMask : CSR_AArch64_AllRegs_RegMask;
282
283 // All the following calling conventions are handled differently on Darwin.
285 if (SCS)
286 report_fatal_error("ShadowCallStack attribute not supported on Darwin.");
287 return getDarwinCallPreservedMask(MF, CC);
288 }
289
291 return SCS ? CSR_AArch64_AAVPCS_SCS_RegMask : CSR_AArch64_AAVPCS_RegMask;
293 return SCS ? CSR_AArch64_SVE_AAPCS_SCS_RegMask
294 : CSR_AArch64_SVE_AAPCS_RegMask;
296 return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
298 return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1_RegMask;
300 return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2_RegMask;
302 return CSR_Win_AArch64_CFGuard_Check_RegMask;
304 ->supportSwiftError() &&
305 MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError))
306 return SCS ? CSR_AArch64_AAPCS_SwiftError_SCS_RegMask
307 : CSR_AArch64_AAPCS_SwiftError_RegMask;
308 if (CC == CallingConv::SwiftTail) {
309 if (SCS)
310 report_fatal_error("ShadowCallStack attribute not supported with swifttail");
311 return CSR_AArch64_AAPCS_SwiftTail_RegMask;
312 }
314 return SCS ? CSR_AArch64_RT_MostRegs_SCS_RegMask
315 : CSR_AArch64_RT_MostRegs_RegMask;
316 if (CC == CallingConv::PreserveAll)
317 return SCS ? CSR_AArch64_RT_AllRegs_SCS_RegMask
318 : CSR_AArch64_RT_AllRegs_RegMask;
319
320 return SCS ? CSR_AArch64_AAPCS_SCS_RegMask : CSR_AArch64_AAPCS_RegMask;
321}
322
324 const MachineFunction &MF) const {
326 return CSR_AArch64_AAPCS_RegMask;
327
328 return nullptr;
329}
330
332 if (TT.isOSDarwin())
333 return CSR_Darwin_AArch64_TLS_RegMask;
334
335 assert(TT.isOSBinFormatELF() && "Invalid target");
336 return CSR_AArch64_TLS_ELF_RegMask;
337}
338
340 const uint32_t **Mask) const {
341 uint32_t *UpdatedMask = MF.allocateRegMask();
342 unsigned RegMaskSize = MachineOperand::getRegMaskSize(getNumRegs());
343 memcpy(UpdatedMask, *Mask, sizeof(UpdatedMask[0]) * RegMaskSize);
344
345 for (size_t i = 0; i < AArch64::GPR64commonRegClass.getNumRegs(); ++i) {
347 for (MCPhysReg SubReg :
348 subregs_inclusive(AArch64::GPR64commonRegClass.getRegister(i))) {
349 // See TargetRegisterInfo::getCallPreservedMask for how to interpret the
350 // register mask.
351 UpdatedMask[SubReg / 32] |= 1u << (SubReg % 32);
352 }
353 }
354 }
355 *Mask = UpdatedMask;
356}
357
359 return CSR_AArch64_SMStartStop_RegMask;
360}
361
362const uint32_t *
364 return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
365}
366
368 return CSR_AArch64_NoRegs_RegMask;
369}
370
371const uint32_t *
373 CallingConv::ID CC) const {
374 // This should return a register mask that is the same as that returned by
375 // getCallPreservedMask but that additionally preserves the register used for
376 // the first i64 argument (which must also be the register used to return a
377 // single i64 return value)
378 //
379 // In case that the calling convention does not use the same register for
380 // both, the function should return NULL (does not currently apply)
381 assert(CC != CallingConv::GHC && "should not be GHC calling convention.");
383 return CSR_Darwin_AArch64_AAPCS_ThisReturn_RegMask;
384 return CSR_AArch64_AAPCS_ThisReturn_RegMask;
385}
386
388 return CSR_AArch64_StackProbe_Windows_RegMask;
389}
390
391std::optional<std::string>
393 MCRegister PhysReg) const {
394 if (hasBasePointer(MF) && MCRegisterInfo::regsOverlap(PhysReg, AArch64::X19))
395 return std::string("X19 is used as the frame base pointer register.");
396
398 bool warn = false;
399 if (MCRegisterInfo::regsOverlap(PhysReg, AArch64::X13) ||
400 MCRegisterInfo::regsOverlap(PhysReg, AArch64::X14) ||
401 MCRegisterInfo::regsOverlap(PhysReg, AArch64::X23) ||
402 MCRegisterInfo::regsOverlap(PhysReg, AArch64::X24) ||
403 MCRegisterInfo::regsOverlap(PhysReg, AArch64::X28))
404 warn = true;
405
406 for (unsigned i = AArch64::B16; i <= AArch64::B31; ++i)
407 if (MCRegisterInfo::regsOverlap(PhysReg, i))
408 warn = true;
409
410 if (warn)
411 return std::string(AArch64InstPrinter::getRegisterName(PhysReg)) +
412 " is clobbered by asynchronous signals when using Arm64EC.";
413 }
414
415 return {};
416}
417
420 const AArch64FrameLowering *TFI = getFrameLowering(MF);
421
422 BitVector Reserved(getNumRegs());
423 markSuperRegs(Reserved, AArch64::WSP);
424 markSuperRegs(Reserved, AArch64::WZR);
425
426 if (TFI->isFPReserved(MF))
427 markSuperRegs(Reserved, AArch64::W29);
428
430 // x13, x14, x23, x24, x28, and v16-v31 are clobbered by asynchronous
431 // signals, so we can't ever use them.
432 markSuperRegs(Reserved, AArch64::W13);
433 markSuperRegs(Reserved, AArch64::W14);
434 markSuperRegs(Reserved, AArch64::W23);
435 markSuperRegs(Reserved, AArch64::W24);
436 markSuperRegs(Reserved, AArch64::W28);
437 for (unsigned i = AArch64::B16; i <= AArch64::B31; ++i)
438 markSuperRegs(Reserved, i);
439 }
440
441 if (MF.getSubtarget<AArch64Subtarget>().isLFI()) {
442 markSuperRegs(Reserved, AArch64::W28);
443 markSuperRegs(Reserved, AArch64::W27);
444 markSuperRegs(Reserved, AArch64::W26);
445 markSuperRegs(Reserved, AArch64::W25);
446 if (!MF.getProperties().hasNoVRegs()) {
447 markSuperRegs(Reserved, AArch64::LR);
448 markSuperRegs(Reserved, AArch64::W30);
449 }
450 }
451
452 for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
454 markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
455 }
456
457 if (hasBasePointer(MF))
458 markSuperRegs(Reserved, AArch64::W19);
459
460 // SLH uses register W16/X16 as the taint register.
461 if (MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening))
462 markSuperRegs(Reserved, AArch64::W16);
463
464 // FFR is modelled as global state that cannot be allocated.
465 if (MF.getSubtarget<AArch64Subtarget>().hasSVE())
466 Reserved.set(AArch64::FFR);
467
468 // SME tiles are not allocatable.
469 if (MF.getSubtarget<AArch64Subtarget>().hasSME()) {
470 for (MCPhysReg SubReg : subregs_inclusive(AArch64::ZA))
471 Reserved.set(SubReg);
472 }
473
474 // VG cannot be allocated
475 Reserved.set(AArch64::VG);
476
477 if (MF.getSubtarget<AArch64Subtarget>().hasSME2()) {
478 for (MCSubRegIterator SubReg(AArch64::ZT0, this, /*self=*/true);
479 SubReg.isValid(); ++SubReg)
480 Reserved.set(*SubReg);
481 }
482
483 markSuperRegs(Reserved, AArch64::FPCR);
484 markSuperRegs(Reserved, AArch64::FPMR);
485 markSuperRegs(Reserved, AArch64::FPSR);
486
488 markSuperRegs(Reserved, AArch64::X27);
489 markSuperRegs(Reserved, AArch64::X28);
490 markSuperRegs(Reserved, AArch64::W27);
491 markSuperRegs(Reserved, AArch64::W28);
492 }
493
494 assert(checkAllSuperRegsMarked(Reserved));
495
496 // Add _HI registers after checkAllSuperRegsMarked as this check otherwise
497 // becomes considerably more expensive.
498 Reserved.set(AArch64::WSP_HI);
499 Reserved.set(AArch64::WZR_HI);
500 static_assert(AArch64::W30_HI - AArch64::W0_HI == 30,
501 "Unexpected order of registers");
502 Reserved.set(AArch64::W0_HI, AArch64::W30_HI + 1);
503 static_assert(AArch64::B31_HI - AArch64::B0_HI == 31,
504 "Unexpected order of registers");
505 Reserved.set(AArch64::B0_HI, AArch64::B31_HI + 1);
506 static_assert(AArch64::H31_HI - AArch64::H0_HI == 31,
507 "Unexpected order of registers");
508 Reserved.set(AArch64::H0_HI, AArch64::H31_HI + 1);
509 static_assert(AArch64::S31_HI - AArch64::S0_HI == 31,
510 "Unexpected order of registers");
511 Reserved.set(AArch64::S0_HI, AArch64::S31_HI + 1);
512 static_assert(AArch64::D31_HI - AArch64::D0_HI == 31,
513 "Unexpected order of registers");
514 Reserved.set(AArch64::D0_HI, AArch64::D31_HI + 1);
515 static_assert(AArch64::Q31_HI - AArch64::Q0_HI == 31,
516 "Unexpected order of registers");
517 Reserved.set(AArch64::Q0_HI, AArch64::Q31_HI + 1);
518
519 return Reserved;
520}
521
524 BitVector Reserved(getNumRegs());
525 for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
526 // ReserveXRegister is set for registers manually reserved
527 // through +reserve-x#i.
529 markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
530 }
531 return Reserved;
532}
533
536 BitVector Reserved(getNumRegs());
537 for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
539 markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
540 }
541
543 // In order to prevent the register allocator from using LR, we need to
544 // mark it as reserved. However we don't want to keep it reserved throughout
545 // the pipeline since it prevents other infrastructure from reasoning about
546 // it's liveness. We use the NoVRegs property instead of IsSSA because
547 // IsSSA is removed before VirtRegRewriter runs.
548 if (!MF.getProperties().hasNoVRegs())
549 // Reserve LR (X30) by marking from its subregister W30 because otherwise
550 // the register allocator could clobber the subregister.
551 markSuperRegs(Reserved, AArch64::W30);
552 }
553
554 assert(checkAllSuperRegsMarked(Reserved));
555
556 // Handle strictlyReservedRegs separately to avoid re-evaluating the assert,
557 // which becomes considerably expensive when considering the _HI registers.
559
560 return Reserved;
561}
562
564 MCRegister Reg) const {
565 return getReservedRegs(MF)[Reg];
566}
567
569 MCRegister Reg) const {
570 return getUserReservedRegs(MF)[Reg];
571}
572
574 MCRegister Reg) const {
575 return getStrictlyReservedRegs(MF)[Reg];
576}
577
579 for (size_t i = 0; i < 8; ++i) {
581 return true;
582 }
583 return false;
584}
585
587 const MachineFunction &MF) const {
588 const Function &F = MF.getFunction();
589 F.getContext().diagnose(DiagnosticInfoUnsupported{F, ("AArch64 doesn't support"
590 " function calls if any of the argument registers is reserved.")});
591}
592
594 MCRegister PhysReg) const {
595 // SLH uses register X16 as the taint register but it will fallback to a different
596 // method if the user clobbers it. So X16 is not reserved for inline asm but is
597 // for normal codegen.
598 if (MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening) &&
599 MCRegisterInfo::regsOverlap(PhysReg, AArch64::X16))
600 return true;
601
602 // ZA/ZT0 registers are reserved but may be permitted in the clobber list.
603 if (PhysReg == AArch64::ZA || PhysReg == AArch64::ZT0)
604 return true;
605
606 return !isReservedReg(MF, PhysReg);
607}
608
611 if (RC == &AArch64::CCRRegClass)
612 return &AArch64::GPR64RegClass; // Only MSR & MRS copy NZCV.
613 return RC;
614}
615
616MCRegister AArch64RegisterInfo::getBaseRegister() const { return AArch64::X19; }
617
619 const MachineFrameInfo &MFI = MF.getFrameInfo();
620
621 // In the presence of variable sized objects or funclets, if the fixed stack
622 // size is large enough that referencing from the FP won't result in things
623 // being in range relatively often, we can use a base pointer to allow access
624 // from the other direction like the SP normally works.
625 //
626 // Furthermore, if both variable sized objects are present, and the
627 // stack needs to be dynamically re-aligned, the base pointer is the only
628 // reliable way to reference the locals.
629 if (MFI.hasVarSizedObjects() || MF.hasEHFunclets()) {
630 if (hasStackRealignment(MF))
631 return true;
632
633 auto &ST = MF.getSubtarget<AArch64Subtarget>();
635 if (ST.hasSVE() || ST.isStreaming()) {
636 // Frames that have variable sized objects and scalable SVE objects,
637 // should always use a basepointer.
638 if (!AFI->hasCalculatedStackSizeSVE() || AFI->hasSVEStackSize())
639 return true;
640 }
641
642 // Frames with hazard padding can have a large offset between the frame
643 // pointer and GPR locals, which includes the emergency spill slot. If the
644 // emergency spill slot is not within range of the load/store instructions
645 // (which have a signed 9-bit range), we will fail to compile if it is used.
646 // Since hasBasePointer() is called before we know if we have hazard padding
647 // or an emergency spill slot we need to enable the basepointer
648 // conservatively.
649 if (ST.getStreamingHazardSize() &&
650 !AFI->getSMEFnAttrs().hasNonStreamingInterfaceAndBody()) {
651 return true;
652 }
653
654 // Conservatively estimate whether the negative offset from the frame
655 // pointer will be sufficient to reach. If a function has a smallish
656 // frame, it's less likely to have lots of spills and callee saved
657 // space, so it's all more likely to be within range of the frame pointer.
658 // If it's wrong, we'll materialize the constant and still get to the
659 // object; it's just suboptimal. Negative offsets use the unscaled
660 // load/store instructions, which have a 9-bit signed immediate.
661 return MFI.getLocalFrameSize() >= 256;
662 }
663
664 return false;
665}
666
668 MCRegister Reg) const {
671 bool IsVarArg = STI.isCallingConvWin64(MF.getFunction().getCallingConv(),
672 MF.getFunction().isVarArg());
673
674 auto HasReg = [](ArrayRef<MCRegister> RegList, MCRegister Reg) {
675 return llvm::is_contained(RegList, Reg);
676 };
677
678 switch (CC) {
679 default:
680 report_fatal_error("Unsupported calling convention.");
681 case CallingConv::GHC:
682 return HasReg(CC_AArch64_GHC_ArgRegs, Reg);
684 if (!MF.getFunction().isVarArg())
685 return HasReg(CC_AArch64_Preserve_None_ArgRegs, Reg);
686 [[fallthrough]];
687 case CallingConv::C:
695 if (STI.isTargetWindowsOrUEFI()) {
696 if (IsVarArg)
697 return HasReg(CC_AArch64_Win64_VarArg_ArgRegs, Reg);
698 switch (CC) {
699 default:
700 return HasReg(CC_AArch64_Win64PCS_ArgRegs, Reg);
703 return HasReg(CC_AArch64_Win64PCS_Swift_ArgRegs, Reg) ||
704 HasReg(CC_AArch64_Win64PCS_ArgRegs, Reg);
705 }
706 }
707 if (!STI.isTargetDarwin()) {
708 switch (CC) {
709 default:
710 return HasReg(CC_AArch64_AAPCS_ArgRegs, Reg);
713 return HasReg(CC_AArch64_AAPCS_ArgRegs, Reg) ||
714 HasReg(CC_AArch64_AAPCS_Swift_ArgRegs, Reg);
715 }
716 }
717 if (!IsVarArg) {
718 switch (CC) {
719 default:
720 return HasReg(CC_AArch64_DarwinPCS_ArgRegs, Reg);
723 return HasReg(CC_AArch64_DarwinPCS_ArgRegs, Reg) ||
724 HasReg(CC_AArch64_DarwinPCS_Swift_ArgRegs, Reg);
725 }
726 }
727 if (STI.isTargetILP32())
728 return HasReg(CC_AArch64_DarwinPCS_ILP32_VarArg_ArgRegs, Reg);
729 return HasReg(CC_AArch64_DarwinPCS_VarArg_ArgRegs, Reg);
731 if (IsVarArg)
732 HasReg(CC_AArch64_Win64_VarArg_ArgRegs, Reg);
733 return HasReg(CC_AArch64_Win64PCS_ArgRegs, Reg);
735 return HasReg(CC_AArch64_Win64_CFGuard_Check_ArgRegs, Reg);
741 if (STI.isTargetWindowsOrUEFI())
742 return HasReg(CC_AArch64_Win64PCS_ArgRegs, Reg);
743 return HasReg(CC_AArch64_AAPCS_ArgRegs, Reg);
744 }
745}
746
749 const AArch64FrameLowering *TFI = getFrameLowering(MF);
750 return TFI->hasFP(MF) ? AArch64::FP : AArch64::SP;
751}
752
754 const MachineFunction &MF) const {
755 return true;
756}
757
762
763bool
765 // This function indicates whether the emergency spillslot should be placed
766 // close to the beginning of the stackframe (closer to FP) or the end
767 // (closer to SP).
768 //
769 // The beginning works most reliably if we have a frame pointer.
770 // In the presence of any non-constant space between FP and locals,
771 // (e.g. in case of stack realignment or a scalable SVE area), it is
772 // better to use SP or BP.
773 const AArch64FrameLowering &TFI = *getFrameLowering(MF);
775 assert((!MF.getSubtarget<AArch64Subtarget>().hasSVE() ||
777 "Expected SVE area to be calculated by this point");
778 return TFI.hasFP(MF) && !hasStackRealignment(MF) && !AFI->hasSVEStackSize() &&
780}
781
783 const MachineFunction &MF) const {
784 return true;
785}
786
787bool
789 const MachineFrameInfo &MFI = MF.getFrameInfo();
790 if (MF.disableFramePointerElim() && MFI.adjustsStack())
791 return true;
792 return MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken();
793}
794
795/// needsFrameBaseReg - Returns true if the instruction's frame index
796/// reference would be better served by a base register other than FP
797/// or SP. Used by LocalStackFrameAllocation to determine which frame index
798/// references it should create new base registers for.
800 int64_t Offset) const {
801 for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i)
802 assert(i < MI->getNumOperands() &&
803 "Instr doesn't have FrameIndex operand!");
804
805 // It's the load/store FI references that cause issues, as it can be difficult
806 // to materialize the offset if it won't fit in the literal field. Estimate
807 // based on the size of the local frame and some conservative assumptions
808 // about the rest of the stack frame (note, this is pre-regalloc, so
809 // we don't know everything for certain yet) whether this offset is likely
810 // to be out of range of the immediate. Return true if so.
811
812 // We only generate virtual base registers for loads and stores, so
813 // return false for everything else.
814 if (!MI->mayLoad() && !MI->mayStore())
815 return false;
816
817 // Without a virtual base register, if the function has variable sized
818 // objects, all fixed-size local references will be via the frame pointer,
819 // Approximate the offset and see if it's legal for the instruction.
820 // Note that the incoming offset is based on the SP value at function entry,
821 // so it'll be negative.
822 MachineFunction &MF = *MI->getParent()->getParent();
823 const AArch64FrameLowering *TFI = getFrameLowering(MF);
824 MachineFrameInfo &MFI = MF.getFrameInfo();
825
826 // Estimate an offset from the frame pointer.
827 // Conservatively assume all GPR callee-saved registers get pushed.
828 // FP, LR, X19-X28, D8-D15. 64-bits each.
829 int64_t FPOffset = Offset - 16 * 20;
830 // Estimate an offset from the stack pointer.
831 // The incoming offset is relating to the SP at the start of the function,
832 // but when we access the local it'll be relative to the SP after local
833 // allocation, so adjust our SP-relative offset by that allocation size.
834 Offset += MFI.getLocalFrameSize();
835 // Assume that we'll have at least some spill slots allocated.
836 // FIXME: This is a total SWAG number. We should run some statistics
837 // and pick a real one.
838 Offset += 128; // 128 bytes of spill slots
839
840 // If there is a frame pointer, try using it.
841 // The FP is only available if there is no dynamic realignment. We
842 // don't know for sure yet whether we'll need that, so we guess based
843 // on whether there are any local variables that would trigger it.
844 if (TFI->hasFP(MF) && isFrameOffsetLegal(MI, AArch64::FP, FPOffset))
845 return false;
846
847 // If we can reference via the stack pointer or base pointer, try that.
848 // FIXME: This (and the code that resolves the references) can be improved
849 // to only disallow SP relative references in the live range of
850 // the VLA(s). In practice, it's unclear how much difference that
851 // would make, but it may be worth doing.
852 if (isFrameOffsetLegal(MI, AArch64::SP, Offset))
853 return false;
854
855 // If even offset 0 is illegal, we don't want a virtual base register.
856 if (!isFrameOffsetLegal(MI, AArch64::SP, 0))
857 return false;
858
859 // The offset likely isn't legal; we want to allocate a virtual base register.
860 return true;
861}
862
864 Register BaseReg,
865 int64_t Offset) const {
866 assert(MI && "Unable to get the legal offset for nil instruction.");
869}
870
871/// Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx
872/// at the beginning of the basic block.
875 int FrameIdx,
876 int64_t Offset) const {
877 MachineBasicBlock::iterator Ins = MBB->begin();
878 DebugLoc DL; // Defaults to "unknown"
879 if (Ins != MBB->end())
880 DL = Ins->getDebugLoc();
881 const MachineFunction &MF = *MBB->getParent();
882 const AArch64InstrInfo *TII =
883 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
884 const MCInstrDesc &MCID = TII->get(AArch64::ADDXri);
885 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
886 Register BaseReg = MRI.createVirtualRegister(&AArch64::GPR64spRegClass);
887 MRI.constrainRegClass(BaseReg, TII->getRegClass(MCID, 0));
888 unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0);
889
890 BuildMI(*MBB, Ins, DL, MCID, BaseReg)
891 .addFrameIndex(FrameIdx)
892 .addImm(Offset)
893 .addImm(Shifter);
894
895 return BaseReg;
896}
897
899 int64_t Offset) const {
900 // ARM doesn't need the general 64-bit offsets
902
903 unsigned i = 0;
904 while (!MI.getOperand(i).isFI()) {
905 ++i;
906 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
907 }
908
909 const MachineFunction *MF = MI.getParent()->getParent();
910 const AArch64InstrInfo *TII =
911 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
912 bool Done = rewriteAArch64FrameIndex(MI, i, BaseReg, Off, TII);
913 assert(Done && "Unable to resolve frame index!");
914 (void)Done;
915}
916
917// Create a scratch register for the frame index elimination in an instruction.
918// This function has special handling of stack tagging loop pseudos, in which
919// case it can also change the instruction opcode.
920static Register
922 const AArch64InstrInfo *TII) {
923 // ST*Gloop have a reserved scratch register in operand 1. Use it, and also
924 // replace the instruction with the writeback variant because it will now
925 // satisfy the operand constraints for it.
926 Register ScratchReg;
927 if (MI.getOpcode() == AArch64::STGloop ||
928 MI.getOpcode() == AArch64::STZGloop) {
929 assert(FIOperandNum == 3 &&
930 "Wrong frame index operand for STGloop/STZGloop");
931 unsigned Op = MI.getOpcode() == AArch64::STGloop ? AArch64::STGloop_wback
932 : AArch64::STZGloop_wback;
933 ScratchReg = MI.getOperand(1).getReg();
934 MI.getOperand(3).ChangeToRegister(ScratchReg, false, false, true);
935 MI.setDesc(TII->get(Op));
936 MI.tieOperands(1, 3);
937 } else {
938 ScratchReg =
939 MI.getMF()->getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
940 MI.getOperand(FIOperandNum)
941 .ChangeToRegister(ScratchReg, false, false, true);
942 }
943 return ScratchReg;
944}
945
948 // The smallest scalable element supported by scaled SVE addressing
949 // modes are predicates, which are 2 scalable bytes in size. So the scalable
950 // byte offset must always be a multiple of 2.
951 assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
952
953 // Add fixed-sized offset using existing DIExpression interface.
955
956 unsigned VG = getDwarfRegNum(AArch64::VG, true);
957 int64_t VGSized = Offset.getScalable() / 2;
958 if (VGSized > 0) {
959 Ops.push_back(dwarf::DW_OP_constu);
960 Ops.push_back(VGSized);
961 Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
962 Ops.push_back(dwarf::DW_OP_mul);
963 Ops.push_back(dwarf::DW_OP_plus);
964 } else if (VGSized < 0) {
965 Ops.push_back(dwarf::DW_OP_constu);
966 Ops.push_back(-VGSized);
967 Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
968 Ops.push_back(dwarf::DW_OP_mul);
969 Ops.push_back(dwarf::DW_OP_minus);
970 }
971}
972
974 int SPAdj, unsigned FIOperandNum,
975 RegScavenger *RS) const {
976 assert(SPAdj == 0 && "Unexpected");
977
978 MachineInstr &MI = *II;
979 MachineBasicBlock &MBB = *MI.getParent();
980 MachineFunction &MF = *MBB.getParent();
981 const MachineFrameInfo &MFI = MF.getFrameInfo();
982 const AArch64InstrInfo *TII =
983 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
984 const AArch64FrameLowering *TFI = getFrameLowering(MF);
985 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
986 bool Tagged =
987 MI.getOperand(FIOperandNum).getTargetFlags() & AArch64II::MO_TAGGED;
988 Register FrameReg;
989
990 // Special handling of dbg_value, stackmap patchpoint statepoint instructions.
991 if (MI.getOpcode() == TargetOpcode::STACKMAP ||
992 MI.getOpcode() == TargetOpcode::PATCHPOINT ||
993 MI.getOpcode() == TargetOpcode::STATEPOINT) {
995 TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg,
996 /*PreferFP=*/true,
997 /*ForSimm=*/false);
998 Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
999 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
1000 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
1001 return false;
1002 }
1003
1004 if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) {
1005 MachineOperand &FI = MI.getOperand(FIOperandNum);
1006 StackOffset Offset = TFI->getNonLocalFrameIndexReference(MF, FrameIndex);
1007 assert(!Offset.getScalable() &&
1008 "Frame offsets with a scalable component are not supported");
1009 FI.ChangeToImmediate(Offset.getFixed());
1010 return false;
1011 }
1012
1014 if (MI.getOpcode() == AArch64::TAGPstack) {
1015 // TAGPstack must use the virtual frame register in its 3rd operand.
1017 FrameReg = MI.getOperand(3).getReg();
1018 Offset = StackOffset::getFixed(MFI.getObjectOffset(FrameIndex) +
1020 } else if (Tagged) {
1022 MFI.getObjectOffset(FrameIndex) + (int64_t)MFI.getStackSize());
1023 if (MFI.hasVarSizedObjects() ||
1024 isAArch64FrameOffsetLegal(MI, SPOffset, nullptr, nullptr, nullptr) !=
1026 // Can't update to SP + offset in place. Precalculate the tagged pointer
1027 // in a scratch register.
1029 MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
1030 Register ScratchReg =
1031 MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
1032 emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset,
1033 TII);
1034 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(AArch64::LDG), ScratchReg)
1035 .addReg(ScratchReg)
1036 .addReg(ScratchReg)
1037 .addImm(0);
1038 MI.getOperand(FIOperandNum)
1039 .ChangeToRegister(ScratchReg, false, false, true);
1040 return false;
1041 }
1042 FrameReg = AArch64::SP;
1043 Offset = StackOffset::getFixed(MFI.getObjectOffset(FrameIndex) +
1044 (int64_t)MFI.getStackSize());
1045 } else {
1047 MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
1048 }
1049
1050 // Modify MI as necessary to handle as much of 'Offset' as possible
1051 if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
1052 return true;
1053
1054 assert((!RS || !RS->isScavengingFrameIndex(FrameIndex)) &&
1055 "Emergency spill slot is out of reach");
1056
1057 // If we get here, the immediate doesn't fit into the instruction. We folded
1058 // as much as possible above. Handle the rest, providing a register that is
1059 // SP+LargeImm.
1060 Register ScratchReg =
1062 emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset, TII);
1063 return false;
1064}
1065
1067 MachineFunction &MF) const {
1068 const AArch64FrameLowering *TFI = getFrameLowering(MF);
1069
1070 switch (RC->getID()) {
1071 default:
1072 return 0;
1073 case AArch64::GPR32RegClassID:
1074 case AArch64::GPR32spRegClassID:
1075 case AArch64::GPR32allRegClassID:
1076 case AArch64::GPR64spRegClassID:
1077 case AArch64::GPR64allRegClassID:
1078 case AArch64::GPR64RegClassID:
1079 case AArch64::GPR32commonRegClassID:
1080 case AArch64::GPR64commonRegClassID:
1081 return 32 - 1 // XZR/SP
1082 - (TFI->hasFP(MF) || TT.isOSDarwin()) // FP
1083 - MF.getSubtarget<AArch64Subtarget>().getNumXRegisterReserved()
1084 - hasBasePointer(MF); // X19
1085 case AArch64::FPR8RegClassID:
1086 case AArch64::FPR16RegClassID:
1087 case AArch64::FPR32RegClassID:
1088 case AArch64::FPR64RegClassID:
1089 case AArch64::FPR128RegClassID:
1090 return 32;
1091
1092 case AArch64::MatrixIndexGPR32_8_11RegClassID:
1093 case AArch64::MatrixIndexGPR32_12_15RegClassID:
1094 return 4;
1095
1096 case AArch64::DDRegClassID:
1097 case AArch64::DDDRegClassID:
1098 case AArch64::DDDDRegClassID:
1099 case AArch64::QQRegClassID:
1100 case AArch64::QQQRegClassID:
1101 case AArch64::QQQQRegClassID:
1102 return 32;
1103
1104 case AArch64::FPR128_loRegClassID:
1105 case AArch64::FPR64_loRegClassID:
1106 case AArch64::FPR16_loRegClassID:
1107 return 16;
1108 case AArch64::FPR128_0to7RegClassID:
1109 return 8;
1110 }
1111}
1112
1114 Register VirtReg, ArrayRef<MCPhysReg> Order,
1115 SmallSetVector<MCPhysReg, 16> &Hints, const VirtRegMap *VRM,
1116 const MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
1117 const AArch64Subtarget &ST, const LiveRegMatrix *Matrix) {
1118 const TargetRegisterClass *RegRC = MRI.getRegClass(VirtReg);
1119 if (!ST.useDistinctPredicateDstReg() ||
1120 !AArch64::PPRRegClass.hasSubClassEq(RegRC) || !MRI.hasOneDef(VirtReg) ||
1121 Order.size() < 2)
1122 return false;
1123
1124 const MachineInstr *DefInst = MRI.getOneDef(VirtReg)->getParent();
1125 if ((TII.get(DefInst->getOpcode()).TSFlags &
1127 return false;
1128
1129 Register Op1Reg = DefInst->getOperand(1).getReg();
1130 if (Op1Reg.isVirtual())
1131 Op1Reg = VRM->getPhys(Op1Reg);
1132
1133 // If no register is allocated for the general-predicate, it's not yet
1134 // possible to choose a distinct register.
1135 if (!Op1Reg.isValid())
1136 return false;
1137
1138 // Move Op1Reg as the least preferred register.
1139 //
1140 // This might result in callee-save spills when the function takes/returns
1141 // arguments in SVE registers (i.e. needs to preserve p4-p15) and can't reuse
1142 // p0-p3. That's why we limit it to non-callee saved registers or to
1143 // callee-saved registers that have already been allocated for other uses in
1144 // the function.
1145 DenseSet<unsigned> CSRs;
1146 for (unsigned I = 0;; ++I) {
1147 Register R = MRI.getCalleeSavedRegs()[I];
1148 if (!R.isValid())
1149 break;
1150 if (AArch64::PPRRegClass.contains(R))
1151 CSRs.insert(R);
1152 }
1153
1154 Hints.insert_range(Order);
1155 auto CanUseReg = [&](Register R) {
1156 return !CSRs.contains(R) || !MRI.def_empty(R) || Matrix->isPhysRegUsed(R);
1157 };
1158 SmallVector<MCPhysReg, 16> SortedHints = Hints.takeVector();
1159 llvm::stable_sort(SortedHints, [&](Register A, Register B) {
1160 bool PrefA = (A != Op1Reg) && CanUseReg(A);
1161 bool PrefB = (B != Op1Reg) && CanUseReg(B);
1162 return PrefA && !PrefB;
1163 });
1164 Hints.insert_range(SortedHints);
1165 return true;
1166}
1167
1168// We add regalloc hints for different cases:
1169// * Choosing a better destination operand for predicated SVE instructions
1170// where the inactive lanes are undef, by choosing a register that is not
1171// unique to the other operands of the instruction.
1172//
1173// * Improve register allocation for SME multi-vector instructions where we can
1174// benefit from the strided- and contiguous register multi-vector tuples.
1175//
1176// Here COPY_INTO_TRANSPOSED_TUPLE nodes are created to improve register
1177// allocation where a consecutive multi-vector tuple is constructed from the
1178// same indices of multiple strided loads. This may still result in
1179// unnecessary copies between the loads and the tuple. Here we try to return a
1180// hint to assign the contiguous ZPRMulReg starting at the same register as
1181// the first operand of the pseudo, which should be a subregister of the first
1182// strided load.
1183//
1184// For example, if the first strided load has been assigned $z16_z20_z24_z28
1185// and the operands of the pseudo are each accessing subregister zsub2, we
1186// should look through through Order to find a contiguous register which
1187// begins with $z24 (i.e. $z24_z25_z26_z27).
1189 Register VirtReg, ArrayRef<MCPhysReg> Order,
1191 const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
1192 auto &ST = MF.getSubtarget<AArch64Subtarget>();
1193 const AArch64InstrInfo *TII =
1194 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
1195 const MachineRegisterInfo &MRI = MF.getRegInfo();
1196
1197 bool ConsiderOnlyHints =
1198 TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);
1199
1200 // For predicated SVE instructions where the inactive lanes are undef,
1201 // pick a destination register that is not unique to avoid introducing
1202 // a movprfx.
1203 const TargetRegisterClass *RegRC = MRI.getRegClass(VirtReg);
1204 if (AArch64::ZPRRegClass.hasSubClassEq(RegRC)) {
1205 for (const MachineOperand &DefOp : MRI.def_operands(VirtReg)) {
1206 const MachineInstr &Def = *DefOp.getParent();
1207 if (DefOp.isImplicit() ||
1208 (TII->get(Def.getOpcode()).TSFlags & AArch64::FalseLanesMask) !=
1210 continue;
1211
1212 unsigned InstFlags =
1213 TII->get(AArch64::getSVEPseudoMap(Def.getOpcode())).TSFlags;
1214
1215 for (MCPhysReg R : Order) {
1216 auto AddHintIfSuitable = [&](MCPhysReg R,
1217 const MachineOperand &MO) -> bool {
1218 // R is a suitable register hint if R can reuse one of the other
1219 // source operands.
1220 MCPhysReg PhysReg = VRM->getPhys(MO.getReg());
1221 if (PhysReg && MO.getSubReg())
1222 PhysReg = getSubReg(PhysReg, MO.getSubReg());
1223 if (PhysReg != R)
1224 return false;
1225 Hints.insert(R);
1226 return true;
1227 };
1228
1229 switch (InstFlags & AArch64::DestructiveInstTypeMask) {
1230 default:
1231 break;
1233 AddHintIfSuitable(R, Def.getOperand(2)) ||
1234 AddHintIfSuitable(R, Def.getOperand(3)) ||
1235 AddHintIfSuitable(R, Def.getOperand(4));
1236 break;
1239 AddHintIfSuitable(R, Def.getOperand(2)) ||
1240 AddHintIfSuitable(R, Def.getOperand(3));
1241 break;
1244 AddHintIfSuitable(R, Def.getOperand(2));
1245 break;
1247 AddHintIfSuitable(R, Def.getOperand(3));
1248 break;
1251 AddHintIfSuitable(R, Def.getOperand(1));
1252 break;
1253 }
1254 }
1255 }
1256
1257 if (Hints.size())
1258 return ConsiderOnlyHints;
1259 }
1260
1261 if (HandleDestructivePredicateHint(VirtReg, Order, Hints, VRM, MRI, *TII, ST,
1262 Matrix))
1263 return ConsiderOnlyHints;
1264
1265 if (!ST.hasSME() || !ST.isStreaming())
1266 return ConsiderOnlyHints;
1267
1268 // The SVE calling convention preserves registers Z8-Z23. As a result, there
1269 // are no ZPR2Strided or ZPR4Strided registers that do not overlap with the
1270 // callee-saved registers and so by default these will be pushed to the back
1271 // of the allocation order for the ZPRStridedOrContiguous classes.
1272 // If any of the instructions which define VirtReg are used by the
1273 // COPY_INTO_TRANSPOSED_TUPLE pseudos, we want to favour reducing copy
1274 // instructions over reducing the number of clobbered callee-save registers,
1275 // so we add the strided registers as a hint.
1276 unsigned RegID = RegRC->getID();
1277 if (RegID == AArch64::ZPR2StridedOrContiguousRegClassID ||
1278 RegID == AArch64::ZPR4StridedOrContiguousRegClassID) {
1279
1280 // Look through uses of the register for COPY_INTO_TRANSPOSED_TUPLE.
1281 for (const MachineInstr &Use : MRI.use_nodbg_instructions(VirtReg)) {
1282 if (Use.getOpcode() != AArch64::COPY_INTO_TRANSPOSED_TUPLE)
1283 continue;
1284
1285 const MachineOperand &Src = Use.getOperand(1);
1286 const MachineOperand &Dst = Use.getOperand(0);
1287
1288 if (!Src.getSubReg() || !Dst.getSubReg())
1289 continue;
1290
1291 const TargetRegisterClass *StridedRC;
1292 switch (RegID) {
1293 case AArch64::ZPR2StridedOrContiguousRegClassID:
1294 StridedRC = &AArch64::ZPR2StridedRegClass;
1295 break;
1296 case AArch64::ZPR4StridedOrContiguousRegClassID:
1297 StridedRC = &AArch64::ZPR4StridedRegClass;
1298 break;
1299 default:
1300 llvm_unreachable("Unexpected RegID");
1301 }
1302
1303 SmallVector<MCPhysReg, 4> StridedOrder;
1304 for (MCPhysReg Reg : Order)
1305 if (StridedRC->contains(Reg))
1306 StridedOrder.push_back(Reg);
1307
1308 unsigned TupleSize = Use.getOperand(2).getImm();
1309 unsigned TupIdx = Dst.getSubReg() - AArch64::zsub0;
1310
1311 unsigned TupleID = MRI.getRegClass(Dst.getReg())->getID();
1312 bool IsMulZPR = TupleID == AArch64::ZPR2Mul2RegClassID ||
1313 TupleID == AArch64::ZPR4Mul4RegClassID;
1314
1315 iterator_range Copies = MRI.def_instructions(Dst.getReg());
1316 MachineRegisterInfo::def_instr_iterator CopyWithAssignedSrc =
1317 llvm::find_if(Copies, [&](const MachineInstr &Def) {
1318 auto &Src = Def.getOperand(1);
1319 return Def.getOpcode() == Use.getOpcode() &&
1320 VRM->hasPhys(Src.getReg());
1321 });
1322
1323 // Example:
1324 //
1325 // When trying to find a suitable register allocation for VirtReg %v2 in:
1326 //
1327 // %v0:zpr2stridedorcontiguous = ld1 p0/z, [...]
1328 // %v1:zpr2stridedorcontiguous = ld1 p0/z, [...]
1329 // %v2:zpr2stridedorcontiguous = ld1 p0/z, [...]
1330 // %v3:zpr2stridedorcontiguous = ld1 p0/z, [...]
1331 // %v4.zsub0:zpr4mul4 = COPY_INTO_TRANSPOSED_TUPLE %v0:0
1332 // %v4.zsub1:zpr4mul4 = COPY_INTO_TRANSPOSED_TUPLE %v1:0
1333 // %v4.zsub2:zpr4mul4 = COPY_INTO_TRANSPOSED_TUPLE %v2:0
1334 // %v4.zsub3:zpr4mul4 = COPY_INTO_TRANSPOSED_TUPLE %v3:0
1335 //
1336 // One such suitable allocation would be:
1337 //
1338 // { z0, z8 } = ld1 p0/z, [...]
1339 // { z1, z9 } = ld1 p0/z, [...]
1340 // { z2, z10 } = ld1 p0/z, [...]
1341 // { z3, z11 } = ld1 p0/z, [...]
1342 // z0 = COPY_INTO_TRANSPOSED_TUPLE {z0, z8}:0
1343 // z1 = COPY_INTO_TRANSPOSED_TUPLE {z1, z9}:0
1344 // z2 = COPY_INTO_TRANSPOSED_TUPLE {z2, z10}:0
1345 // z3 = COPY_INTO_TRANSPOSED_TUPLE {z3, z11}:0
1346 //
1347 // Below we distinguish two cases when trying to find a register:
1348 // * None of the sources of the copies have been assigned a register yet.
1349 // In this case the code must ensure that there are at least TupleSize
1350 // free consecutive registers. If IsMulZPR is true, then the first of
1351 // registers must also be a multiple of TupleSize, e.g.
1352 // { z0, z1, z2, z3 } is valid but { z1, z2, z3, z5 } is not.
1353 // * One or more copies already have registers assigned to their sources,
1354 // which means only checking that a consecutive range of free tuple
1355 // registers exists which includes the assigned register.
1356 // e.g. in the example above, if { z0, z8 } is already allocated for
1357 // %v0, we just need to ensure that { z1, z9 }, { z2, z10 } and
1358 // { z3, z11 } are also free. If so, we add { z2, z10 }.
1359
1360 if (CopyWithAssignedSrc == Copies.end()) {
1361 // There are no registers already assigned to any of the pseudo
1362 // operands. Look for a valid starting register for the group.
1363 for (unsigned I = 0; I < StridedOrder.size(); ++I) {
1364 MCPhysReg Reg = StridedOrder[I];
1365
1366 // If the COPY_INTO_TRANSPOSED_TUPLE nodes use the ZPRMul classes, the
1367 // starting register of the first load should be a multiple of 2 or 4.
1368 unsigned SubRegIdx = Src.getSubReg();
1369 if (IsMulZPR &&
1370 (getSubReg(Reg, SubRegIdx) - AArch64::Z0) % TupleSize != TupIdx)
1371 continue;
1372
1373 // In the example above, if VirtReg is the third operand of the
1374 // tuple (%v2) and Reg == Z2_Z10, then we need to make sure that
1375 // Z0_Z8, Z1_Z9 and Z3_Z11 are also available.
1376 auto IsFreeConsecutiveReg = [&](unsigned I) {
1377 unsigned R = Reg - TupIdx + I;
1378 return StridedRC->contains(R) &&
1379 (I == 0 ||
1380 ((getSubReg(R, AArch64::zsub0) - AArch64::Z0) ==
1381 (getSubReg(R - 1, AArch64::zsub0) - AArch64::Z0) + 1)) &&
1382 !Matrix->isPhysRegUsed(R);
1383 };
1384 if (all_of(seq(0U, TupleSize), IsFreeConsecutiveReg))
1385 Hints.insert(Reg);
1386 }
1387 } else {
1388 // At least copy already has a physical register assigned to its source.
1389 // Find the starting sub-register of this and use it to work out the
1390 // correct strided register to suggest based on the current op index.
1391 MachineOperand &AssignedSrc = CopyWithAssignedSrc->getOperand(1);
1392 MachineOperand &AssignedDst = CopyWithAssignedSrc->getOperand(0);
1393
1394 if (!AssignedSrc.getSubReg() || !AssignedDst.getSubReg())
1395 continue;
1396
1397 unsigned AssignedTupIdx = AssignedDst.getSubReg() - AArch64::zsub0;
1398 MCPhysReg TargetStartReg =
1399 getSubReg(VRM->getPhys(AssignedSrc.getReg()), AArch64::zsub0) +
1400 (TupIdx - AssignedTupIdx);
1401
1402 for (unsigned I = 0; I < StridedOrder.size(); ++I)
1403 if (getSubReg(StridedOrder[I], AArch64::zsub0) == TargetStartReg)
1404 Hints.insert(StridedOrder[I]);
1405 }
1406
1407 if (!Hints.empty())
1408 return ConsiderOnlyHints;
1409 }
1410 }
1411
1412 for (auto &Def : MRI.def_instructions(VirtReg)) {
1413 if (Def.getOpcode() != AArch64::COPY_INTO_TRANSPOSED_TUPLE)
1414 continue;
1415
1416 MachineOperand &Src = Def.getOperand(1);
1417 MachineOperand &Dst = Def.getOperand(0);
1418
1419 if (!Src.getSubReg() || !Dst.getSubReg())
1420 continue;
1421
1422 // FIXME: This is fragile. If we allocate a register to the Dst before Src,
1423 // our hints are won't have any effect... This is currently mitigated by
1424 // by trying to schedule copies immediately before their uses. This gives
1425 // them a short live range (so they're low priority to allocate).
1426 if (!VRM->hasPhys(Src.getReg()))
1427 continue;
1428
1429 // Find the ZPR register mapped to the source of the copy.
1430 MCPhysReg SrcZPR = getSubReg(VRM->getPhys(Src.getReg()), Src.getSubReg());
1431
1432 // Try to pick a tuple register for Dst with Src as a member.
1433 for (MCPhysReg R : Order) {
1434 if (getSubReg(R, Dst.getSubReg()) == SrcZPR)
1435 Hints.insert(R);
1436 }
1437 }
1438
1439 return ConsiderOnlyHints;
1440}
1441
1443 const MachineFunction &MF) const {
1444 const auto &MFI = MF.getFrameInfo();
1445 if (!MF.hasEHFunclets() && !MFI.hasVarSizedObjects())
1446 return AArch64::SP;
1447 else if (hasStackRealignment(MF))
1448 return getBaseRegister();
1449 return getFrameRegister(MF);
1450}
1451
1452/// SrcRC and DstRC will be morphed into NewRC if this returns true
1454 MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
1455 const TargetRegisterClass *DstRC, unsigned DstSubReg,
1456 const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
1457 MachineFunction &MF = *MI->getMF();
1458 MachineRegisterInfo &MRI = MF.getRegInfo();
1459
1460 if (MI->isSubregToReg() && MRI.subRegLivenessEnabled() &&
1462 return false;
1463
1464 if (MI->isCopy() &&
1465 ((DstRC->getID() == AArch64::GPR64RegClassID) ||
1466 (DstRC->getID() == AArch64::GPR64commonRegClassID)) &&
1467 MI->getOperand(0).getSubReg() && MI->getOperand(1).getSubReg())
1468 // Do not coalesce in the case of a 32-bit subregister copy
1469 // which implements a 32 to 64 bit zero extension
1470 // which relies on the upper 32 bits being zeroed.
1471 return false;
1472
1473 auto IsCoalescerBarrier = [](const MachineInstr &MI) {
1474 switch (MI.getOpcode()) {
1475 case AArch64::COALESCER_BARRIER_FPR16:
1476 case AArch64::COALESCER_BARRIER_FPR32:
1477 case AArch64::COALESCER_BARRIER_FPR64:
1478 case AArch64::COALESCER_BARRIER_FPR128:
1479 return true;
1480 default:
1481 return false;
1482 }
1483 };
1484
1485 // For calls that temporarily have to toggle streaming mode as part of the
1486 // call-sequence, we need to be more careful when coalescing copy instructions
1487 // so that we don't end up coalescing the NEON/FP result or argument register
1488 // with a whole Z-register, such that after coalescing the register allocator
1489 // will try to spill/reload the entire Z register.
1490 //
1491 // We do this by checking if the node has any defs/uses that are
1492 // COALESCER_BARRIER pseudos. These are 'nops' in practice, but they exist to
1493 // instruct the coalescer to avoid coalescing the copy.
1494 if (MI->isCopy() && SubReg != DstSubReg &&
1495 (AArch64::ZPRRegClass.hasSubClassEq(DstRC) ||
1496 AArch64::ZPRRegClass.hasSubClassEq(SrcRC))) {
1497 unsigned SrcReg = MI->getOperand(1).getReg();
1498 if (any_of(MRI.def_instructions(SrcReg), IsCoalescerBarrier))
1499 return false;
1500 unsigned DstReg = MI->getOperand(0).getReg();
1501 if (any_of(MRI.use_nodbg_instructions(DstReg), IsCoalescerBarrier))
1502 return false;
1503 }
1504
1505 return true;
1506}
1507
1509 MCRegister R) const {
1510 return R == AArch64::VG;
1511}
1512
1514 return (LLVMReg >= AArch64::Z0 && LLVMReg <= AArch64::Z31) ||
1515 (LLVMReg >= AArch64::P0 && LLVMReg <= AArch64::P15);
1516}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool HandleDestructivePredicateHint(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallSetVector< MCPhysReg, 16 > &Hints, const VirtRegMap *VRM, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const AArch64Subtarget &ST, const LiveRegMatrix *Matrix)
static Register createScratchRegisterForInstruction(MachineInstr &MI, unsigned FIOperandNum, const AArch64InstrInfo *TII)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition Compiler.h:425
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Live Register Matrix
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
This file declares the machine register scavenger class.
SI Lower i1 Copies
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
static unsigned getDwarfRegNum(MCRegister Reg, const TargetRegisterInfo *TRI)
Go up the super-register chain until we hit a valid dwarf register number.
StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const override
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
bool isFPReserved(const MachineFunction &MF) const
Should the Frame Pointer be reserved for the current function?
StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP, bool ForSimm) const
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
BitVector getStrictlyReservedRegs(const MachineFunction &MF) const
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned' is on...
bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
bool isIgnoredCVReg(MCRegister LLVMReg) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override
SrcRC and DstRC will be morphed into NewRC if this returns true.
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
bool isUserReservedReg(const MachineFunction &MF, MCRegister Reg) const
const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const override
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx at the beginning of the basic ...
void UpdateCustomCalleeSavedRegs(MachineFunction &MF) const
bool requiresRegisterScavenging(const MachineFunction &MF) const override
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
BitVector getUserReservedRegs(const MachineFunction &MF) const
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
needsFrameBaseReg - Returns true if the instruction's frame index reference would be better served by...
const uint32_t * getWindowsStackProbePreservedMask() const
Stack probing calls preserve different CSRs to the normal CC.
bool regNeedsCFI(MCRegister Reg, MCRegister &RegToUseForCFI) const
Return whether the register needs a CFI entry.
bool isAnyArgRegReserved(const MachineFunction &MF) const
void emitReservedArgRegCallError(const MachineFunction &MF) const
bool isStrictlyReservedReg(const MachineFunction &MF, MCRegister Reg) const
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
const uint32_t * getTLSCallPreservedMask() const
const uint32_t * getNoPreservedMask() const override
Register getFrameRegister(const MachineFunction &MF) const override
bool shouldAnalyzePhysregInMachineLoopInfo(MCRegister R) const override
void getOffsetOpcodes(const StackOffset &Offset, SmallVectorImpl< uint64_t > &Ops) const override
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
AArch64RegisterInfo(const Triple &TT, unsigned HwMode)
const uint32_t * SMEABISupportRoutinesCallPreservedMaskFromX0() const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const uint32_t * getCustomEHPadPreservedMask(const MachineFunction &MF) const override
unsigned getLocalAddressRegister(const MachineFunction &MF) const
bool hasBasePointer(const MachineFunction &MF) const
const uint32_t * getDarwinCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const
const uint32_t * getSMStartStopCallPreservedMask() const
bool useFPForScavengingIndex(const MachineFunction &MF) const override
bool cannotEliminateFrame(const MachineFunction &MF) const
bool isArgumentRegister(const MachineFunction &MF, MCRegister Reg) const override
void UpdateCustomCallPreservedMask(MachineFunction &MF, const uint32_t **Mask) const
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallSetVector< MCPhysReg, 16 > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
std::optional< std::string > explainReservedReg(const MachineFunction &MF, MCRegister PhysReg) const override
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
bool enableSRLTSubregToRegMitigation() const
bool isXRegisterReservedForRA(size_t i) const
const AArch64TargetLowering * getTargetLowering() const override
bool isXRegCustomCalleeSaved(size_t i) const
bool isTargetWindowsOrUEFI() const
UEFI follows the Windows ARM64 ABI and produces PE/COFF images, so most of the Windows specific ABI h...
bool isXRegisterReserved(size_t i) const
bool isCallingConvWin64(CallingConv::ID CC, bool IsVarArg) const
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
static LLVM_ABI void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
A debug info location.
Definition DebugLoc.h:126
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Diagnostic information for unsupported feature in backend.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:273
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
Describe properties that are true of each instruction in the target description file.
unsigned getID() const
getID() - Return the register class ID number.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
MCSubRegIterator enumerates all sub-registers of Reg.
bool isValid() const
Returns true if this iterator is not yet at the end.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
int64_t getLocalFrameSize() const
Get the size of the local object blob.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
uint32_t * allocateRegMask()
Allocate and initialize a register mask with NumRegister bits.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< def_instr_iterator > def_instructions(Register Reg) const
MachineOperand * getOneDef(Register Reg) const
Returns the defining operand if there is exactly one operand defining the specified register,...
defusechain_instr_iterator< false, true, false, true > def_instr_iterator
def_instr_iterator/def_instr_begin/def_instr_end - Walk all defs of the specified register,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool def_empty(Register RegNo) const
def_empty - Return true if there are no instructions defining the specified register (it may be live-...
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
iterator_range< def_iterator > def_operands(Register Reg) const
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
LLVM_ABI void setCalleeSavedRegs(ArrayRef< MCPhysReg > CSRs)
Sets the updated Callee Saved Registers list.
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
void insert_range(Range &&R)
Definition SetVector.h:182
Vector takeVector()
Clear the SetVector and return the underlying vector.
Definition SetVector.h:94
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:100
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:31
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:47
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallSetVector< MCPhysReg, 16 > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const
Get a list of 'hint' registers that the register allocator should try first when allocating a physica...
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition VirtRegMap.h:91
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
Definition VirtRegMap.h:87
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
A range adaptor for a pair of iterators.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
int32_t getSVEPseudoMap(uint32_t Opcode)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Definition CallingConv.h:82
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ AnyReg
OBSOLETED - Used for stack based JavaScript calls.
Definition CallingConv.h:60
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2
Preserve X2-X15, X19-X29, SP, Z0-Z31, P0-P15.
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
Preserve X0-X13, X19-X29, SP, Z0-Z31, P0-P15.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1
Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ PreserveNone
Used for runtime calls that preserves none general registers.
Definition CallingConv.h:90
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition CallingConv.h:87
@ GRAAL
Used by GraalVM. Two additional registers are reserved.
@ ARM64EC_Thunk_X64
Calling convention used in the ARM64EC ABI to implement calls between x64 code and thunks.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2132
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset, bool *OutUseUnscaledOp=nullptr, unsigned *OutUnscaledOp=nullptr, int64_t *EmittableOffset=nullptr)
Check if the Offset is a valid frame offset for MI.
@ Done
Definition Threading.h:60
@ AArch64FrameOffsetIsLegal
Offset is legal.
@ AArch64FrameOffsetCanUpdate
Offset can apply, at least partly.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false, bool *HasWinCFI=nullptr, bool EmitCFAOffset=false, StackOffset InitialOffset={}, unsigned FrameReg=AArch64::SP)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, StackOffset &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58