LLVM  16.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"
15 #include "AArch64FrameLowering.h"
16 #include "AArch64InstrInfo.h"
18 #include "AArch64Subtarget.h"
21 #include "llvm/ADT/BitVector.h"
22 #include "llvm/ADT/Triple.h"
30 #include "llvm/IR/DiagnosticInfo.h"
31 #include "llvm/IR/Function.h"
34 
35 using 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), 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  unsigned &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 
70 const MCPhysReg *
72  assert(MF && "Invalid MachineFunction pointer.");
73 
75  // GHC set of callee saved regs is empty as all those regs are
76  // used for passing STG regs around
77  return CSR_AArch64_NoRegs_SaveList;
79  return CSR_AArch64_AllRegs_SaveList;
80 
81  // Darwin has its own CSR_AArch64_AAPCS_SaveList, which means most CSR save
82  // lists depending on that will need to have their Darwin variant as well.
84  return getDarwinCalleeSavedRegs(MF);
85 
87  return CSR_Win_AArch64_CFGuard_Check_SaveList;
89  return CSR_Win_AArch64_AAPCS_SaveList;
91  return CSR_AArch64_AAVPCS_SaveList;
93  return CSR_AArch64_SVE_AAPCS_SaveList;
94  if (MF->getFunction().getCallingConv() ==
97  "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
98  "only supported to improve calls to SME ACLE save/restore/disable-za "
99  "functions, and is not intended to be used beyond that scope.");
100  if (MF->getFunction().getCallingConv() ==
103  "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
104  "only supported to improve calls to SME ACLE __arm_sme_state "
105  "and is not intended to be used beyond that scope.");
107  ->supportSwiftError() &&
109  Attribute::SwiftError))
110  return CSR_AArch64_AAPCS_SwiftError_SaveList;
112  return CSR_AArch64_AAPCS_SwiftTail_SaveList;
114  return CSR_AArch64_RT_MostRegs_SaveList;
116  // This is for OSes other than Windows; Windows is a separate case further
117  // above.
118  return CSR_AArch64_AAPCS_X18_SaveList;
119  if (MF->getInfo<AArch64FunctionInfo>()->isSVECC())
120  return CSR_AArch64_SVE_AAPCS_SaveList;
121  return CSR_AArch64_AAPCS_SaveList;
122 }
123 
124 const MCPhysReg *
126  assert(MF && "Invalid MachineFunction pointer.");
128  "Invalid subtarget for getDarwinCalleeSavedRegs");
129 
132  "Calling convention CFGuard_Check is unsupported on Darwin.");
134  return CSR_Darwin_AArch64_AAVPCS_SaveList;
137  "Calling convention SVE_VectorCall is unsupported on Darwin.");
138  if (MF->getFunction().getCallingConv() ==
141  "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
142  "only supported to improve calls to SME ACLE save/restore/disable-za "
143  "functions, and is not intended to be used beyond that scope.");
144  if (MF->getFunction().getCallingConv() ==
147  "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
148  "only supported to improve calls to SME ACLE __arm_sme_state "
149  "and is not intended to be used beyond that scope.");
151  return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR()
152  ? CSR_Darwin_AArch64_CXX_TLS_PE_SaveList
153  : CSR_Darwin_AArch64_CXX_TLS_SaveList;
155  ->supportSwiftError() &&
157  Attribute::SwiftError))
158  return CSR_Darwin_AArch64_AAPCS_SwiftError_SaveList;
160  return CSR_Darwin_AArch64_AAPCS_SwiftTail_SaveList;
162  return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
164  return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
165  return CSR_Darwin_AArch64_AAPCS_SaveList;
166 }
167 
169  const MachineFunction *MF) const {
170  assert(MF && "Invalid MachineFunction pointer.");
173  return CSR_Darwin_AArch64_CXX_TLS_ViaCopy_SaveList;
174  return nullptr;
175 }
176 
178  MachineFunction &MF) const {
179  const MCPhysReg *CSRs = getCalleeSavedRegs(&MF);
180  SmallVector<MCPhysReg, 32> UpdatedCSRs;
181  for (const MCPhysReg *I = CSRs; *I; ++I)
182  UpdatedCSRs.push_back(*I);
183 
184  for (size_t i = 0; i < AArch64::GPR64commonRegClass.getNumRegs(); ++i) {
186  UpdatedCSRs.push_back(AArch64::GPR64commonRegClass.getRegister(i));
187  }
188  }
189  // Register lists are zero-terminated.
190  UpdatedCSRs.push_back(0);
191  MF.getRegInfo().setCalleeSavedRegs(UpdatedCSRs);
192 }
193 
194 const TargetRegisterClass *
196  unsigned Idx) const {
197  // edge case for GPR/FPR register classes
198  if (RC == &AArch64::GPR32allRegClass && Idx == AArch64::hsub)
199  return &AArch64::FPR32RegClass;
200  else if (RC == &AArch64::GPR64allRegClass && Idx == AArch64::hsub)
201  return &AArch64::FPR64RegClass;
202 
203  // Forward to TableGen's default version.
204  return AArch64GenRegisterInfo::getSubClassWithSubReg(RC, Idx);
205 }
206 
207 const uint32_t *
209  CallingConv::ID CC) const {
211  "Invalid subtarget for getDarwinCallPreservedMask");
212 
214  return CSR_Darwin_AArch64_CXX_TLS_RegMask;
216  return CSR_Darwin_AArch64_AAVPCS_RegMask;
219  "Calling convention SVE_VectorCall is unsupported on Darwin.");
222  "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
223  "unsupported on Darwin.");
226  "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
227  "unsupported on Darwin.");
230  "Calling convention CFGuard_Check is unsupported on Darwin.");
233  ->supportSwiftError() &&
234  MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError))
235  return CSR_Darwin_AArch64_AAPCS_SwiftError_RegMask;
236  if (CC == CallingConv::SwiftTail)
237  return CSR_Darwin_AArch64_AAPCS_SwiftTail_RegMask;
239  return CSR_Darwin_AArch64_RT_MostRegs_RegMask;
240  return CSR_Darwin_AArch64_AAPCS_RegMask;
241 }
242 
243 const uint32_t *
245  CallingConv::ID CC) const {
246  bool SCS = MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
247  if (CC == CallingConv::GHC)
248  // This is academic because all GHC calls are (supposed to be) tail calls
249  return SCS ? CSR_AArch64_NoRegs_SCS_RegMask : CSR_AArch64_NoRegs_RegMask;
250  if (CC == CallingConv::AnyReg)
251  return SCS ? CSR_AArch64_AllRegs_SCS_RegMask : CSR_AArch64_AllRegs_RegMask;
252 
253  // All the following calling conventions are handled differently on Darwin.
255  if (SCS)
256  report_fatal_error("ShadowCallStack attribute not supported on Darwin.");
257  return getDarwinCallPreservedMask(MF, CC);
258  }
259 
261  return SCS ? CSR_AArch64_AAVPCS_SCS_RegMask : CSR_AArch64_AAVPCS_RegMask;
263  return SCS ? CSR_AArch64_SVE_AAPCS_SCS_RegMask
264  : CSR_AArch64_SVE_AAPCS_RegMask;
266  return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
268  return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2_RegMask;
270  return CSR_Win_AArch64_CFGuard_Check_RegMask;
272  ->supportSwiftError() &&
273  MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError))
274  return SCS ? CSR_AArch64_AAPCS_SwiftError_SCS_RegMask
275  : CSR_AArch64_AAPCS_SwiftError_RegMask;
276  if (CC == CallingConv::SwiftTail) {
277  if (SCS)
278  report_fatal_error("ShadowCallStack attribute not supported with swifttail");
279  return CSR_AArch64_AAPCS_SwiftTail_RegMask;
280  }
282  return SCS ? CSR_AArch64_RT_MostRegs_SCS_RegMask
283  : CSR_AArch64_RT_MostRegs_RegMask;
284  else
285  return SCS ? CSR_AArch64_AAPCS_SCS_RegMask : CSR_AArch64_AAPCS_RegMask;
286 }
287 
289  const MachineFunction &MF) const {
291  return CSR_AArch64_AAPCS_RegMask;
292 
293  return nullptr;
294 }
295 
297  if (TT.isOSDarwin())
298  return CSR_Darwin_AArch64_TLS_RegMask;
299 
300  assert(TT.isOSBinFormatELF() && "Invalid target");
301  return CSR_AArch64_TLS_ELF_RegMask;
302 }
303 
305  const uint32_t **Mask) const {
306  uint32_t *UpdatedMask = MF.allocateRegMask();
307  unsigned RegMaskSize = MachineOperand::getRegMaskSize(getNumRegs());
308  memcpy(UpdatedMask, *Mask, sizeof(UpdatedMask[0]) * RegMaskSize);
309 
310  for (size_t i = 0; i < AArch64::GPR64commonRegClass.getNumRegs(); ++i) {
312  for (MCSubRegIterator SubReg(AArch64::GPR64commonRegClass.getRegister(i),
313  this, true);
314  SubReg.isValid(); ++SubReg) {
315  // See TargetRegisterInfo::getCallPreservedMask for how to interpret the
316  // register mask.
317  UpdatedMask[*SubReg / 32] |= 1u << (*SubReg % 32);
318  }
319  }
320  }
321  *Mask = UpdatedMask;
322 }
323 
325  return CSR_AArch64_SMStartStop_RegMask;
326 }
327 
329  return CSR_AArch64_NoRegs_RegMask;
330 }
331 
332 const uint32_t *
334  CallingConv::ID CC) const {
335  // This should return a register mask that is the same as that returned by
336  // getCallPreservedMask but that additionally preserves the register used for
337  // the first i64 argument (which must also be the register used to return a
338  // single i64 return value)
339  //
340  // In case that the calling convention does not use the same register for
341  // both, the function should return NULL (does not currently apply)
342  assert(CC != CallingConv::GHC && "should not be GHC calling convention.");
344  return CSR_Darwin_AArch64_AAPCS_ThisReturn_RegMask;
345  return CSR_AArch64_AAPCS_ThisReturn_RegMask;
346 }
347 
349  return CSR_AArch64_StackProbe_Windows_RegMask;
350 }
351 
354  MCRegister PhysReg) const {
355  if (hasBasePointer(MF) && MCRegisterInfo::regsOverlap(PhysReg, AArch64::X19))
356  return std::string("X19 is used as the frame base pointer register.");
357 
359  bool warn = false;
360  if (MCRegisterInfo::regsOverlap(PhysReg, AArch64::X13) ||
361  MCRegisterInfo::regsOverlap(PhysReg, AArch64::X14) ||
362  MCRegisterInfo::regsOverlap(PhysReg, AArch64::X23) ||
363  MCRegisterInfo::regsOverlap(PhysReg, AArch64::X24) ||
364  MCRegisterInfo::regsOverlap(PhysReg, AArch64::X28))
365  warn = true;
366 
367  for (unsigned i = AArch64::B16; i <= AArch64::B31; ++i)
368  if (MCRegisterInfo::regsOverlap(PhysReg, i))
369  warn = true;
370 
371  if (warn)
372  return std::string(AArch64InstPrinter::getRegisterName(PhysReg)) +
373  " is clobbered by asynchronous signals when using Arm64EC.";
374  }
375 
376  return {};
377 }
378 
379 BitVector
381  const AArch64FrameLowering *TFI = getFrameLowering(MF);
382 
383  // FIXME: avoid re-calculating this every time.
384  BitVector Reserved(getNumRegs());
385  markSuperRegs(Reserved, AArch64::WSP);
386  markSuperRegs(Reserved, AArch64::WZR);
387 
388  if (TFI->hasFP(MF) || TT.isOSDarwin())
389  markSuperRegs(Reserved, AArch64::W29);
390 
392  // x13, x14, x23, x24, x28, and v16-v31 are clobbered by asynchronous
393  // signals, so we can't ever use them.
394  markSuperRegs(Reserved, AArch64::W13);
395  markSuperRegs(Reserved, AArch64::W14);
396  markSuperRegs(Reserved, AArch64::W23);
397  markSuperRegs(Reserved, AArch64::W24);
398  markSuperRegs(Reserved, AArch64::W28);
399  for (unsigned i = AArch64::B16; i <= AArch64::B31; ++i)
400  markSuperRegs(Reserved, i);
401  }
402 
403  for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
405  markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
406  }
407 
408  if (hasBasePointer(MF))
409  markSuperRegs(Reserved, AArch64::W19);
410 
411  // SLH uses register W16/X16 as the taint register.
412  if (MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening))
413  markSuperRegs(Reserved, AArch64::W16);
414 
415  // SME tiles are not allocatable.
416  if (MF.getSubtarget<AArch64Subtarget>().hasSME()) {
417  for (MCSubRegIterator SubReg(AArch64::ZA, this, /*self=*/true);
418  SubReg.isValid(); ++SubReg)
419  Reserved.set(*SubReg);
420  }
421 
422  assert(checkAllSuperRegsMarked(Reserved));
423  return Reserved;
424 }
425 
426 BitVector
428  BitVector Reserved = getStrictlyReservedRegs(MF);
429 
430  for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
432  markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
433  }
434 
435  assert(checkAllSuperRegsMarked(Reserved));
436  return Reserved;
437 }
438 
440  MCRegister Reg) const {
441  return getReservedRegs(MF)[Reg];
442 }
443 
445  MCRegister Reg) const {
446  return getStrictlyReservedRegs(MF)[Reg];
447 }
448 
450  return llvm::any_of(*AArch64::GPR64argRegClass.MC, [this, &MF](MCPhysReg r) {
451  return isStrictlyReservedReg(MF, r);
452  });
453 }
454 
456  const MachineFunction &MF) const {
457  const Function &F = MF.getFunction();
458  F.getContext().diagnose(DiagnosticInfoUnsupported{F, ("AArch64 doesn't support"
459  " function calls if any of the argument registers is reserved.")});
460 }
461 
463  MCRegister PhysReg) const {
464  // SLH uses register X16 as the taint register but it will fallback to a different
465  // method if the user clobbers it. So X16 is not reserved for inline asm but is
466  // for normal codegen.
467  if (MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening) &&
468  MCRegisterInfo::regsOverlap(PhysReg, AArch64::X16))
469  return true;
470 
471  return !isReservedReg(MF, PhysReg);
472 }
473 
474 const TargetRegisterClass *
476  unsigned Kind) const {
477  return &AArch64::GPR64spRegClass;
478 }
479 
480 const TargetRegisterClass *
482  if (RC == &AArch64::CCRRegClass)
483  return &AArch64::GPR64RegClass; // Only MSR & MRS copy NZCV.
484  return RC;
485 }
486 
487 unsigned AArch64RegisterInfo::getBaseRegister() const { return AArch64::X19; }
488 
490  const MachineFrameInfo &MFI = MF.getFrameInfo();
491 
492  // In the presence of variable sized objects or funclets, if the fixed stack
493  // size is large enough that referencing from the FP won't result in things
494  // being in range relatively often, we can use a base pointer to allow access
495  // from the other direction like the SP normally works.
496  //
497  // Furthermore, if both variable sized objects are present, and the
498  // stack needs to be dynamically re-aligned, the base pointer is the only
499  // reliable way to reference the locals.
500  if (MFI.hasVarSizedObjects() || MF.hasEHFunclets()) {
501  if (hasStackRealignment(MF))
502  return true;
503 
504  if (MF.getSubtarget<AArch64Subtarget>().hasSVE()) {
506  // Frames that have variable sized objects and scalable SVE objects,
507  // should always use a basepointer.
508  if (!AFI->hasCalculatedStackSizeSVE() || AFI->getStackSizeSVE())
509  return true;
510  }
511 
512  // Conservatively estimate whether the negative offset from the frame
513  // pointer will be sufficient to reach. If a function has a smallish
514  // frame, it's less likely to have lots of spills and callee saved
515  // space, so it's all more likely to be within range of the frame pointer.
516  // If it's wrong, we'll materialize the constant and still get to the
517  // object; it's just suboptimal. Negative offsets use the unscaled
518  // load/store instructions, which have a 9-bit signed immediate.
519  return MFI.getLocalFrameSize() >= 256;
520  }
521 
522  return false;
523 }
524 
526  MCRegister Reg) const {
529  bool IsVarArg = STI.isCallingConvWin64(MF.getFunction().getCallingConv());
530 
531  auto HasReg = [](ArrayRef<MCRegister> RegList, MCRegister Reg) {
532  return llvm::is_contained(RegList, Reg);
533  };
534 
535  switch (CC) {
536  default:
537  report_fatal_error("Unsupported calling convention.");
539  return HasReg(CC_AArch64_WebKit_JS_ArgRegs, Reg);
540  case CallingConv::GHC:
541  return HasReg(CC_AArch64_GHC_ArgRegs, Reg);
542  case CallingConv::C:
543  case CallingConv::Fast:
546  case CallingConv::Swift:
548  case CallingConv::Tail:
549  if (STI.isTargetWindows() && IsVarArg)
550  return HasReg(CC_AArch64_Win64_VarArg_ArgRegs, Reg);
551  if (!STI.isTargetDarwin()) {
552  switch (CC) {
553  default:
554  return HasReg(CC_AArch64_AAPCS_ArgRegs, Reg);
555  case CallingConv::Swift:
557  return HasReg(CC_AArch64_AAPCS_ArgRegs, Reg) ||
558  HasReg(CC_AArch64_AAPCS_Swift_ArgRegs, Reg);
559  }
560  }
561  if (!IsVarArg) {
562  switch (CC) {
563  default:
564  return HasReg(CC_AArch64_DarwinPCS_ArgRegs, Reg);
565  case CallingConv::Swift:
567  return HasReg(CC_AArch64_DarwinPCS_ArgRegs, Reg) ||
568  HasReg(CC_AArch64_DarwinPCS_Swift_ArgRegs, Reg);
569  }
570  }
571  if (STI.isTargetILP32())
572  return HasReg(CC_AArch64_DarwinPCS_ILP32_VarArg_ArgRegs, Reg);
573  return HasReg(CC_AArch64_DarwinPCS_VarArg_ArgRegs, Reg);
574  case CallingConv::Win64:
575  if (IsVarArg)
576  HasReg(CC_AArch64_Win64_VarArg_ArgRegs, Reg);
577  return HasReg(CC_AArch64_AAPCS_ArgRegs, Reg);
579  return HasReg(CC_AArch64_Win64_CFGuard_Check_ArgRegs, Reg);
584  return HasReg(CC_AArch64_AAPCS_ArgRegs, Reg);
585  }
586 }
587 
588 Register
590  const AArch64FrameLowering *TFI = getFrameLowering(MF);
591  return TFI->hasFP(MF) ? AArch64::FP : AArch64::SP;
592 }
593 
595  const MachineFunction &MF) const {
596  return true;
597 }
598 
600  const MachineFunction &MF) const {
601  return true;
602 }
603 
604 bool
606  // This function indicates whether the emergency spillslot should be placed
607  // close to the beginning of the stackframe (closer to FP) or the end
608  // (closer to SP).
609  //
610  // The beginning works most reliably if we have a frame pointer.
611  // In the presence of any non-constant space between FP and locals,
612  // (e.g. in case of stack realignment or a scalable SVE area), it is
613  // better to use SP or BP.
614  const AArch64FrameLowering &TFI = *getFrameLowering(MF);
616  assert((!MF.getSubtarget<AArch64Subtarget>().hasSVE() ||
617  AFI->hasCalculatedStackSizeSVE()) &&
618  "Expected SVE area to be calculated by this point");
619  return TFI.hasFP(MF) && !hasStackRealignment(MF) && !AFI->getStackSizeSVE();
620 }
621 
623  const MachineFunction &MF) const {
624  return true;
625 }
626 
627 bool
629  const MachineFrameInfo &MFI = MF.getFrameInfo();
631  return true;
632  return MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken();
633 }
634 
635 /// needsFrameBaseReg - Returns true if the instruction's frame index
636 /// reference would be better served by a base register other than FP
637 /// or SP. Used by LocalStackFrameAllocation to determine which frame index
638 /// references it should create new base registers for.
640  int64_t Offset) const {
641  for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i)
642  assert(i < MI->getNumOperands() &&
643  "Instr doesn't have FrameIndex operand!");
644 
645  // It's the load/store FI references that cause issues, as it can be difficult
646  // to materialize the offset if it won't fit in the literal field. Estimate
647  // based on the size of the local frame and some conservative assumptions
648  // about the rest of the stack frame (note, this is pre-regalloc, so
649  // we don't know everything for certain yet) whether this offset is likely
650  // to be out of range of the immediate. Return true if so.
651 
652  // We only generate virtual base registers for loads and stores, so
653  // return false for everything else.
654  if (!MI->mayLoad() && !MI->mayStore())
655  return false;
656 
657  // Without a virtual base register, if the function has variable sized
658  // objects, all fixed-size local references will be via the frame pointer,
659  // Approximate the offset and see if it's legal for the instruction.
660  // Note that the incoming offset is based on the SP value at function entry,
661  // so it'll be negative.
662  MachineFunction &MF = *MI->getParent()->getParent();
663  const AArch64FrameLowering *TFI = getFrameLowering(MF);
664  MachineFrameInfo &MFI = MF.getFrameInfo();
665 
666  // Estimate an offset from the frame pointer.
667  // Conservatively assume all GPR callee-saved registers get pushed.
668  // FP, LR, X19-X28, D8-D15. 64-bits each.
669  int64_t FPOffset = Offset - 16 * 20;
670  // Estimate an offset from the stack pointer.
671  // The incoming offset is relating to the SP at the start of the function,
672  // but when we access the local it'll be relative to the SP after local
673  // allocation, so adjust our SP-relative offset by that allocation size.
674  Offset += MFI.getLocalFrameSize();
675  // Assume that we'll have at least some spill slots allocated.
676  // FIXME: This is a total SWAG number. We should run some statistics
677  // and pick a real one.
678  Offset += 128; // 128 bytes of spill slots
679 
680  // If there is a frame pointer, try using it.
681  // The FP is only available if there is no dynamic realignment. We
682  // don't know for sure yet whether we'll need that, so we guess based
683  // on whether there are any local variables that would trigger it.
684  if (TFI->hasFP(MF) && isFrameOffsetLegal(MI, AArch64::FP, FPOffset))
685  return false;
686 
687  // If we can reference via the stack pointer or base pointer, try that.
688  // FIXME: This (and the code that resolves the references) can be improved
689  // to only disallow SP relative references in the live range of
690  // the VLA(s). In practice, it's unclear how much difference that
691  // would make, but it may be worth doing.
692  if (isFrameOffsetLegal(MI, AArch64::SP, Offset))
693  return false;
694 
695  // If even offset 0 is illegal, we don't want a virtual base register.
696  if (!isFrameOffsetLegal(MI, AArch64::SP, 0))
697  return false;
698 
699  // The offset likely isn't legal; we want to allocate a virtual base register.
700  return true;
701 }
702 
704  Register BaseReg,
705  int64_t Offset) const {
706  assert(MI && "Unable to get the legal offset for nil instruction.");
707  StackOffset SaveOffset = StackOffset::getFixed(Offset);
709 }
710 
711 /// Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx
712 /// at the beginning of the basic block.
713 Register
715  int FrameIdx,
716  int64_t Offset) const {
718  DebugLoc DL; // Defaults to "unknown"
719  if (Ins != MBB->end())
720  DL = Ins->getDebugLoc();
721  const MachineFunction &MF = *MBB->getParent();
722  const AArch64InstrInfo *TII =
723  MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
724  const MCInstrDesc &MCID = TII->get(AArch64::ADDXri);
726  Register BaseReg = MRI.createVirtualRegister(&AArch64::GPR64spRegClass);
727  MRI.constrainRegClass(BaseReg, TII->getRegClass(MCID, 0, this, MF));
728  unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0);
729 
730  BuildMI(*MBB, Ins, DL, MCID, BaseReg)
731  .addFrameIndex(FrameIdx)
732  .addImm(Offset)
733  .addImm(Shifter);
734 
735  return BaseReg;
736 }
737 
739  int64_t Offset) const {
740  // ARM doesn't need the general 64-bit offsets
741  StackOffset Off = StackOffset::getFixed(Offset);
742 
743  unsigned i = 0;
744  while (!MI.getOperand(i).isFI()) {
745  ++i;
746  assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
747  }
748 
749  const MachineFunction *MF = MI.getParent()->getParent();
750  const AArch64InstrInfo *TII =
751  MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
752  bool Done = rewriteAArch64FrameIndex(MI, i, BaseReg, Off, TII);
753  assert(Done && "Unable to resolve frame index!");
754  (void)Done;
755 }
756 
757 // Create a scratch register for the frame index elimination in an instruction.
758 // This function has special handling of stack tagging loop pseudos, in which
759 // case it can also change the instruction opcode.
760 static Register
762  const AArch64InstrInfo *TII) {
763  // ST*Gloop have a reserved scratch register in operand 1. Use it, and also
764  // replace the instruction with the writeback variant because it will now
765  // satisfy the operand constraints for it.
766  Register ScratchReg;
767  if (MI.getOpcode() == AArch64::STGloop ||
768  MI.getOpcode() == AArch64::STZGloop) {
769  assert(FIOperandNum == 3 &&
770  "Wrong frame index operand for STGloop/STZGloop");
771  unsigned Op = MI.getOpcode() == AArch64::STGloop ? AArch64::STGloop_wback
772  : AArch64::STZGloop_wback;
773  ScratchReg = MI.getOperand(1).getReg();
774  MI.getOperand(3).ChangeToRegister(ScratchReg, false, false, true);
775  MI.setDesc(TII->get(Op));
776  MI.tieOperands(1, 3);
777  } else {
778  ScratchReg =
779  MI.getMF()->getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
780  MI.getOperand(FIOperandNum)
781  .ChangeToRegister(ScratchReg, false, false, true);
782  }
783  return ScratchReg;
784 }
785 
787  const StackOffset &Offset, SmallVectorImpl<uint64_t> &Ops) const {
788  // The smallest scalable element supported by scaled SVE addressing
789  // modes are predicates, which are 2 scalable bytes in size. So the scalable
790  // byte offset must always be a multiple of 2.
791  assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
792 
793  // Add fixed-sized offset using existing DIExpression interface.
794  DIExpression::appendOffset(Ops, Offset.getFixed());
795 
796  unsigned VG = getDwarfRegNum(AArch64::VG, true);
797  int64_t VGSized = Offset.getScalable() / 2;
798  if (VGSized > 0) {
799  Ops.push_back(dwarf::DW_OP_constu);
800  Ops.push_back(VGSized);
801  Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
802  Ops.push_back(dwarf::DW_OP_mul);
803  Ops.push_back(dwarf::DW_OP_plus);
804  } else if (VGSized < 0) {
805  Ops.push_back(dwarf::DW_OP_constu);
806  Ops.push_back(-VGSized);
807  Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
808  Ops.push_back(dwarf::DW_OP_mul);
809  Ops.push_back(dwarf::DW_OP_minus);
810  }
811 }
812 
814  int SPAdj, unsigned FIOperandNum,
815  RegScavenger *RS) const {
816  assert(SPAdj == 0 && "Unexpected");
817 
818  MachineInstr &MI = *II;
819  MachineBasicBlock &MBB = *MI.getParent();
820  MachineFunction &MF = *MBB.getParent();
821  const MachineFrameInfo &MFI = MF.getFrameInfo();
822  const AArch64InstrInfo *TII =
823  MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
824  const AArch64FrameLowering *TFI = getFrameLowering(MF);
825  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
826  bool Tagged =
827  MI.getOperand(FIOperandNum).getTargetFlags() & AArch64II::MO_TAGGED;
828  Register FrameReg;
829 
830  // Special handling of dbg_value, stackmap patchpoint statepoint instructions.
831  if (MI.getOpcode() == TargetOpcode::STACKMAP ||
832  MI.getOpcode() == TargetOpcode::PATCHPOINT ||
833  MI.getOpcode() == TargetOpcode::STATEPOINT) {
834  StackOffset Offset =
835  TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg,
836  /*PreferFP=*/true,
837  /*ForSimm=*/false);
838  Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
839  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
840  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
841  return;
842  }
843 
844  if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) {
845  MachineOperand &FI = MI.getOperand(FIOperandNum);
847  assert(!Offset.getScalable() &&
848  "Frame offsets with a scalable component are not supported");
849  FI.ChangeToImmediate(Offset.getFixed());
850  return;
851  }
852 
853  StackOffset Offset;
854  if (MI.getOpcode() == AArch64::TAGPstack) {
855  // TAGPstack must use the virtual frame register in its 3rd operand.
857  FrameReg = MI.getOperand(3).getReg();
860  } else if (Tagged) {
862  MFI.getObjectOffset(FrameIndex) + (int64_t)MFI.getStackSize());
863  if (MFI.hasVarSizedObjects() ||
864  isAArch64FrameOffsetLegal(MI, SPOffset, nullptr, nullptr, nullptr) !=
866  // Can't update to SP + offset in place. Precalculate the tagged pointer
867  // in a scratch register.
868  Offset = TFI->resolveFrameIndexReference(
869  MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
870  Register ScratchReg =
871  MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
872  emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset,
873  TII);
874  BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(AArch64::LDG), ScratchReg)
875  .addReg(ScratchReg)
876  .addReg(ScratchReg)
877  .addImm(0);
878  MI.getOperand(FIOperandNum)
879  .ChangeToRegister(ScratchReg, false, false, true);
880  return;
881  }
882  FrameReg = AArch64::SP;
884  (int64_t)MFI.getStackSize());
885  } else {
886  Offset = TFI->resolveFrameIndexReference(
887  MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
888  }
889 
890  // Modify MI as necessary to handle as much of 'Offset' as possible
891  if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
892  return;
893 
894  assert((!RS || !RS->isScavengingFrameIndex(FrameIndex)) &&
895  "Emergency spill slot is out of reach");
896 
897  // If we get here, the immediate doesn't fit into the instruction. We folded
898  // as much as possible above. Handle the rest, providing a register that is
899  // SP+LargeImm.
900  Register ScratchReg =
902  emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset, TII);
903 }
904 
906  MachineFunction &MF) const {
907  const AArch64FrameLowering *TFI = getFrameLowering(MF);
908 
909  switch (RC->getID()) {
910  default:
911  return 0;
912  case AArch64::GPR32RegClassID:
913  case AArch64::GPR32spRegClassID:
914  case AArch64::GPR32allRegClassID:
915  case AArch64::GPR64spRegClassID:
916  case AArch64::GPR64allRegClassID:
917  case AArch64::GPR64RegClassID:
918  case AArch64::GPR32commonRegClassID:
919  case AArch64::GPR64commonRegClassID:
920  return 32 - 1 // XZR/SP
921  - (TFI->hasFP(MF) || TT.isOSDarwin()) // FP
923  - hasBasePointer(MF); // X19
924  case AArch64::FPR8RegClassID:
925  case AArch64::FPR16RegClassID:
926  case AArch64::FPR32RegClassID:
927  case AArch64::FPR64RegClassID:
928  case AArch64::FPR128RegClassID:
929  return 32;
930 
931  case AArch64::MatrixIndexGPR32_12_15RegClassID:
932  return 4;
933 
934  case AArch64::DDRegClassID:
935  case AArch64::DDDRegClassID:
936  case AArch64::DDDDRegClassID:
937  case AArch64::QQRegClassID:
938  case AArch64::QQQRegClassID:
939  case AArch64::QQQQRegClassID:
940  return 32;
941 
942  case AArch64::FPR128_loRegClassID:
943  case AArch64::FPR64_loRegClassID:
944  case AArch64::FPR16_loRegClassID:
945  return 16;
946  }
947 }
948 
950  const MachineFunction &MF) const {
951  const auto &MFI = MF.getFrameInfo();
952  if (!MF.hasEHFunclets() && !MFI.hasVarSizedObjects())
953  return AArch64::SP;
954  else if (hasStackRealignment(MF))
955  return getBaseRegister();
956  return getFrameRegister(MF);
957 }
958 
959 /// SrcRC and DstRC will be morphed into NewRC if this returns true
961  MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
962  const TargetRegisterClass *DstRC, unsigned DstSubReg,
963  const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
964  if (MI->isCopy() &&
965  ((DstRC->getID() == AArch64::GPR64RegClassID) ||
966  (DstRC->getID() == AArch64::GPR64commonRegClassID)) &&
967  MI->getOperand(0).getSubReg() && MI->getOperand(1).getSubReg())
968  // Do not coalesce in the case of a 32-bit subregister copy
969  // which implements a 32 to 64 bit zero extension
970  // which relies on the upper 32 bits being zeroed.
971  return false;
972  return true;
973 }
llvm::AArch64RegisterInfo::getSMStartStopCallPreservedMask
const uint32_t * getSMStartStopCallPreservedMask() const
Definition: AArch64RegisterInfo.cpp:324
i
i
Definition: README.txt:29
llvm::AArch64RegisterInfo::getCallPreservedMask
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Definition: AArch64RegisterInfo.cpp:244
llvm::MachineFrameInfo::hasVarSizedObjects
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
Definition: MachineFrameInfo.h:354
llvm::AArch64Subtarget::isTargetWindows
bool isTargetWindows() const
Definition: AArch64Subtarget.h:254
AArch64RegisterInfo.h
createScratchRegisterForInstruction
static Register createScratchRegisterForInstruction(MachineInstr &MI, unsigned FIOperandNum, const AArch64InstrInfo *TII)
Definition: AArch64RegisterInfo.cpp:761
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:75
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
AArch64MachineFunctionInfo.h
llvm::CallingConv::Win64
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
Definition: CallingConv.h:156
llvm::ISD::PATCHPOINT
@ PATCHPOINT
Definition: ISDOpcodes.h:1299
llvm::AArch64RegisterInfo::eliminateFrameIndex
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Definition: AArch64RegisterInfo.cpp:813
TargetFrameLowering.h
llvm::AArch64RegisterInfo::shouldCoalesce
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.
Definition: AArch64RegisterInfo.cpp:960
llvm::AArch64_AM::LSL
@ LSL
Definition: AArch64AddressingModes.h:35
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:156
llvm::AttributeList::hasAttrSomewhere
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value.
Definition: Attributes.cpp:1413
llvm::MachineFunction::allocateRegMask
uint32_t * allocateRegMask()
Allocate and initialize a register mask with NumRegister bits.
Definition: MachineFunction.cpp:547
llvm::DiagnosticInfoUnsupported
Diagnostic information for unsupported feature in backend.
Definition: DiagnosticInfo.h:1009
DebugInfoMetadata.h
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::Function
Definition: Function.h:60
llvm::BitVector::set
BitVector & set()
Definition: BitVector.h:344
llvm::AArch64FrameOffsetCanUpdate
@ AArch64FrameOffsetCanUpdate
Offset can apply, at least partly.
Definition: AArch64InstrInfo.h:437
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1182
llvm::CallingConv::Fast
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
AArch64GenRegisterInfo
llvm::CallingConv::PreserveMost
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition: CallingConv.h:63
llvm::AArch64RegisterInfo::UpdateCustomCallPreservedMask
void UpdateCustomCallPreservedMask(MachineFunction &MF, const uint32_t **Mask) const
Definition: AArch64RegisterInfo.cpp:304
llvm::AArch64RegisterInfo::explainReservedReg
llvm::Optional< std::string > explainReservedReg(const MachineFunction &MF, MCRegister PhysReg) const override
Definition: AArch64RegisterInfo.cpp:353
llvm::AArch64RegisterInfo::getBaseRegister
unsigned getBaseRegister() const
Definition: AArch64RegisterInfo.cpp:487
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::AArch64RegisterInfo::isAnyArgRegReserved
bool isAnyArgRegReserved(const MachineFunction &MF) const
Definition: AArch64RegisterInfo.cpp:449
llvm::AArch64RegisterInfo::getNoPreservedMask
const uint32_t * getNoPreservedMask() const override
Definition: AArch64RegisterInfo.cpp:328
llvm::AArch64InstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo, unsigned AltIdx=AArch64::NoRegAltName)
llvm::AArch64RegisterInfo::isArgumentRegister
bool isArgumentRegister(const MachineFunction &MF, MCRegister Reg) const override
Definition: AArch64RegisterInfo.cpp:525
llvm::AArch64Subtarget::isTargetDarwin
bool isTargetDarwin() const
Definition: AArch64Subtarget.h:251
llvm::AArch64RegisterInfo::getCalleeSavedRegsViaCopy
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
Definition: AArch64RegisterInfo.cpp:168
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
getDwarfRegNum
static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI)
Go up the super-register chain until we hit a valid dwarf register number.
Definition: StackMaps.cpp:178
llvm::AArch64FunctionInfo::isSVECC
bool isSVECC() const
Definition: AArch64MachineFunctionInfo.h:201
llvm::StackOffset::getFixed
ScalarTy getFixed() const
Definition: TypeSize.h:149
llvm::AArch64RegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:589
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
llvm::rewriteAArch64FrameIndex
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, StackOffset &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
Definition: AArch64InstrInfo.cpp:4697
llvm::Optional< std::string >
llvm::AArch64Subtarget::isXRegCustomCalleeSaved
bool isXRegCustomCalleeSaved(size_t i) const
Definition: AArch64Subtarget.h:209
llvm::CallingConv::WebKit_JS
@ WebKit_JS
Used for stack based JavaScript calls.
Definition: CallingConv.h:56
llvm::AArch64FrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
Definition: AArch64FrameLowering.cpp:426
llvm::AArch64Subtarget::isWindowsArm64EC
bool isWindowsArm64EC() const
Definition: AArch64Subtarget.h:257
llvm::AArch64Subtarget::getTargetLowering
const AArch64TargetLowering * getTargetLowering() const override
Definition: AArch64Subtarget.h:171
llvm::CallingConv::AArch64_SVE_VectorCall
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
Definition: CallingConv.h:225
F
#define F(x, y, z)
Definition: MD5.cpp:55
MachineRegisterInfo.h
llvm::AArch64RegisterInfo::getRegPressureLimit
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:905
llvm::RegScavenger::isScavengingFrameIndex
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
Definition: RegisterScavenging.h:148
llvm::MCRegisterInfo::regsOverlap
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
Definition: MCRegisterInfo.cpp:126
llvm::AArch64RegisterInfo::cannotEliminateFrame
bool cannotEliminateFrame(const MachineFunction &MF) const
Definition: AArch64RegisterInfo.cpp:628
llvm::AArch64RegisterInfo::getCrossCopyRegClass
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
Definition: AArch64RegisterInfo.cpp:481
llvm::AArch64FrameLowering
Definition: AArch64FrameLowering.h:21
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:666
llvm::Triple::isOSBinFormatELF
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:663
llvm::AArch64RegisterInfo::getSubClassWithSubReg
const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const override
Definition: AArch64RegisterInfo.cpp:195
AArch64InstrInfo.h
llvm::CallingConv::Swift
@ Swift
Calling convention for Swift.
Definition: CallingConv.h:69
llvm::AArch64InstrInfo
Definition: AArch64InstrInfo.h:37
llvm::Triple::isOSDarwin
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or DriverKit).
Definition: Triple.h:509
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:754
llvm::MachineOperand::getRegMaskSize
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
Definition: MachineOperand.h:645
llvm::AArch64Subtarget::isTargetILP32
bool isTargetILP32() const
Definition: AArch64Subtarget.h:263
llvm::AArch64TargetLowering::supportSwiftError
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
Definition: AArch64ISelLowering.h:820
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::MachineOperand::ChangeToImmediate
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
Definition: MachineOperand.cpp:156
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:197
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::MachineRegisterInfo::setCalleeSavedRegs
void setCalleeSavedRegs(ArrayRef< MCPhysReg > CSRs)
Sets the updated Callee Saved Registers list.
Definition: MachineRegisterInfo.cpp:630
llvm::AArch64_AM::getShifterImm
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 ==...
Definition: AArch64AddressingModes.h:99
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
BitVector.h
llvm::MachineFrameInfo::getStackSize
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Definition: MachineFrameInfo.h:577
llvm::MachineFrameInfo::getObjectOffset
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
Definition: MachineFrameInfo.h:518
llvm::BitVector
Definition: BitVector.h:75
llvm::SmallVectorImpl::append
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:670
llvm::AArch64RegisterInfo::materializeFrameBaseRegister
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 ...
Definition: AArch64RegisterInfo.cpp:714
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::AArch64RegisterInfo::isFrameOffsetLegal
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
Definition: AArch64RegisterInfo.cpp:703
llvm::Function::getAttributes
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:314
llvm::CallingConv::AnyReg
@ AnyReg
Used for dynamic register based calls (e.g.
Definition: CallingConv.h:60
AArch64AddressingModes.h
llvm::CallingConv::AArch64_VectorCall
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
Definition: CallingConv.h:222
llvm::TargetOptions::DisableFramePointerElim
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
Definition: TargetOptionsImpl.cpp:23
llvm::AArch64FrameOffsetIsLegal
@ AArch64FrameOffsetIsLegal
Offset is legal.
Definition: AArch64InstrInfo.h:436
llvm::AArch64FrameLowering::resolveFrameIndexReference
StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP, bool ForSimm) const
Definition: AArch64FrameLowering.cpp:2269
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:656
llvm::AArch64RegisterInfo::AArch64RegisterInfo
AArch64RegisterInfo(const Triple &TT)
Definition: AArch64RegisterInfo.cpp:42
llvm::AArch64FunctionInfo::isSplitCSR
bool isSplitCSR() const
Definition: AArch64MachineFunctionInfo.h:240
llvm::MachineInstrBuilder::addFrameIndex
const MachineInstrBuilder & addFrameIndex(int Idx) const
Definition: MachineInstrBuilder.h:152
llvm::AArch64Subtarget::isXRegisterReservedForRA
bool isXRegisterReservedForRA(size_t i) const
Definition: AArch64Subtarget.h:202
llvm::isAArch64FrameOffsetLegal
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.
Definition: AArch64InstrInfo.cpp:4596
llvm::Function::hasFnAttribute
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:628
llvm::MachineFrameInfo::getLocalFrameSize
int64_t getLocalFrameSize() const
Get the size of the local object blob.
Definition: MachineFrameInfo.h:437
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
AArch64FrameLowering.h
llvm::Function::getCallingConv
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:238
llvm::CallingConv::CXX_FAST_TLS
@ CXX_FAST_TLS
Used for access functions.
Definition: CallingConv.h:72
llvm::AArch64FunctionInfo::getTaggedBasePointerOffset
unsigned getTaggedBasePointerOffset() const
Definition: AArch64MachineFunctionInfo.h:408
llvm::AArch64RegisterInfo::isStrictlyReservedReg
bool isStrictlyReservedReg(const MachineFunction &MF, MCRegister Reg) const
Definition: AArch64RegisterInfo.cpp:444
llvm::AArch64FunctionInfo
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
Definition: AArch64MachineFunctionInfo.h:38
llvm::AArch64RegisterInfo::needsFrameBaseReg
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
needsFrameBaseReg - Returns true if the instruction's frame index reference would be better served by...
Definition: AArch64RegisterInfo.cpp:639
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::RegScavenger
Definition: RegisterScavenging.h:34
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1673
llvm::CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2
Preserve X2-X15, X19-X29, SP, Z0-Z31, P0-P15.
Definition: CallingConv.h:242
llvm::TargetMachine::Options
TargetOptions Options
Definition: TargetMachine.h:118
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:672
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:261
llvm::ISD::STACKMAP
@ STACKMAP
Definition: ISDOpcodes.h:1293
llvm::AArch64Subtarget::isTargetLinux
bool isTargetLinux() const
Definition: AArch64Subtarget.h:253
llvm::AArch64Subtarget::isCallingConvWin64
bool isCallingConvWin64(CallingConv::ID CC) const
Definition: AArch64Subtarget.h:307
llvm::AArch64RegisterInfo::useFPForScavengingIndex
bool useFPForScavengingIndex(const MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:605
llvm::emitFrameOffset
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.
Definition: AArch64InstrInfo.cpp:4363
llvm::AArch64FrameLowering::getNonLocalFrameIndexReference
StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const override
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
Definition: AArch64FrameLowering.cpp:2233
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::AArch64RegisterInfo::getCalleeSavedRegs
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
Definition: AArch64RegisterInfo.cpp:71
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::AArch64RegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:427
Triple.h
llvm::AArch64RegisterInfo::requiresFrameIndexScavenging
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:622
TargetOptions.h
llvm::AArch64RegisterInfo::isAsmClobberable
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
Definition: AArch64RegisterInfo.cpp:462
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::AArch64Subtarget::isXRegisterReserved
bool isXRegisterReserved(size_t i) const
Definition: AArch64Subtarget.h:201
llvm::AArch64RegisterInfo::getLocalAddressRegister
unsigned getLocalAddressRegister(const MachineFunction &MF) const
Definition: AArch64RegisterInfo.cpp:949
llvm::any_of
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:1597
AArch64InstPrinter.h
llvm::AArch64FunctionInfo::hasCalculatedStackSizeSVE
bool hasCalculatedStackSizeSVE() const
Definition: AArch64MachineFunctionInfo.h:219
Dwarf.h
uint32_t
llvm::StackOffset
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
Definition: TypeSize.h:134
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::AArch64RegisterInfo::getCustomEHPadPreservedMask
const uint32_t * getCustomEHPadPreservedMask(const MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:288
CC
auto CC
Definition: RISCVRedundantCopyElimination.cpp:79
llvm::AArch64RegisterInfo::getThisReturnPreservedMask
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned' is on...
Definition: AArch64RegisterInfo.cpp:333
llvm::AArch64RegisterInfo::emitReservedArgRegCallError
void emitReservedArgRegCallError(const MachineFunction &MF) const
Definition: AArch64RegisterInfo.cpp:455
llvm::AArch64RegisterInfo::getDarwinCallPreservedMask
const uint32_t * getDarwinCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const
Definition: AArch64RegisterInfo.cpp:208
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineFrameInfo::isFrameAddressTaken
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Definition: MachineFrameInfo.h:370
llvm::AArch64_MC::initLLVMToCVRegMapping
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
Definition: AArch64MCTargetDesc.cpp:66
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::DIExpression::appendOffset
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
Definition: DebugInfoMetadata.cpp:1382
llvm::AArch64Subtarget::getNumXRegisterReserved
unsigned getNumXRegisterReserved() const
Definition: AArch64Subtarget.h:203
llvm::AArch64RegisterInfo::getOffsetOpcodes
void getOffsetOpcodes(const StackOffset &Offset, SmallVectorImpl< uint64_t > &Ops) const override
Definition: AArch64RegisterInfo.cpp:786
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:622
uint16_t
llvm::AArch64FunctionInfo::getStackSizeSVE
uint64_t getStackSizeSVE() const
Definition: AArch64MachineFunctionInfo.h:226
llvm::MachineFunction::getTarget
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition: MachineFunction.h:652
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
MachineFrameInfo.h
llvm::CallingConv::SwiftTail
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition: CallingConv.h:87
DiagnosticInfo.h
Function.h
llvm::LiveIntervals
Definition: LiveIntervals.h:53
llvm::AArch64RegisterInfo::getWindowsStackProbePreservedMask
const uint32_t * getWindowsStackProbePreservedMask() const
Stack probing calls preserve different CSRs to the normal CC.
Definition: AArch64RegisterInfo.cpp:348
llvm::MachineFunction::hasEHFunclets
bool hasEHFunclets() const
Definition: MachineFunction.h:1099
llvm::MCSubRegIterator
MCSubRegIterator enumerates all sub-registers of Reg.
Definition: MCRegisterInfo.h:597
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:105
AArch64Subtarget.h
llvm::AArch64RegisterInfo::resolveFrameIndex
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
Definition: AArch64RegisterInfo.cpp:738
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:305
MachineInstrBuilder.h
llvm::CallingConv::CFGuard_Check
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Definition: CallingConv.h:82
llvm::AArch64RegisterInfo::getPointerRegClass
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
Definition: AArch64RegisterInfo.cpp:475
llvm::CallingConv::GHC
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition: CallingConv.h:50
llvm::MachineRegisterInfo::constrainRegClass
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...
Definition: MachineRegisterInfo.cpp:82
llvm::AArch64RegisterInfo::UpdateCustomCalleeSavedRegs
void UpdateCustomCalleeSavedRegs(MachineFunction &MF) const
Definition: AArch64RegisterInfo.cpp:177
llvm::MipsISD::Ins
@ Ins
Definition: MipsISelLowering.h:160
llvm::SmallVectorImpl< uint64_t >
llvm::AArch64RegisterInfo::getTLSCallPreservedMask
const uint32_t * getTLSCallPreservedMask() const
Definition: AArch64RegisterInfo.cpp:296
llvm::CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
Preserve X0-X13, X19-X29, SP, Z0-Z31, P0-P15.
Definition: CallingConv.h:239
llvm::AArch64RegisterInfo::regNeedsCFI
bool regNeedsCFI(unsigned Reg, unsigned &RegToUseForCFI) const
Return whether the register needs a CFI entry.
Definition: AArch64RegisterInfo.cpp:52
llvm::CallingConv::Tail
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition: CallingConv.h:76
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineFrameInfo::adjustsStack
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
Definition: MachineFrameInfo.h:601
llvm::AArch64II::MO_TAGGED
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
Definition: AArch64BaseInfo.h:785
RegisterScavenging.h
llvm::AArch64RegisterInfo::requiresVirtualBaseRegisters
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:599
llvm::AArch64Subtarget
Definition: AArch64Subtarget.h:38
raw_ostream.h
llvm::AArch64RegisterInfo::hasBasePointer
bool hasBasePointer(const MachineFunction &MF) const
Definition: AArch64RegisterInfo.cpp:489
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::AArch64RegisterInfo::requiresRegisterScavenging
bool requiresRegisterScavenging(const MachineFunction &MF) const override
Definition: AArch64RegisterInfo.cpp:594
llvm::AArch64RegisterInfo::getDarwinCalleeSavedRegs
const MCPhysReg * getDarwinCalleeSavedRegs(const MachineFunction *MF) const
Definition: AArch64RegisterInfo.cpp:125
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:307
SubReg
unsigned SubReg
Definition: AArch64AdvSIMDScalarPass.cpp:104
llvm::AArch64RegisterInfo::isReservedReg
bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const
Definition: AArch64RegisterInfo.cpp:439
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
llvm::AArch64RegisterInfo::getStrictlyReservedRegs
BitVector getStrictlyReservedRegs(const MachineFunction &MF) const
Definition: AArch64RegisterInfo.cpp:380