LLVM  10.0.0svn
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 "AArch64StackOffset.h"
19 #include "AArch64Subtarget.h"
21 #include "llvm/ADT/BitVector.h"
22 #include "llvm/ADT/Triple.h"
28 #include "llvm/IR/DiagnosticInfo.h"
29 #include "llvm/IR/Function.h"
32 
33 using namespace llvm;
34 
35 #define GET_REGINFO_TARGET_DESC
36 #include "AArch64GenRegisterInfo.inc"
37 
39  : AArch64GenRegisterInfo(AArch64::LR), TT(TT) {
41 }
42 
43 const MCPhysReg *
45  assert(MF && "Invalid MachineFunction pointer.");
47  return CSR_Win_AArch64_AAPCS_SaveList;
49  // GHC set of callee saved regs is empty as all those regs are
50  // used for passing STG regs around
51  return CSR_AArch64_NoRegs_SaveList;
53  return CSR_AArch64_AllRegs_SaveList;
55  return CSR_AArch64_AAVPCS_SaveList;
57  return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR() ?
58  CSR_AArch64_CXX_TLS_Darwin_PE_SaveList :
59  CSR_AArch64_CXX_TLS_Darwin_SaveList;
61  ->supportSwiftError() &&
63  Attribute::SwiftError))
64  return CSR_AArch64_AAPCS_SwiftError_SaveList;
66  return CSR_AArch64_RT_MostRegs_SaveList;
68  return CSR_Darwin_AArch64_AAPCS_SaveList;
69  return CSR_AArch64_AAPCS_SaveList;
70 }
71 
73  const MachineFunction *MF) const {
74  assert(MF && "Invalid MachineFunction pointer.");
76  MF->getInfo<AArch64FunctionInfo>()->isSplitCSR())
77  return CSR_AArch64_CXX_TLS_Darwin_ViaCopy_SaveList;
78  return nullptr;
79 }
80 
82  MachineFunction &MF) const {
83  const MCPhysReg *CSRs = getCalleeSavedRegs(&MF);
84  SmallVector<MCPhysReg, 32> UpdatedCSRs;
85  for (const MCPhysReg *I = CSRs; *I; ++I)
86  UpdatedCSRs.push_back(*I);
87 
88  for (size_t i = 0; i < AArch64::GPR64commonRegClass.getNumRegs(); ++i) {
90  UpdatedCSRs.push_back(AArch64::GPR64commonRegClass.getRegister(i));
91  }
92  }
93  // Register lists are zero-terminated.
94  UpdatedCSRs.push_back(0);
95  MF.getRegInfo().setCalleeSavedRegs(UpdatedCSRs);
96 }
97 
98 const TargetRegisterClass *
100  unsigned Idx) const {
101  // edge case for GPR/FPR register classes
102  if (RC == &AArch64::GPR32allRegClass && Idx == AArch64::hsub)
103  return &AArch64::FPR32RegClass;
104  else if (RC == &AArch64::GPR64allRegClass && Idx == AArch64::hsub)
105  return &AArch64::FPR64RegClass;
106 
107  // Forward to TableGen's default version.
108  return AArch64GenRegisterInfo::getSubClassWithSubReg(RC, Idx);
109 }
110 
111 const uint32_t *
113  CallingConv::ID CC) const {
114  bool SCS = MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
115  if (CC == CallingConv::GHC)
116  // This is academic because all GHC calls are (supposed to be) tail calls
117  return SCS ? CSR_AArch64_NoRegs_SCS_RegMask : CSR_AArch64_NoRegs_RegMask;
118  if (CC == CallingConv::AnyReg)
119  return SCS ? CSR_AArch64_AllRegs_SCS_RegMask : CSR_AArch64_AllRegs_RegMask;
120  if (CC == CallingConv::CXX_FAST_TLS)
121  return SCS ? CSR_AArch64_CXX_TLS_Darwin_SCS_RegMask
122  : CSR_AArch64_CXX_TLS_Darwin_RegMask;
124  return SCS ? CSR_AArch64_AAVPCS_SCS_RegMask : CSR_AArch64_AAVPCS_RegMask;
126  return CSR_AArch64_SVE_AAPCS_RegMask;
128  ->supportSwiftError() &&
129  MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError))
130  return SCS ? CSR_AArch64_AAPCS_SwiftError_SCS_RegMask
131  : CSR_AArch64_AAPCS_SwiftError_RegMask;
132  if (CC == CallingConv::PreserveMost)
133  return SCS ? CSR_AArch64_RT_MostRegs_SCS_RegMask
134  : CSR_AArch64_RT_MostRegs_RegMask;
135  else
136  return SCS ? CSR_AArch64_AAPCS_SCS_RegMask : CSR_AArch64_AAPCS_RegMask;
137 }
138 
140  if (TT.isOSDarwin())
141  return CSR_AArch64_TLS_Darwin_RegMask;
142 
143  assert(TT.isOSBinFormatELF() && "Invalid target");
144  return CSR_AArch64_TLS_ELF_RegMask;
145 }
146 
148  const uint32_t **Mask) const {
149  uint32_t *UpdatedMask = MF.allocateRegMask();
150  unsigned RegMaskSize = MachineOperand::getRegMaskSize(getNumRegs());
151  memcpy(UpdatedMask, *Mask, sizeof(UpdatedMask[0]) * RegMaskSize);
152 
153  for (size_t i = 0; i < AArch64::GPR64commonRegClass.getNumRegs(); ++i) {
155  for (MCSubRegIterator SubReg(AArch64::GPR64commonRegClass.getRegister(i),
156  this, true);
157  SubReg.isValid(); ++SubReg) {
158  // See TargetRegisterInfo::getCallPreservedMask for how to interpret the
159  // register mask.
160  UpdatedMask[*SubReg / 32] |= 1u << (*SubReg % 32);
161  }
162  }
163  }
164  *Mask = UpdatedMask;
165 }
166 
168  return CSR_AArch64_NoRegs_RegMask;
169 }
170 
171 const uint32_t *
173  CallingConv::ID CC) const {
174  // This should return a register mask that is the same as that returned by
175  // getCallPreservedMask but that additionally preserves the register used for
176  // the first i64 argument (which must also be the register used to return a
177  // single i64 return value)
178  //
179  // In case that the calling convention does not use the same register for
180  // both, the function should return NULL (does not currently apply)
181  assert(CC != CallingConv::GHC && "should not be GHC calling convention.");
182  return CSR_AArch64_AAPCS_ThisReturn_RegMask;
183 }
184 
186  return CSR_AArch64_StackProbe_Windows_RegMask;
187 }
188 
189 BitVector
191  const AArch64FrameLowering *TFI = getFrameLowering(MF);
192 
193  // FIXME: avoid re-calculating this every time.
194  BitVector Reserved(getNumRegs());
195  markSuperRegs(Reserved, AArch64::WSP);
196  markSuperRegs(Reserved, AArch64::WZR);
197 
198  if (TFI->hasFP(MF) || TT.isOSDarwin())
199  markSuperRegs(Reserved, AArch64::W29);
200 
201  for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
203  markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
204  }
205 
206  if (hasBasePointer(MF))
207  markSuperRegs(Reserved, AArch64::W19);
208 
209  // SLH uses register W16/X16 as the taint register.
210  if (MF.getFunction().hasFnAttribute(Attribute::SpeculativeLoadHardening))
211  markSuperRegs(Reserved, AArch64::W16);
212 
213  assert(checkAllSuperRegsMarked(Reserved));
214  return Reserved;
215 }
216 
218  unsigned Reg) const {
219  return getReservedRegs(MF)[Reg];
220 }
221 
223  return std::any_of(std::begin(*AArch64::GPR64argRegClass.MC),
224  std::end(*AArch64::GPR64argRegClass.MC),
225  [this, &MF](MCPhysReg r){return isReservedReg(MF, r);});
226 }
227 
229  const MachineFunction &MF) const {
230  const Function &F = MF.getFunction();
231  F.getContext().diagnose(DiagnosticInfoUnsupported{F, "AArch64 doesn't support"
232  " function calls if any of the argument registers is reserved."});
233 }
234 
236  unsigned PhysReg) const {
237  return !isReservedReg(MF, PhysReg);
238 }
239 
240 bool AArch64RegisterInfo::isConstantPhysReg(unsigned PhysReg) const {
241  return PhysReg == AArch64::WZR || PhysReg == AArch64::XZR;
242 }
243 
244 const TargetRegisterClass *
246  unsigned Kind) const {
247  return &AArch64::GPR64spRegClass;
248 }
249 
250 const TargetRegisterClass *
252  if (RC == &AArch64::CCRRegClass)
253  return &AArch64::GPR64RegClass; // Only MSR & MRS copy NZCV.
254  return RC;
255 }
256 
257 unsigned AArch64RegisterInfo::getBaseRegister() const { return AArch64::X19; }
258 
260  const MachineFrameInfo &MFI = MF.getFrameInfo();
261 
262  // In the presence of variable sized objects or funclets, if the fixed stack
263  // size is large enough that referencing from the FP won't result in things
264  // being in range relatively often, we can use a base pointer to allow access
265  // from the other direction like the SP normally works.
266  //
267  // Furthermore, if both variable sized objects are present, and the
268  // stack needs to be dynamically re-aligned, the base pointer is the only
269  // reliable way to reference the locals.
270  if (MFI.hasVarSizedObjects() || MF.hasEHFunclets()) {
271  if (needsStackRealignment(MF))
272  return true;
273  // Conservatively estimate whether the negative offset from the frame
274  // pointer will be sufficient to reach. If a function has a smallish
275  // frame, it's less likely to have lots of spills and callee saved
276  // space, so it's all more likely to be within range of the frame pointer.
277  // If it's wrong, we'll materialize the constant and still get to the
278  // object; it's just suboptimal. Negative offsets use the unscaled
279  // load/store instructions, which have a 9-bit signed immediate.
280  return MFI.getLocalFrameSize() >= 256;
281  }
282 
283  return false;
284 }
285 
286 Register
288  const AArch64FrameLowering *TFI = getFrameLowering(MF);
289  return TFI->hasFP(MF) ? AArch64::FP : AArch64::SP;
290 }
291 
293  const MachineFunction &MF) const {
294  return true;
295 }
296 
298  const MachineFunction &MF) const {
299  return true;
300 }
301 
302 bool
304  // This function indicates whether the emergency spillslot should be placed
305  // close to the beginning of the stackframe (closer to FP) or the end
306  // (closer to SP).
307  //
308  // The beginning works most reliably if we have a frame pointer.
309  const AArch64FrameLowering &TFI = *getFrameLowering(MF);
310  return TFI.hasFP(MF);
311 }
312 
314  const MachineFunction &MF) const {
315  return true;
316 }
317 
318 bool
320  const MachineFrameInfo &MFI = MF.getFrameInfo();
322  return true;
323  return MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken();
324 }
325 
326 /// needsFrameBaseReg - Returns true if the instruction's frame index
327 /// reference would be better served by a base register other than FP
328 /// or SP. Used by LocalStackFrameAllocation to determine which frame index
329 /// references it should create new base registers for.
331  int64_t Offset) const {
332  for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i)
333  assert(i < MI->getNumOperands() &&
334  "Instr doesn't have FrameIndex operand!");
335 
336  // It's the load/store FI references that cause issues, as it can be difficult
337  // to materialize the offset if it won't fit in the literal field. Estimate
338  // based on the size of the local frame and some conservative assumptions
339  // about the rest of the stack frame (note, this is pre-regalloc, so
340  // we don't know everything for certain yet) whether this offset is likely
341  // to be out of range of the immediate. Return true if so.
342 
343  // We only generate virtual base registers for loads and stores, so
344  // return false for everything else.
345  if (!MI->mayLoad() && !MI->mayStore())
346  return false;
347 
348  // Without a virtual base register, if the function has variable sized
349  // objects, all fixed-size local references will be via the frame pointer,
350  // Approximate the offset and see if it's legal for the instruction.
351  // Note that the incoming offset is based on the SP value at function entry,
352  // so it'll be negative.
353  MachineFunction &MF = *MI->getParent()->getParent();
354  const AArch64FrameLowering *TFI = getFrameLowering(MF);
355  MachineFrameInfo &MFI = MF.getFrameInfo();
356 
357  // Estimate an offset from the frame pointer.
358  // Conservatively assume all GPR callee-saved registers get pushed.
359  // FP, LR, X19-X28, D8-D15. 64-bits each.
360  int64_t FPOffset = Offset - 16 * 20;
361  // Estimate an offset from the stack pointer.
362  // The incoming offset is relating to the SP at the start of the function,
363  // but when we access the local it'll be relative to the SP after local
364  // allocation, so adjust our SP-relative offset by that allocation size.
365  Offset += MFI.getLocalFrameSize();
366  // Assume that we'll have at least some spill slots allocated.
367  // FIXME: This is a total SWAG number. We should run some statistics
368  // and pick a real one.
369  Offset += 128; // 128 bytes of spill slots
370 
371  // If there is a frame pointer, try using it.
372  // The FP is only available if there is no dynamic realignment. We
373  // don't know for sure yet whether we'll need that, so we guess based
374  // on whether there are any local variables that would trigger it.
375  if (TFI->hasFP(MF) && isFrameOffsetLegal(MI, AArch64::FP, FPOffset))
376  return false;
377 
378  // If we can reference via the stack pointer or base pointer, try that.
379  // FIXME: This (and the code that resolves the references) can be improved
380  // to only disallow SP relative references in the live range of
381  // the VLA(s). In practice, it's unclear how much difference that
382  // would make, but it may be worth doing.
383  if (isFrameOffsetLegal(MI, AArch64::SP, Offset))
384  return false;
385 
386  // The offset likely isn't legal; we want to allocate a virtual base register.
387  return true;
388 }
389 
391  unsigned BaseReg,
392  int64_t Offset) const {
393  assert(Offset <= INT_MAX && "Offset too big to fit in int.");
394  assert(MI && "Unable to get the legal offset for nil instruction.");
395  StackOffset SaveOffset(Offset, MVT::i8);
396  return isAArch64FrameOffsetLegal(*MI, SaveOffset) & AArch64FrameOffsetIsLegal;
397 }
398 
399 /// Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx
400 /// at the beginning of the basic block.
402  unsigned BaseReg,
403  int FrameIdx,
404  int64_t Offset) const {
406  DebugLoc DL; // Defaults to "unknown"
407  if (Ins != MBB->end())
408  DL = Ins->getDebugLoc();
409  const MachineFunction &MF = *MBB->getParent();
410  const AArch64InstrInfo *TII =
411  MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
412  const MCInstrDesc &MCID = TII->get(AArch64::ADDXri);
414  MRI.constrainRegClass(BaseReg, TII->getRegClass(MCID, 0, this, MF));
415  unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0);
416 
417  BuildMI(*MBB, Ins, DL, MCID, BaseReg)
418  .addFrameIndex(FrameIdx)
419  .addImm(Offset)
420  .addImm(Shifter);
421 }
422 
424  int64_t Offset) const {
425  // ARM doesn't need the general 64-bit offsets
426  StackOffset Off(Offset, MVT::i8);
427 
428  unsigned i = 0;
429 
430  while (!MI.getOperand(i).isFI()) {
431  ++i;
432  assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
433  }
434  const MachineFunction *MF = MI.getParent()->getParent();
435  const AArch64InstrInfo *TII =
436  MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
437  bool Done = rewriteAArch64FrameIndex(MI, i, BaseReg, Off, TII);
438  assert(Done && "Unable to resolve frame index!");
439  (void)Done;
440 }
441 
443  int SPAdj, unsigned FIOperandNum,
444  RegScavenger *RS) const {
445  assert(SPAdj == 0 && "Unexpected");
446 
447  MachineInstr &MI = *II;
448  MachineBasicBlock &MBB = *MI.getParent();
449  MachineFunction &MF = *MBB.getParent();
450  const MachineFrameInfo &MFI = MF.getFrameInfo();
451  const AArch64InstrInfo *TII =
452  MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
453  const AArch64FrameLowering *TFI = getFrameLowering(MF);
454 
455  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
456  bool Tagged =
457  MI.getOperand(FIOperandNum).getTargetFlags() & AArch64II::MO_TAGGED;
458  unsigned FrameReg;
459 
460  // Special handling of dbg_value, stackmap and patchpoint instructions.
461  if (MI.isDebugValue() || MI.getOpcode() == TargetOpcode::STACKMAP ||
462  MI.getOpcode() == TargetOpcode::PATCHPOINT) {
464  TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg,
465  /*PreferFP=*/true,
466  /*ForSimm=*/false);
467  Offset += StackOffset(MI.getOperand(FIOperandNum + 1).getImm(), MVT::i8);
468  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
469  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getBytes());
470  return;
471  }
472 
473  if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) {
474  MachineOperand &FI = MI.getOperand(FIOperandNum);
475  int Offset = TFI->getNonLocalFrameIndexReference(MF, FrameIndex);
476  FI.ChangeToImmediate(Offset);
477  return;
478  }
479 
481  if (MI.getOpcode() == AArch64::TAGPstack) {
482  // TAGPstack must use the virtual frame register in its 3rd operand.
484  FrameReg = MI.getOperand(3).getReg();
485  Offset = {MFI.getObjectOffset(FrameIndex) +
487  MVT::i8};
488  } else if (Tagged) {
489  StackOffset SPOffset = {
490  MFI.getObjectOffset(FrameIndex) + (int64_t)MFI.getStackSize(), MVT::i8};
491  if (MFI.hasVarSizedObjects() ||
492  isAArch64FrameOffsetLegal(MI, SPOffset, nullptr, nullptr, nullptr) !=
494  // Can't update to SP + offset in place. Precalculate the tagged pointer
495  // in a scratch register.
496  Offset = TFI->resolveFrameIndexReference(
497  MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
498  Register ScratchReg =
499  MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
500  emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset,
501  TII);
502  BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(AArch64::LDG), ScratchReg)
503  .addReg(ScratchReg)
504  .addReg(ScratchReg)
505  .addImm(0);
506  MI.getOperand(FIOperandNum)
507  .ChangeToRegister(ScratchReg, false, false, true);
508  return;
509  }
510  FrameReg = AArch64::SP;
511  Offset = {MFI.getObjectOffset(FrameIndex) + (int64_t)MFI.getStackSize(),
512  MVT::i8};
513  } else {
514  Offset = TFI->resolveFrameIndexReference(
515  MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
516  }
517 
518  // Modify MI as necessary to handle as much of 'Offset' as possible
519  if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
520  return;
521 
522  assert((!RS || !RS->isScavengingFrameIndex(FrameIndex)) &&
523  "Emergency spill slot is out of reach");
524 
525  // If we get here, the immediate doesn't fit into the instruction. We folded
526  // as much as possible above. Handle the rest, providing a register that is
527  // SP+LargeImm.
528  Register ScratchReg =
529  MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
530  emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset, TII);
531  MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg, false, false, true);
532 }
533 
535  MachineFunction &MF) const {
536  const AArch64FrameLowering *TFI = getFrameLowering(MF);
537 
538  switch (RC->getID()) {
539  default:
540  return 0;
541  case AArch64::GPR32RegClassID:
542  case AArch64::GPR32spRegClassID:
543  case AArch64::GPR32allRegClassID:
544  case AArch64::GPR64spRegClassID:
545  case AArch64::GPR64allRegClassID:
546  case AArch64::GPR64RegClassID:
547  case AArch64::GPR32commonRegClassID:
548  case AArch64::GPR64commonRegClassID:
549  return 32 - 1 // XZR/SP
550  - (TFI->hasFP(MF) || TT.isOSDarwin()) // FP
552  - hasBasePointer(MF); // X19
553  case AArch64::FPR8RegClassID:
554  case AArch64::FPR16RegClassID:
555  case AArch64::FPR32RegClassID:
556  case AArch64::FPR64RegClassID:
557  case AArch64::FPR128RegClassID:
558  return 32;
559 
560  case AArch64::DDRegClassID:
561  case AArch64::DDDRegClassID:
562  case AArch64::DDDDRegClassID:
563  case AArch64::QQRegClassID:
564  case AArch64::QQQRegClassID:
565  case AArch64::QQQQRegClassID:
566  return 32;
567 
568  case AArch64::FPR128_loRegClassID:
569  return 16;
570  }
571 }
572 
574  const MachineFunction &MF) const {
575  const auto &MFI = MF.getFrameInfo();
576  if (!MF.hasEHFunclets() && !MFI.hasVarSizedObjects())
577  return AArch64::SP;
578  else if (needsStackRealignment(MF))
579  return getBaseRegister();
580  return getFrameRegister(MF);
581 }
unsigned getTargetFlags() const
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
Definition: Triple.h:481
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
Calling convention between AArch64 SVE functions.
Definition: CallingConv.h:231
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
StackOffset is a wrapper around scalable and non-scalable offsets and is used in several functions su...
Diagnostic information for unsupported feature in backend.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:224
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:623
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
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)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
void push_back(const T &Elt)
Definition: SmallVector.h:211
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:385
bool cannotEliminateFrame(const MachineFunction &MF) const
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:179
int64_t getLocalFrameSize() const
Get the size of the local object blob.
unsigned Reg
Offset can apply, at least partly.
bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, int64_t Offset) const override
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:323
A debug info location.
Definition: DebugLoc.h:33
F(f)
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset, bool *OutUseUnscaledOp=nullptr, unsigned *OutUnscaledOp=nullptr, int *EmittableOffset=nullptr)
Check if the Offset is a valid frame offset for MI.
bool isAnyArgRegReserved(const MachineFunction &MF) const
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:414
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
unsigned SubReg
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
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 ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
unsigned getID() const
Return the register class ID number.
const uint32_t * getNoPreservedMask() const override
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
AArch64RegisterInfo(const Triple &TT)
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:223
bool isXRegisterReserved(size_t i) const
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
int64_t getBytes() const
Returns the non-scalable part of the offset in bytes.
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
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 ==...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
int getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const override
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
void materializeFrameBaseRegister(MachineBasicBlock *MBB, unsigned BaseReg, 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 ...
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...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const AArch64TargetLowering * getTargetLowering() const override
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:844
StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg, bool PreferFP, bool ForSimm) const
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
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.
bool hasEHFunclets() const
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
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:1172
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that &#39;returned&#39; is on...
Register getFrameRegister(const MachineFunction &MF) const override
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
void setCalleeSavedRegs(ArrayRef< MCPhysReg > CSRs)
Sets the updated Callee Saved Registers list.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const MachineInstrBuilder & addFrameIndex(int Idx) const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:205
MCSubRegIterator enumerates all sub-registers of Reg.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:212
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
uint32_t * allocateRegMask()
Allocate and initialize a register mask with NumRegister bits.
void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, int64_t Offset) const override
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const override
unsigned getNumXRegisterReserved() const
void UpdateCustomCallPreservedMask(MachineFunction &MF, const uint32_t **Mask) const
const uint32_t * getWindowsStackProbePreservedMask() const
Stack probing calls preserve different CSRs to the normal CC.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
bool isReservedReg(const MachineFunction &MF, unsigned Reg) const
Representation of each machine instruction.
Definition: MachineInstr.h:64
BitVector getReservedRegs(const MachineFunction &MF) const override
void UpdateCustomCalleeSavedRegs(MachineFunction &MF) const
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
void emitReservedArgRegCallError(const MachineFunction &MF) const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getLocalAddressRegister(const MachineFunction &MF) const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetOptions Options
#define I(x, y, z)
Definition: MD5.cpp:58
void ChangeToRegister(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
bool useFPForScavengingIndex(const MachineFunction &MF) const override
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool requiresRegisterScavenging(const MachineFunction &MF) const override
const uint32_t * getTLSCallPreservedMask() const
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:831
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isConstantPhysReg(unsigned PhysReg) const override
bool hasBasePointer(const MachineFunction &MF) const
bool isXRegCustomCalleeSaved(size_t i) const
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
IRTranslator LLVM IR MI
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
needsFrameBaseReg - Returns true if the instruction&#39;s frame index reference would be better served by...
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, StackOffset &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access &#39;Offset&#39; bytes from the FP.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isAsmClobberable(const MachineFunction &MF, unsigned PhysReg) const override
Wrapper class representing virtual and physical registers.
Definition: Register.h:19