LLVM  4.0.0
AArch64RegisterBankInfo.cpp
Go to the documentation of this file.
1 //===- AArch64RegisterBankInfo.cpp -------------------------------*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements the targeting of the RegisterBankInfo class for
11 /// AArch64.
12 /// \todo This should be generated by TableGen.
13 //===----------------------------------------------------------------------===//
14 
16 #include "AArch64InstrInfo.h" // For XXXRegClassID.
23 
24 // This file will be TableGen'ed at some point.
25 #include "AArch64GenRegisterBankInfo.def"
26 
27 using namespace llvm;
28 
29 #ifndef LLVM_BUILD_GLOBAL_ISEL
30 #error "You shouldn't build this"
31 #endif
32 
34  : RegisterBankInfo(AArch64::RegBanks, AArch64::NumRegisterBanks) {
35  static bool AlreadyInit = false;
36  // We have only one set of register banks, whatever the subtarget
37  // is. Therefore, the initialization of the RegBanks table should be
38  // done only once. Indeed the table of all register banks
39  // (AArch64::RegBanks) is unique in the compiler. At some point, it
40  // will get tablegen'ed and the whole constructor becomes empty.
41  if (AlreadyInit)
42  return;
43  AlreadyInit = true;
44 
46  (void)RBGPR;
47  assert(&AArch64::GPRRegBank == &RBGPR &&
48  "The order in RegBanks is messed up");
49 
51  (void)RBFPR;
52  assert(&AArch64::FPRRegBank == &RBFPR &&
53  "The order in RegBanks is messed up");
54 
56  (void)RBCCR;
57  assert(&AArch64::CCRRegBank == &RBCCR &&
58  "The order in RegBanks is messed up");
59 
60  // The GPR register bank is fully defined by all the registers in
61  // GR64all + its subclasses.
62  assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
63  "Subclass not added?");
64  assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
65 
66  // The FPR register bank is fully defined by all the registers in
67  // GR64all + its subclasses.
68  assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
69  "Subclass not added?");
70  assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
71  "Subclass not added?");
72  assert(RBFPR.getSize() == 512 &&
73  "FPRs should hold up to 512-bit via QQQQ sequence");
74 
75  assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
76  "Class not added?");
77  assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
78 
79  // Check that the TableGen'ed like file is in sync we our expectations.
80  // First, the Idx.
81  assert(AArch64::PartialMappingIdx::PMI_GPR32 ==
82  AArch64::PartialMappingIdx::PMI_FirstGPR &&
83  "GPR32 index not first in the GPR list");
84  assert(AArch64::PartialMappingIdx::PMI_GPR64 ==
85  AArch64::PartialMappingIdx::PMI_LastGPR &&
86  "GPR64 index not last in the GPR list");
87  assert(AArch64::PartialMappingIdx::PMI_FirstGPR <=
88  AArch64::PartialMappingIdx::PMI_LastGPR &&
89  "GPR list is backward");
90  assert(AArch64::PartialMappingIdx::PMI_FPR32 ==
91  AArch64::PartialMappingIdx::PMI_FirstFPR &&
92  "FPR32 index not first in the FPR list");
93  assert(AArch64::PartialMappingIdx::PMI_FPR512 ==
94  AArch64::PartialMappingIdx::PMI_LastFPR &&
95  "FPR512 index not last in the FPR list");
96  assert(AArch64::PartialMappingIdx::PMI_FirstFPR <=
97  AArch64::PartialMappingIdx::PMI_LastFPR &&
98  "FPR list is backward");
99  assert(AArch64::PartialMappingIdx::PMI_FPR32 + 1 ==
100  AArch64::PartialMappingIdx::PMI_FPR64 &&
101  AArch64::PartialMappingIdx::PMI_FPR64 + 1 ==
102  AArch64::PartialMappingIdx::PMI_FPR128 &&
103  AArch64::PartialMappingIdx::PMI_FPR128 + 1 ==
104  AArch64::PartialMappingIdx::PMI_FPR256 &&
105  AArch64::PartialMappingIdx::PMI_FPR256 + 1 ==
106  AArch64::PartialMappingIdx::PMI_FPR512 &&
107  "FPR indices not properly ordered");
108 // Now, the content.
109 // Check partial mapping.
110 #define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB) \
111  do { \
112  const PartialMapping &Map = \
113  AArch64::PartMappings[AArch64::PartialMappingIdx::Idx - \
114  AArch64::PartialMappingIdx::PMI_Min]; \
115  (void)Map; \
116  assert(Map.StartIdx == ValStartIdx && Map.Length == ValLength && \
117  Map.RegBank == &RB && #Idx " is incorrectly initialized"); \
118  } while (0)
119 
120  CHECK_PARTIALMAP(PMI_GPR32, 0, 32, RBGPR);
121  CHECK_PARTIALMAP(PMI_GPR64, 0, 64, RBGPR);
122  CHECK_PARTIALMAP(PMI_FPR32, 0, 32, RBFPR);
123  CHECK_PARTIALMAP(PMI_FPR64, 0, 64, RBFPR);
124  CHECK_PARTIALMAP(PMI_FPR128, 0, 128, RBFPR);
125  CHECK_PARTIALMAP(PMI_FPR256, 0, 256, RBFPR);
126  CHECK_PARTIALMAP(PMI_FPR512, 0, 512, RBFPR);
127 
128 // Check value mapping.
129 #define CHECK_VALUEMAP_IMPL(RBName, Size, Offset) \
130  do { \
131  unsigned PartialMapBaseIdx = \
132  AArch64::PartialMappingIdx::PMI_##RBName##Size - \
133  AArch64::PartialMappingIdx::PMI_Min; \
134  (void)PartialMapBaseIdx; \
135  const ValueMapping &Map = AArch64::getValueMapping( \
136  AArch64::PartialMappingIdx::PMI_First##RBName, Size)[Offset]; \
137  (void)Map; \
138  assert(Map.BreakDown == &AArch64::PartMappings[PartialMapBaseIdx] && \
139  Map.NumBreakDowns == 1 && #RBName #Size \
140  " " #Offset " is incorrectly initialized"); \
141  } while (0)
142 
143 #define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
144 
145  CHECK_VALUEMAP(GPR, 32);
146  CHECK_VALUEMAP(GPR, 64);
147  CHECK_VALUEMAP(FPR, 32);
148  CHECK_VALUEMAP(FPR, 64);
149  CHECK_VALUEMAP(FPR, 128);
150  CHECK_VALUEMAP(FPR, 256);
151  CHECK_VALUEMAP(FPR, 512);
152 
153 // Check the value mapping for 3-operands instructions where all the operands
154 // map to the same value mapping.
155 #define CHECK_VALUEMAP_3OPS(RBName, Size) \
156  do { \
157  CHECK_VALUEMAP_IMPL(RBName, Size, 0); \
158  CHECK_VALUEMAP_IMPL(RBName, Size, 1); \
159  CHECK_VALUEMAP_IMPL(RBName, Size, 2); \
160  } while (0)
161 
166  CHECK_VALUEMAP_3OPS(FPR, 128);
167  CHECK_VALUEMAP_3OPS(FPR, 256);
168  CHECK_VALUEMAP_3OPS(FPR, 512);
169 
170 #define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size) \
171  do { \
172  unsigned PartialMapDstIdx = \
173  AArch64::PMI_##RBNameDst##Size - AArch64::PMI_Min; \
174  unsigned PartialMapSrcIdx = \
175  AArch64::PMI_##RBNameSrc##Size - AArch64::PMI_Min; \
176  (void) PartialMapDstIdx; \
177  (void) PartialMapSrcIdx; \
178  const ValueMapping *Map = AArch64::getCopyMapping( \
179  AArch64::PMI_First##RBNameDst == AArch64::PMI_FirstGPR, \
180  AArch64::PMI_First##RBNameSrc == AArch64::PMI_FirstGPR, Size); \
181  (void) Map; \
182  assert(Map[0].BreakDown == &AArch64::PartMappings[PartialMapDstIdx] && \
183  Map[0].NumBreakDowns == 1 && #RBNameDst #Size \
184  " Dst is incorrectly initialized"); \
185  assert(Map[1].BreakDown == &AArch64::PartMappings[PartialMapSrcIdx] && \
186  Map[1].NumBreakDowns == 1 && #RBNameSrc #Size \
187  " Src is incorrectly initialized"); \
188  \
189  } while (0)
190 
199 
200  assert(verify(TRI) && "Invalid register bank information");
201 }
202 
204  const RegisterBank &B,
205  unsigned Size) const {
206  // What do we do with different size?
207  // copy are same size.
208  // Will introduce other hooks for different size:
209  // * extract cost.
210  // * build_sequence cost.
211 
212  // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
213  // FIXME: This should be deduced from the scheduling model.
214  if (&A == &AArch64::GPRRegBank && &B == &AArch64::FPRRegBank)
215  // FMOVXDr or FMOVWSr.
216  return 5;
217  if (&A == &AArch64::FPRRegBank && &B == &AArch64::GPRRegBank)
218  // FMOVDXr or FMOVSWr.
219  return 4;
220 
221  return RegisterBankInfo::copyCost(A, B, Size);
222 }
223 
225  const TargetRegisterClass &RC) const {
226  switch (RC.getID()) {
227  case AArch64::FPR8RegClassID:
228  case AArch64::FPR16RegClassID:
229  case AArch64::FPR32RegClassID:
230  case AArch64::FPR64RegClassID:
231  case AArch64::FPR128RegClassID:
232  case AArch64::FPR128_loRegClassID:
233  case AArch64::DDRegClassID:
234  case AArch64::DDDRegClassID:
235  case AArch64::DDDDRegClassID:
236  case AArch64::QQRegClassID:
237  case AArch64::QQQRegClassID:
238  case AArch64::QQQQRegClassID:
240  case AArch64::GPR32commonRegClassID:
241  case AArch64::GPR32RegClassID:
242  case AArch64::GPR32spRegClassID:
243  case AArch64::GPR32sponlyRegClassID:
244  case AArch64::GPR32allRegClassID:
245  case AArch64::GPR64commonRegClassID:
246  case AArch64::GPR64RegClassID:
247  case AArch64::GPR64spRegClassID:
248  case AArch64::GPR64sponlyRegClassID:
249  case AArch64::GPR64allRegClassID:
250  case AArch64::tcGPR64RegClassID:
251  case AArch64::WSeqPairsClassRegClassID:
252  case AArch64::XSeqPairsClassRegClassID:
254  case AArch64::CCRRegClassID:
256  default:
257  llvm_unreachable("Register class not supported");
258  }
259 }
260 
263  const MachineInstr &MI) const {
264  const MachineFunction &MF = *MI.getParent()->getParent();
265  const TargetSubtargetInfo &STI = MF.getSubtarget();
266  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
267  const MachineRegisterInfo &MRI = MF.getRegInfo();
268 
269  switch (MI.getOpcode()) {
270  case TargetOpcode::G_OR: {
271  // 32 and 64-bit or can be mapped on either FPR or
272  // GPR for the same cost.
273  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
274  if (Size != 32 && Size != 64)
275  break;
276 
277  // If the instruction has any implicit-defs or uses,
278  // do not mess with it.
279  if (MI.getNumOperands() != 3)
280  break;
281  InstructionMappings AltMappings;
282  InstructionMapping GPRMapping(
283  /*ID*/ 1, /*Cost*/ 1,
284  AArch64::getValueMapping(AArch64::PMI_FirstGPR, Size),
285  /*NumOperands*/ 3);
286  InstructionMapping FPRMapping(
287  /*ID*/ 2, /*Cost*/ 1,
288  AArch64::getValueMapping(AArch64::PMI_FirstFPR, Size),
289  /*NumOperands*/ 3);
290 
291  AltMappings.emplace_back(std::move(GPRMapping));
292  AltMappings.emplace_back(std::move(FPRMapping));
293  return AltMappings;
294  }
295  case TargetOpcode::G_BITCAST: {
296  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
297  if (Size != 32 && Size != 64)
298  break;
299 
300  // If the instruction has any implicit-defs or uses,
301  // do not mess with it.
302  if (MI.getNumOperands() != 2)
303  break;
304 
305  InstructionMappings AltMappings;
306  InstructionMapping GPRMapping(
307  /*ID*/ 1, /*Cost*/ 1,
308  AArch64::getCopyMapping(/*DstIsGPR*/ true, /*SrcIsGPR*/ true, Size),
309  /*NumOperands*/ 2);
310  InstructionMapping FPRMapping(
311  /*ID*/ 2, /*Cost*/ 1,
312  AArch64::getCopyMapping(/*DstIsGPR*/ false, /*SrcIsGPR*/ false, Size),
313  /*NumOperands*/ 2);
314  InstructionMapping GPRToFPRMapping(
315  /*ID*/ 3,
317  AArch64::getCopyMapping(/*DstIsGPR*/ false, /*SrcIsGPR*/ true, Size),
318  /*NumOperands*/ 2);
319  InstructionMapping FPRToGPRMapping(
320  /*ID*/ 3,
322  AArch64::getCopyMapping(/*DstIsGPR*/ true, /*SrcIsGPR*/ false, Size),
323  /*NumOperands*/ 2);
324 
325  AltMappings.emplace_back(std::move(GPRMapping));
326  AltMappings.emplace_back(std::move(FPRMapping));
327  AltMappings.emplace_back(std::move(GPRToFPRMapping));
328  AltMappings.emplace_back(std::move(FPRToGPRMapping));
329  return AltMappings;
330  }
331  case TargetOpcode::G_LOAD: {
332  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
333  if (Size != 64)
334  break;
335 
336  // If the instruction has any implicit-defs or uses,
337  // do not mess with it.
338  if (MI.getNumOperands() != 2)
339  break;
340 
341  InstructionMappings AltMappings;
342  InstructionMapping GPRMapping(
343  /*ID*/ 1, /*Cost*/ 1,
345  {AArch64::getValueMapping(AArch64::PMI_FirstGPR, Size),
346  // Addresses are GPR 64-bit.
347  AArch64::getValueMapping(AArch64::PMI_FirstGPR, 64)}),
348  /*NumOperands*/ 2);
349  InstructionMapping FPRMapping(
350  /*ID*/ 2, /*Cost*/ 1,
352  {AArch64::getValueMapping(AArch64::PMI_FirstFPR, Size),
353  // Addresses are GPR 64-bit.
354  AArch64::getValueMapping(AArch64::PMI_FirstGPR, 64)}),
355  /*NumOperands*/ 2);
356 
357  AltMappings.emplace_back(std::move(GPRMapping));
358  AltMappings.emplace_back(std::move(FPRMapping));
359  return AltMappings;
360  }
361  default:
362  break;
363  }
365 }
366 
367 void AArch64RegisterBankInfo::applyMappingImpl(
368  const OperandsMapper &OpdMapper) const {
369  switch (OpdMapper.getMI().getOpcode()) {
370  case TargetOpcode::G_OR:
371  case TargetOpcode::G_BITCAST:
372  case TargetOpcode::G_LOAD: {
373  // Those ID must match getInstrAlternativeMappings.
374  assert((OpdMapper.getInstrMapping().getID() >= 1 &&
375  OpdMapper.getInstrMapping().getID() <= 4) &&
376  "Don't know how to handle that ID");
377  return applyDefaultMapping(OpdMapper);
378  }
379  default:
380  llvm_unreachable("Don't know how to handle that operation");
381  }
382 }
383 
384 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
385 /// having only floating-point operands.
386 static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
387  switch (Opc) {
388  case TargetOpcode::G_FADD:
389  case TargetOpcode::G_FSUB:
390  case TargetOpcode::G_FMUL:
391  case TargetOpcode::G_FDIV:
392  case TargetOpcode::G_FCONSTANT:
393  case TargetOpcode::G_FPEXT:
394  case TargetOpcode::G_FPTRUNC:
395  return true;
396  }
397  return false;
398 }
399 
401 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) {
402  const unsigned Opc = MI.getOpcode();
403  const MachineFunction &MF = *MI.getParent()->getParent();
404  const MachineRegisterInfo &MRI = MF.getRegInfo();
405 
406  unsigned NumOperands = MI.getNumOperands();
407  assert(NumOperands <= 3 &&
408  "This code is for instructions with 3 or less operands");
409 
410  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
411  unsigned Size = Ty.getSizeInBits();
412  bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
413 
414 #ifndef NDEBUG
415  // Make sure all the operands are using similar size and type.
416  // Should probably be checked by the machine verifier.
417  // This code won't catch cases where the number of lanes is
418  // different between the operands.
419  // If we want to go to that level of details, it is probably
420  // best to check that the types are the same, period.
421  // Currently, we just check that the register banks are the same
422  // for each types.
423  for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
424  LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
425  assert(AArch64::getRegBankBaseIdxOffset(OpTy.getSizeInBits()) ==
426  AArch64::getRegBankBaseIdxOffset(Size) &&
427  "Operand has incompatible size");
428  bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
429  (void)OpIsFPR;
430  assert(IsFPR == OpIsFPR && "Operand has incompatible type");
431  }
432 #endif // End NDEBUG.
433 
434  AArch64::PartialMappingIdx RBIdx =
435  IsFPR ? AArch64::PMI_FirstFPR : AArch64::PMI_FirstGPR;
436 
438  AArch64::getValueMapping(RBIdx, Size), NumOperands};
439 }
440 
443  const unsigned Opc = MI.getOpcode();
444  const MachineFunction &MF = *MI.getParent()->getParent();
445  const MachineRegisterInfo &MRI = MF.getRegInfo();
446 
447  // Try the default logic for non-generic instructions that are either copies
448  // or already have some operands assigned to banks.
449  if (!isPreISelGenericOpcode(Opc)) {
451  if (Mapping.isValid())
452  return Mapping;
453  }
454 
455  switch (Opc) {
456  // G_{F|S|U}REM are not listed because they are not legal.
457  // Arithmetic ops.
458  case TargetOpcode::G_ADD:
459  case TargetOpcode::G_SUB:
460  case TargetOpcode::G_GEP:
461  case TargetOpcode::G_MUL:
462  case TargetOpcode::G_SDIV:
463  case TargetOpcode::G_UDIV:
464  // Bitwise ops.
465  case TargetOpcode::G_AND:
466  case TargetOpcode::G_OR:
467  case TargetOpcode::G_XOR:
468  // Shifts.
469  case TargetOpcode::G_SHL:
470  case TargetOpcode::G_LSHR:
471  case TargetOpcode::G_ASHR:
472  // Floating point ops.
473  case TargetOpcode::G_FADD:
474  case TargetOpcode::G_FSUB:
475  case TargetOpcode::G_FMUL:
476  case TargetOpcode::G_FDIV:
477  return getSameKindOfOperandsMapping(MI);
478  case TargetOpcode::G_BITCAST: {
479  LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
480  LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
481  unsigned Size = DstTy.getSizeInBits();
482  bool DstIsGPR = !DstTy.isVector();
483  bool SrcIsGPR = !SrcTy.isVector();
484  const RegisterBank &DstRB =
486  const RegisterBank &SrcRB =
488  return InstructionMapping{DefaultMappingID, copyCost(DstRB, SrcRB, Size),
489  AArch64::getCopyMapping(DstIsGPR, SrcIsGPR, Size),
490  /*NumOperands*/ 2};
491  }
492  case TargetOpcode::G_SEQUENCE:
493  // FIXME: support this, but the generic code is really not going to do
494  // anything sane.
495  return InstructionMapping();
496  default:
497  break;
498  }
499 
500  unsigned NumOperands = MI.getNumOperands();
501 
502  // Track the size and bank of each register. We don't do partial mappings.
503  SmallVector<unsigned, 4> OpSize(NumOperands);
504  SmallVector<AArch64::PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
505  for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
506  auto &MO = MI.getOperand(Idx);
507  if (!MO.isReg())
508  continue;
509 
510  LLT Ty = MRI.getType(MO.getReg());
511  OpSize[Idx] = Ty.getSizeInBits();
512 
513  // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
514  // For floating-point instructions, scalars go in FPRs.
516  OpRegBankIdx[Idx] = AArch64::PMI_FirstFPR;
517  else
518  OpRegBankIdx[Idx] = AArch64::PMI_FirstGPR;
519  }
520 
521  unsigned Cost = 1;
522  // Some of the floating-point instructions have mixed GPR and FPR operands:
523  // fine-tune the computed mapping.
524  switch (Opc) {
525  case TargetOpcode::G_SITOFP:
526  case TargetOpcode::G_UITOFP: {
527  OpRegBankIdx = {AArch64::PMI_FirstFPR, AArch64::PMI_FirstGPR};
528  break;
529  }
530  case TargetOpcode::G_FPTOSI:
531  case TargetOpcode::G_FPTOUI: {
532  OpRegBankIdx = {AArch64::PMI_FirstGPR, AArch64::PMI_FirstFPR};
533  break;
534  }
535  case TargetOpcode::G_FCMP: {
536  OpRegBankIdx = {AArch64::PMI_FirstGPR,
537  /* Predicate */ AArch64::PMI_None, AArch64::PMI_FirstFPR,
538  AArch64::PMI_FirstFPR};
539  break;
540  }
541  case TargetOpcode::G_BITCAST: {
542  // This is going to be a cross register bank copy and this is expensive.
543  if (OpRegBankIdx[0] != OpRegBankIdx[1])
544  Cost =
545  copyCost(*AArch64::PartMappings[OpRegBankIdx[0]].RegBank,
546  *AArch64::PartMappings[OpRegBankIdx[1]].RegBank, OpSize[0]);
547  break;
548  }
549  case TargetOpcode::G_LOAD: {
550  // Loading in vector unit is slightly more expensive.
551  // This is actually only true for the LD1R and co instructions,
552  // but anyway for the fast mode this number does not matter and
553  // for the greedy mode the cost of the cross bank copy will
554  // offset this number.
555  // FIXME: Should be derived from the scheduling model.
556  if (OpRegBankIdx[0] >= AArch64::PMI_FirstFPR)
557  Cost = 2;
558  }
559  }
560 
561  // Finally construct the computed mapping.
563  InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands};
564  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
565  for (unsigned Idx = 0; Idx < NumOperands; ++Idx)
566  if (MI.getOperand(Idx).isReg())
567  OpdsMapping[Idx] =
568  AArch64::getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
569 
570  Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
571  return Mapping;
572 }
RegisterBank FPRRegBank
AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
void setOperandsMapping(const ValueMapping *OpdsMapping)
Set the mapping for all the operands.
RegisterBank ** RegBanks
Hold the set of supported register banks.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
virtual unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
const ValueMapping & getValueMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const
Methods to get a uniquely generated ValueMapping.
class llvm::RegisterBankInfo GPR
Helper class that represents how the value of an instruction may be mapped and what is the related co...
unsigned getID() const
Return the register class ID number.
#define CHECK_VALUEMAP(RBName, Size)
This file declares the targeting of the RegisterBankInfo class for AArch64.
Holds all the information related to register banks.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:277
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
#define CHECK_VALUEMAP_3OPS(RBName, Size)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments, on Darwin.
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Methods to get a uniquely generated array of ValueMapping.
InstructionMapping getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:131
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
unsigned const MachineRegisterInfo * MRI
static unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
Get the size in bits of Reg.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
Conditional register: NZCV.
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const override
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
#define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)
This class implements the register bank concept.
Definition: RegisterBank.h:29
RegisterBank GPRRegBank
static bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel...
Definition: TargetOpcodes.h:31
const InstructionMapping & getInstrMapping() const
The final mapping of the instruction.
bool isValid() const
Check whether this object is valid.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
Definition: MachineInstr.h:52
void emplace_back(ArgTypes &&...Args)
Definition: SmallVector.h:635
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getSize() const
Get the maximal size in bits that fits in this register bank.
Definition: RegisterBank.h:55
bool covers(const TargetRegisterClass &RC) const
Check whether this register bank covers RC.
unsigned getReg() const
getReg - Returns the register number.
Floating Point/Vector Registers: B, H, S, D, Q.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)
RegisterBank CCRRegBank
General Purpose Registers: W, X.
IRTranslator LLVM IR MI
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:104
bool isVector() const
Definition: LowLevelType.h:94
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const override
Get a register bank that covers RC.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
MachineInstr & getMI() const
Getters.