LLVM  13.0.0git
AArch64RegisterBankInfo.cpp
Go to the documentation of this file.
1 //===- AArch64RegisterBankInfo.cpp ----------------------------------------===//
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 /// \file
9 /// This file implements the targeting of the RegisterBankInfo class for
10 /// AArch64.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13 
15 #include "AArch64InstrInfo.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
29 #include <algorithm>
30 #include <cassert>
31 
32 #define GET_TARGET_REGBANK_IMPL
33 #include "AArch64GenRegisterBank.inc"
34 
35 // This file will be TableGen'ed at some point.
36 #include "AArch64GenRegisterBankInfo.def"
37 
38 using namespace llvm;
39 
42  static llvm::once_flag InitializeRegisterBankFlag;
43 
44  static auto InitializeRegisterBankOnce = [&]() {
45  // We have only one set of register banks, whatever the subtarget
46  // is. Therefore, the initialization of the RegBanks table should be
47  // done only once. Indeed the table of all register banks
48  // (AArch64::RegBanks) is unique in the compiler. At some point, it
49  // will get tablegen'ed and the whole constructor becomes empty.
50 
51  const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
52  (void)RBGPR;
53  assert(&AArch64::GPRRegBank == &RBGPR &&
54  "The order in RegBanks is messed up");
55 
56  const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
57  (void)RBFPR;
58  assert(&AArch64::FPRRegBank == &RBFPR &&
59  "The order in RegBanks is messed up");
60 
61  const RegisterBank &RBCCR = getRegBank(AArch64::CCRegBankID);
62  (void)RBCCR;
63  assert(&AArch64::CCRegBank == &RBCCR &&
64  "The order in RegBanks is messed up");
65 
66  // The GPR register bank is fully defined by all the registers in
67  // GR64all + its subclasses.
68  assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
69  "Subclass not added?");
70  assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
71 
72  // The FPR register bank is fully defined by all the registers in
73  // GR64all + its subclasses.
74  assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
75  "Subclass not added?");
76  assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
77  "Subclass not added?");
78  assert(RBFPR.getSize() == 512 &&
79  "FPRs should hold up to 512-bit via QQQQ sequence");
80 
81  assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
82  "Class not added?");
83  assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
84 
85  // Check that the TableGen'ed like file is in sync we our expectations.
86  // First, the Idx.
88  {PMI_GPR32, PMI_GPR64}) &&
89  "PartialMappingIdx's are incorrectly ordered");
93  "PartialMappingIdx's are incorrectly ordered");
94 // Now, the content.
95 // Check partial mapping.
96 #define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB) \
97  do { \
98  assert( \
99  checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \
100  #Idx " is incorrectly initialized"); \
101  } while (false)
102 
103  CHECK_PARTIALMAP(PMI_GPR32, 0, 32, RBGPR);
104  CHECK_PARTIALMAP(PMI_GPR64, 0, 64, RBGPR);
105  CHECK_PARTIALMAP(PMI_FPR16, 0, 16, RBFPR);
106  CHECK_PARTIALMAP(PMI_FPR32, 0, 32, RBFPR);
107  CHECK_PARTIALMAP(PMI_FPR64, 0, 64, RBFPR);
108  CHECK_PARTIALMAP(PMI_FPR128, 0, 128, RBFPR);
109  CHECK_PARTIALMAP(PMI_FPR256, 0, 256, RBFPR);
110  CHECK_PARTIALMAP(PMI_FPR512, 0, 512, RBFPR);
111 
112 // Check value mapping.
113 #define CHECK_VALUEMAP_IMPL(RBName, Size, Offset) \
114  do { \
115  assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size, \
116  PartialMappingIdx::PMI_First##RBName, Size, \
117  Offset) && \
118  #RBName #Size " " #Offset " is incorrectly initialized"); \
119  } while (false)
120 
121 #define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
122 
123  CHECK_VALUEMAP(GPR, 32);
124  CHECK_VALUEMAP(GPR, 64);
125  CHECK_VALUEMAP(FPR, 16);
126  CHECK_VALUEMAP(FPR, 32);
127  CHECK_VALUEMAP(FPR, 64);
128  CHECK_VALUEMAP(FPR, 128);
129  CHECK_VALUEMAP(FPR, 256);
130  CHECK_VALUEMAP(FPR, 512);
131 
132 // Check the value mapping for 3-operands instructions where all the operands
133 // map to the same value mapping.
134 #define CHECK_VALUEMAP_3OPS(RBName, Size) \
135  do { \
136  CHECK_VALUEMAP_IMPL(RBName, Size, 0); \
137  CHECK_VALUEMAP_IMPL(RBName, Size, 1); \
138  CHECK_VALUEMAP_IMPL(RBName, Size, 2); \
139  } while (false)
140 
141  CHECK_VALUEMAP_3OPS(GPR, 32);
142  CHECK_VALUEMAP_3OPS(GPR, 64);
145  CHECK_VALUEMAP_3OPS(FPR, 128);
146  CHECK_VALUEMAP_3OPS(FPR, 256);
147  CHECK_VALUEMAP_3OPS(FPR, 512);
148 
149 #define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size) \
150  do { \
151  unsigned PartialMapDstIdx = PMI_##RBNameDst##Size - PMI_Min; \
152  unsigned PartialMapSrcIdx = PMI_##RBNameSrc##Size - PMI_Min; \
153  (void)PartialMapDstIdx; \
154  (void)PartialMapSrcIdx; \
155  const ValueMapping *Map = getCopyMapping( \
156  AArch64::RBNameDst##RegBankID, AArch64::RBNameSrc##RegBankID, Size); \
157  (void)Map; \
158  assert(Map[0].BreakDown == \
159  &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \
160  Map[0].NumBreakDowns == 1 && #RBNameDst #Size \
161  " Dst is incorrectly initialized"); \
162  assert(Map[1].BreakDown == \
163  &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \
164  Map[1].NumBreakDowns == 1 && #RBNameSrc #Size \
165  " Src is incorrectly initialized"); \
166  \
167  } while (false)
168 
169  CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 32);
171  CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 64);
177 
178 #define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize) \
179  do { \
180  unsigned PartialMapDstIdx = PMI_FPR##DstSize - PMI_Min; \
181  unsigned PartialMapSrcIdx = PMI_FPR##SrcSize - PMI_Min; \
182  (void)PartialMapDstIdx; \
183  (void)PartialMapSrcIdx; \
184  const ValueMapping *Map = getFPExtMapping(DstSize, SrcSize); \
185  (void)Map; \
186  assert(Map[0].BreakDown == \
187  &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \
188  Map[0].NumBreakDowns == 1 && "FPR" #DstSize \
189  " Dst is incorrectly initialized"); \
190  assert(Map[1].BreakDown == \
191  &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \
192  Map[1].NumBreakDowns == 1 && "FPR" #SrcSize \
193  " Src is incorrectly initialized"); \
194  \
195  } while (false)
196 
197  CHECK_VALUEMAP_FPEXT(32, 16);
198  CHECK_VALUEMAP_FPEXT(64, 16);
199  CHECK_VALUEMAP_FPEXT(64, 32);
200  CHECK_VALUEMAP_FPEXT(128, 64);
201 
202  assert(verify(TRI) && "Invalid register bank information");
203  };
204 
205  llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce);
206 }
207 
209  const RegisterBank &B,
210  unsigned Size) const {
211  // What do we do with different size?
212  // copy are same size.
213  // Will introduce other hooks for different size:
214  // * extract cost.
215  // * build_sequence cost.
216 
217  // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
218  // FIXME: This should be deduced from the scheduling model.
219  if (&A == &AArch64::GPRRegBank && &B == &AArch64::FPRRegBank)
220  // FMOVXDr or FMOVWSr.
221  return 5;
222  if (&A == &AArch64::FPRRegBank && &B == &AArch64::GPRRegBank)
223  // FMOVDXr or FMOVSWr.
224  return 4;
225 
226  return RegisterBankInfo::copyCost(A, B, Size);
227 }
228 
229 const RegisterBank &
231  LLT) const {
232  switch (RC.getID()) {
233  case AArch64::FPR8RegClassID:
234  case AArch64::FPR16RegClassID:
235  case AArch64::FPR16_loRegClassID:
236  case AArch64::FPR32_with_hsub_in_FPR16_loRegClassID:
237  case AArch64::FPR32RegClassID:
238  case AArch64::FPR64RegClassID:
239  case AArch64::FPR64_loRegClassID:
240  case AArch64::FPR128RegClassID:
241  case AArch64::FPR128_loRegClassID:
242  case AArch64::DDRegClassID:
243  case AArch64::DDDRegClassID:
244  case AArch64::DDDDRegClassID:
245  case AArch64::QQRegClassID:
246  case AArch64::QQQRegClassID:
247  case AArch64::QQQQRegClassID:
248  return getRegBank(AArch64::FPRRegBankID);
249  case AArch64::GPR32commonRegClassID:
250  case AArch64::GPR32RegClassID:
251  case AArch64::GPR32spRegClassID:
252  case AArch64::GPR32sponlyRegClassID:
253  case AArch64::GPR32argRegClassID:
254  case AArch64::GPR32allRegClassID:
255  case AArch64::GPR64commonRegClassID:
256  case AArch64::GPR64RegClassID:
257  case AArch64::GPR64spRegClassID:
258  case AArch64::GPR64sponlyRegClassID:
259  case AArch64::GPR64argRegClassID:
260  case AArch64::GPR64allRegClassID:
261  case AArch64::GPR64noipRegClassID:
262  case AArch64::GPR64common_and_GPR64noipRegClassID:
263  case AArch64::GPR64noip_and_tcGPR64RegClassID:
264  case AArch64::tcGPR64RegClassID:
265  case AArch64::rtcGPR64RegClassID:
266  case AArch64::WSeqPairsClassRegClassID:
267  case AArch64::XSeqPairsClassRegClassID:
268  return getRegBank(AArch64::GPRRegBankID);
269  case AArch64::CCRRegClassID:
270  return getRegBank(AArch64::CCRegBankID);
271  default:
272  llvm_unreachable("Register class not supported");
273  }
274 }
275 
278  const MachineInstr &MI) const {
279  const MachineFunction &MF = *MI.getParent()->getParent();
280  const TargetSubtargetInfo &STI = MF.getSubtarget();
281  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
282  const MachineRegisterInfo &MRI = MF.getRegInfo();
283 
284  switch (MI.getOpcode()) {
285  case TargetOpcode::G_OR: {
286  // 32 and 64-bit or can be mapped on either FPR or
287  // GPR for the same cost.
288  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
289  if (Size != 32 && Size != 64)
290  break;
291 
292  // If the instruction has any implicit-defs or uses,
293  // do not mess with it.
294  if (MI.getNumOperands() != 3)
295  break;
296  InstructionMappings AltMappings;
297  const InstructionMapping &GPRMapping = getInstructionMapping(
298  /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
299  /*NumOperands*/ 3);
300  const InstructionMapping &FPRMapping = getInstructionMapping(
301  /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
302  /*NumOperands*/ 3);
303 
304  AltMappings.push_back(&GPRMapping);
305  AltMappings.push_back(&FPRMapping);
306  return AltMappings;
307  }
308  case TargetOpcode::G_BITCAST: {
309  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
310  if (Size != 32 && Size != 64)
311  break;
312 
313  // If the instruction has any implicit-defs or uses,
314  // do not mess with it.
315  if (MI.getNumOperands() != 2)
316  break;
317 
318  InstructionMappings AltMappings;
319  const InstructionMapping &GPRMapping = getInstructionMapping(
320  /*ID*/ 1, /*Cost*/ 1,
321  getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
322  /*NumOperands*/ 2);
323  const InstructionMapping &FPRMapping = getInstructionMapping(
324  /*ID*/ 2, /*Cost*/ 1,
325  getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
326  /*NumOperands*/ 2);
327  const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
328  /*ID*/ 3,
329  /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
330  getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
331  /*NumOperands*/ 2);
332  const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
333  /*ID*/ 3,
334  /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
335  getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
336  /*NumOperands*/ 2);
337 
338  AltMappings.push_back(&GPRMapping);
339  AltMappings.push_back(&FPRMapping);
340  AltMappings.push_back(&GPRToFPRMapping);
341  AltMappings.push_back(&FPRToGPRMapping);
342  return AltMappings;
343  }
344  case TargetOpcode::G_LOAD: {
345  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
346  if (Size != 64)
347  break;
348 
349  // If the instruction has any implicit-defs or uses,
350  // do not mess with it.
351  if (MI.getNumOperands() != 2)
352  break;
353 
354  InstructionMappings AltMappings;
355  const InstructionMapping &GPRMapping = getInstructionMapping(
356  /*ID*/ 1, /*Cost*/ 1,
358  // Addresses are GPR 64-bit.
360  /*NumOperands*/ 2);
361  const InstructionMapping &FPRMapping = getInstructionMapping(
362  /*ID*/ 2, /*Cost*/ 1,
364  // Addresses are GPR 64-bit.
366  /*NumOperands*/ 2);
367 
368  AltMappings.push_back(&GPRMapping);
369  AltMappings.push_back(&FPRMapping);
370  return AltMappings;
371  }
372  default:
373  break;
374  }
376 }
377 
378 void AArch64RegisterBankInfo::applyMappingImpl(
379  const OperandsMapper &OpdMapper) const {
380  switch (OpdMapper.getMI().getOpcode()) {
381  case TargetOpcode::G_OR:
382  case TargetOpcode::G_BITCAST:
383  case TargetOpcode::G_LOAD:
384  // Those ID must match getInstrAlternativeMappings.
385  assert((OpdMapper.getInstrMapping().getID() >= 1 &&
386  OpdMapper.getInstrMapping().getID() <= 4) &&
387  "Don't know how to handle that ID");
388  return applyDefaultMapping(OpdMapper);
389  default:
390  llvm_unreachable("Don't know how to handle that operation");
391  }
392 }
393 
394 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
395 /// having only floating-point operands.
396 static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
397  switch (Opc) {
398  case TargetOpcode::G_FADD:
399  case TargetOpcode::G_FSUB:
400  case TargetOpcode::G_FMUL:
401  case TargetOpcode::G_FMA:
402  case TargetOpcode::G_FDIV:
403  case TargetOpcode::G_FCONSTANT:
404  case TargetOpcode::G_FPEXT:
405  case TargetOpcode::G_FPTRUNC:
406  case TargetOpcode::G_FCEIL:
407  case TargetOpcode::G_FFLOOR:
408  case TargetOpcode::G_FNEARBYINT:
409  case TargetOpcode::G_FNEG:
410  case TargetOpcode::G_FCOS:
411  case TargetOpcode::G_FSIN:
412  case TargetOpcode::G_FLOG10:
413  case TargetOpcode::G_FLOG:
414  case TargetOpcode::G_FLOG2:
415  case TargetOpcode::G_FSQRT:
416  case TargetOpcode::G_FABS:
417  case TargetOpcode::G_FEXP:
418  case TargetOpcode::G_FRINT:
419  case TargetOpcode::G_INTRINSIC_TRUNC:
420  case TargetOpcode::G_INTRINSIC_ROUND:
421  return true;
422  }
423  return false;
424 }
425 
427 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
428  const MachineInstr &MI) const {
429  const unsigned Opc = MI.getOpcode();
430  const MachineFunction &MF = *MI.getParent()->getParent();
431  const MachineRegisterInfo &MRI = MF.getRegInfo();
432 
433  unsigned NumOperands = MI.getNumOperands();
434  assert(NumOperands <= 3 &&
435  "This code is for instructions with 3 or less operands");
436 
437  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
438  unsigned Size = Ty.getSizeInBits();
439  bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
440 
441  PartialMappingIdx RBIdx = IsFPR ? PMI_FirstFPR : PMI_FirstGPR;
442 
443 #ifndef NDEBUG
444  // Make sure all the operands are using similar size and type.
445  // Should probably be checked by the machine verifier.
446  // This code won't catch cases where the number of lanes is
447  // different between the operands.
448  // If we want to go to that level of details, it is probably
449  // best to check that the types are the same, period.
450  // Currently, we just check that the register banks are the same
451  // for each types.
452  for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
453  LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
454  assert(
456  RBIdx, OpTy.getSizeInBits()) ==
458  "Operand has incompatible size");
459  bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
460  (void)OpIsFPR;
461  assert(IsFPR == OpIsFPR && "Operand has incompatible type");
462  }
463 #endif // End NDEBUG.
464 
466  getValueMapping(RBIdx, Size), NumOperands);
467 }
468 
469 bool AArch64RegisterBankInfo::hasFPConstraints(const MachineInstr &MI,
470  const MachineRegisterInfo &MRI,
471  const TargetRegisterInfo &TRI,
472  unsigned Depth) const {
473  unsigned Op = MI.getOpcode();
474 
475  // Do we have an explicit floating point instruction?
477  return true;
478 
479  // No. Check if we have a copy-like instruction. If we do, then we could
480  // still be fed by floating point instructions.
481  if (Op != TargetOpcode::COPY && !MI.isPHI() &&
483  return false;
484 
485  // Check if we already know the register bank.
486  auto *RB = getRegBank(MI.getOperand(0).getReg(), MRI, TRI);
487  if (RB == &AArch64::FPRRegBank)
488  return true;
489  if (RB == &AArch64::GPRRegBank)
490  return false;
491 
492  // We don't know anything.
493  //
494  // If we have a phi, we may be able to infer that it will be assigned a FPR
495  // based off of its inputs.
496  if (!MI.isPHI() || Depth > MaxFPRSearchDepth)
497  return false;
498 
499  return any_of(MI.explicit_uses(), [&](const MachineOperand &Op) {
500  return Op.isReg() &&
501  onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
502  });
503 }
504 
505 bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
506  const MachineRegisterInfo &MRI,
507  const TargetRegisterInfo &TRI,
508  unsigned Depth) const {
509  switch (MI.getOpcode()) {
510  case TargetOpcode::G_FPTOSI:
511  case TargetOpcode::G_FPTOUI:
512  case TargetOpcode::G_FCMP:
513  return true;
514  default:
515  break;
516  }
517  return hasFPConstraints(MI, MRI, TRI, Depth);
518 }
519 
520 bool AArch64RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
521  const MachineRegisterInfo &MRI,
522  const TargetRegisterInfo &TRI,
523  unsigned Depth) const {
524  switch (MI.getOpcode()) {
525  case AArch64::G_DUP:
526  case TargetOpcode::G_SITOFP:
527  case TargetOpcode::G_UITOFP:
528  case TargetOpcode::G_EXTRACT_VECTOR_ELT:
529  case TargetOpcode::G_INSERT_VECTOR_ELT:
530  case TargetOpcode::G_BUILD_VECTOR:
531  case TargetOpcode::G_BUILD_VECTOR_TRUNC:
532  return true;
533  default:
534  break;
535  }
536  return hasFPConstraints(MI, MRI, TRI, Depth);
537 }
538 
541  const unsigned Opc = MI.getOpcode();
542 
543  // Try the default logic for non-generic instructions that are either copies
544  // or already have some operands assigned to banks.
545  if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opc)) ||
546  Opc == TargetOpcode::G_PHI) {
547  const RegisterBankInfo::InstructionMapping &Mapping =
549  if (Mapping.isValid())
550  return Mapping;
551  }
552 
553  const MachineFunction &MF = *MI.getParent()->getParent();
554  const MachineRegisterInfo &MRI = MF.getRegInfo();
555  const TargetSubtargetInfo &STI = MF.getSubtarget();
556  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
557 
558  switch (Opc) {
559  // G_{F|S|U}REM are not listed because they are not legal.
560  // Arithmetic ops.
561  case TargetOpcode::G_ADD:
562  case TargetOpcode::G_SUB:
563  case TargetOpcode::G_PTR_ADD:
564  case TargetOpcode::G_MUL:
565  case TargetOpcode::G_SDIV:
566  case TargetOpcode::G_UDIV:
567  // Bitwise ops.
568  case TargetOpcode::G_AND:
569  case TargetOpcode::G_OR:
570  case TargetOpcode::G_XOR:
571  // Floating point ops.
572  case TargetOpcode::G_FADD:
573  case TargetOpcode::G_FSUB:
574  case TargetOpcode::G_FMUL:
575  case TargetOpcode::G_FDIV:
576  return getSameKindOfOperandsMapping(MI);
577  case TargetOpcode::G_FPEXT: {
578  LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
579  LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
580  return getInstructionMapping(
581  DefaultMappingID, /*Cost*/ 1,
582  getFPExtMapping(DstTy.getSizeInBits(), SrcTy.getSizeInBits()),
583  /*NumOperands*/ 2);
584  }
585  // Shifts.
586  case TargetOpcode::G_SHL:
587  case TargetOpcode::G_LSHR:
588  case TargetOpcode::G_ASHR: {
589  LLT ShiftAmtTy = MRI.getType(MI.getOperand(2).getReg());
590  LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
591  if (ShiftAmtTy.getSizeInBits() == 64 && SrcTy.getSizeInBits() == 32)
593  &ValMappings[Shift64Imm], 3);
594  return getSameKindOfOperandsMapping(MI);
595  }
596  case TargetOpcode::COPY: {
597  Register DstReg = MI.getOperand(0).getReg();
598  Register SrcReg = MI.getOperand(1).getReg();
599  // Check if one of the register is not a generic register.
600  if ((Register::isPhysicalRegister(DstReg) ||
601  !MRI.getType(DstReg).isValid()) ||
602  (Register::isPhysicalRegister(SrcReg) ||
603  !MRI.getType(SrcReg).isValid())) {
604  const RegisterBank *DstRB = getRegBank(DstReg, MRI, TRI);
605  const RegisterBank *SrcRB = getRegBank(SrcReg, MRI, TRI);
606  if (!DstRB)
607  DstRB = SrcRB;
608  else if (!SrcRB)
609  SrcRB = DstRB;
610  // If both RB are null that means both registers are generic.
611  // We shouldn't be here.
612  assert(DstRB && SrcRB && "Both RegBank were nullptr");
613  unsigned Size = getSizeInBits(DstReg, MRI, TRI);
614  return getInstructionMapping(
615  DefaultMappingID, copyCost(*DstRB, *SrcRB, Size),
616  getCopyMapping(DstRB->getID(), SrcRB->getID(), Size),
617  // We only care about the mapping of the destination.
618  /*NumOperands*/ 1);
619  }
620  // Both registers are generic, use G_BITCAST.
622  }
623  case TargetOpcode::G_BITCAST: {
624  LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
625  LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
626  unsigned Size = DstTy.getSizeInBits();
627  bool DstIsGPR = !DstTy.isVector() && DstTy.getSizeInBits() <= 64;
628  bool SrcIsGPR = !SrcTy.isVector() && SrcTy.getSizeInBits() <= 64;
629  const RegisterBank &DstRB =
630  DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
631  const RegisterBank &SrcRB =
632  SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
633  return getInstructionMapping(
634  DefaultMappingID, copyCost(DstRB, SrcRB, Size),
635  getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
636  // We only care about the mapping of the destination for COPY.
637  /*NumOperands*/ Opc == TargetOpcode::G_BITCAST ? 2 : 1);
638  }
639  default:
640  break;
641  }
642 
643  unsigned NumOperands = MI.getNumOperands();
644 
645  // Track the size and bank of each register. We don't do partial mappings.
646  SmallVector<unsigned, 4> OpSize(NumOperands);
647  SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
648  for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
649  auto &MO = MI.getOperand(Idx);
650  if (!MO.isReg() || !MO.getReg())
651  continue;
652 
653  LLT Ty = MRI.getType(MO.getReg());
654  OpSize[Idx] = Ty.getSizeInBits();
655 
656  // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
657  // For floating-point instructions, scalars go in FPRs.
659  Ty.getSizeInBits() > 64)
660  OpRegBankIdx[Idx] = PMI_FirstFPR;
661  else
662  OpRegBankIdx[Idx] = PMI_FirstGPR;
663  }
664 
665  unsigned Cost = 1;
666  // Some of the floating-point instructions have mixed GPR and FPR operands:
667  // fine-tune the computed mapping.
668  switch (Opc) {
669  case AArch64::G_DUP: {
670  Register ScalarReg = MI.getOperand(1).getReg();
671  LLT ScalarTy = MRI.getType(ScalarReg);
672  auto ScalarDef = MRI.getVRegDef(ScalarReg);
673  // s8 is an exception for G_DUP, which we always want on gpr.
674  if (ScalarTy.getSizeInBits() != 8 &&
675  (getRegBank(ScalarReg, MRI, TRI) == &AArch64::FPRRegBank ||
676  onlyDefinesFP(*ScalarDef, MRI, TRI)))
677  OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
678  else
679  OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
680  break;
681  }
682  case TargetOpcode::G_TRUNC: {
683  LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
684  if (!SrcTy.isVector() && SrcTy.getSizeInBits() == 128)
685  OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
686  break;
687  }
688  case TargetOpcode::G_SITOFP:
689  case TargetOpcode::G_UITOFP: {
690  if (MRI.getType(MI.getOperand(0).getReg()).isVector())
691  break;
692  // Integer to FP conversions don't necessarily happen between GPR -> FPR
693  // regbanks. They can also be done within an FPR register.
694  Register SrcReg = MI.getOperand(1).getReg();
695  if (getRegBank(SrcReg, MRI, TRI) == &AArch64::FPRRegBank)
696  OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
697  else
698  OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
699  break;
700  }
701  case TargetOpcode::G_FPTOSI:
702  case TargetOpcode::G_FPTOUI:
703  if (MRI.getType(MI.getOperand(0).getReg()).isVector())
704  break;
705  OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
706  break;
707  case TargetOpcode::G_FCMP:
708  OpRegBankIdx = {PMI_FirstGPR,
709  /* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
710  break;
711  case TargetOpcode::G_BITCAST:
712  // This is going to be a cross register bank copy and this is expensive.
713  if (OpRegBankIdx[0] != OpRegBankIdx[1])
714  Cost = copyCost(
715  *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
716  *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
717  OpSize[0]);
718  break;
719  case TargetOpcode::G_LOAD:
720  // Loading in vector unit is slightly more expensive.
721  // This is actually only true for the LD1R and co instructions,
722  // but anyway for the fast mode this number does not matter and
723  // for the greedy mode the cost of the cross bank copy will
724  // offset this number.
725  // FIXME: Should be derived from the scheduling model.
726  if (OpRegBankIdx[0] != PMI_FirstGPR)
727  Cost = 2;
728  else
729  // Check if that load feeds fp instructions.
730  // In that case, we want the default mapping to be on FPR
731  // instead of blind map every scalar to GPR.
732  for (const MachineInstr &UseMI :
733  MRI.use_nodbg_instructions(MI.getOperand(0).getReg())) {
734  // If we have at least one direct use in a FP instruction,
735  // assume this was a floating point load in the IR.
736  // If it was not, we would have had a bitcast before
737  // reaching that instruction.
738  // Int->FP conversion operations are also captured in onlyDefinesFP().
739  if (onlyUsesFP(UseMI, MRI, TRI) || onlyDefinesFP(UseMI, MRI, TRI)) {
740  OpRegBankIdx[0] = PMI_FirstFPR;
741  break;
742  }
743  }
744  break;
745  case TargetOpcode::G_STORE:
746  // Check if that store is fed by fp instructions.
747  if (OpRegBankIdx[0] == PMI_FirstGPR) {
748  Register VReg = MI.getOperand(0).getReg();
749  if (!VReg)
750  break;
751  MachineInstr *DefMI = MRI.getVRegDef(VReg);
752  if (onlyDefinesFP(*DefMI, MRI, TRI))
753  OpRegBankIdx[0] = PMI_FirstFPR;
754  break;
755  }
756  break;
757  case TargetOpcode::G_SELECT: {
758  // If the destination is FPR, preserve that.
759  if (OpRegBankIdx[0] != PMI_FirstGPR)
760  break;
761 
762  // If we're taking in vectors, we have no choice but to put everything on
763  // FPRs, except for the condition. The condition must always be on a GPR.
764  LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
765  if (SrcTy.isVector()) {
767  break;
768  }
769 
770  // Try to minimize the number of copies. If we have more floating point
771  // constrained values than not, then we'll put everything on FPR. Otherwise,
772  // everything has to be on GPR.
773  unsigned NumFP = 0;
774 
775  // Check if the uses of the result always produce floating point values.
776  //
777  // For example:
778  //
779  // %z = G_SELECT %cond %x %y
780  // fpr = G_FOO %z ...
781  if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
782  [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); }))
783  ++NumFP;
784 
785  // Check if the defs of the source values always produce floating point
786  // values.
787  //
788  // For example:
789  //
790  // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
791  // %z = G_SELECT %cond %x %y
792  //
793  // Also check whether or not the sources have already been decided to be
794  // FPR. Keep track of this.
795  //
796  // This doesn't check the condition, since it's just whatever is in NZCV.
797  // This isn't passed explicitly in a register to fcsel/csel.
798  for (unsigned Idx = 2; Idx < 4; ++Idx) {
799  Register VReg = MI.getOperand(Idx).getReg();
800  MachineInstr *DefMI = MRI.getVRegDef(VReg);
801  if (getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank ||
802  onlyDefinesFP(*DefMI, MRI, TRI))
803  ++NumFP;
804  }
805 
806  // If we have more FP constraints than not, then move everything over to
807  // FPR.
808  if (NumFP >= 2)
810 
811  break;
812  }
813  case TargetOpcode::G_UNMERGE_VALUES: {
814  // If the first operand belongs to a FPR register bank, then make sure that
815  // we preserve that.
816  if (OpRegBankIdx[0] != PMI_FirstGPR)
817  break;
818 
819  LLT SrcTy = MRI.getType(MI.getOperand(MI.getNumOperands()-1).getReg());
820  // UNMERGE into scalars from a vector should always use FPR.
821  // Likewise if any of the uses are FP instructions.
822  if (SrcTy.isVector() || SrcTy == LLT::scalar(128) ||
823  any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
824  [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); })) {
825  // Set the register bank of every operand to FPR.
826  for (unsigned Idx = 0, NumOperands = MI.getNumOperands();
827  Idx < NumOperands; ++Idx)
828  OpRegBankIdx[Idx] = PMI_FirstFPR;
829  }
830  break;
831  }
832  case TargetOpcode::G_EXTRACT_VECTOR_ELT:
833  // Destination and source need to be FPRs.
834  OpRegBankIdx[0] = PMI_FirstFPR;
835  OpRegBankIdx[1] = PMI_FirstFPR;
836 
837  // Index needs to be a GPR.
838  OpRegBankIdx[2] = PMI_FirstGPR;
839  break;
840  case TargetOpcode::G_INSERT_VECTOR_ELT:
841  OpRegBankIdx[0] = PMI_FirstFPR;
842  OpRegBankIdx[1] = PMI_FirstFPR;
843 
844  // The element may be either a GPR or FPR. Preserve that behaviour.
845  if (getRegBank(MI.getOperand(2).getReg(), MRI, TRI) == &AArch64::FPRRegBank)
846  OpRegBankIdx[2] = PMI_FirstFPR;
847  else
848  OpRegBankIdx[2] = PMI_FirstGPR;
849 
850  // Index needs to be a GPR.
851  OpRegBankIdx[3] = PMI_FirstGPR;
852  break;
853  case TargetOpcode::G_EXTRACT: {
854  // For s128 sources we have to use fpr.
855  LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
856  if (SrcTy.getSizeInBits() == 128) {
857  OpRegBankIdx[0] = PMI_FirstFPR;
858  OpRegBankIdx[1] = PMI_FirstFPR;
859  }
860  break;
861  }
862  case TargetOpcode::G_BUILD_VECTOR: {
863  // If the first source operand belongs to a FPR register bank, then make
864  // sure that we preserve that.
865  if (OpRegBankIdx[1] != PMI_FirstGPR)
866  break;
867  Register VReg = MI.getOperand(1).getReg();
868  if (!VReg)
869  break;
870 
871  // Get the instruction that defined the source operand reg, and check if
872  // it's a floating point operation. Or, if it's a type like s16 which
873  // doesn't have a exact size gpr register class. The exception is if the
874  // build_vector has all constant operands, which may be better to leave as
875  // gpr without copies, so it can be matched in imported patterns.
876  MachineInstr *DefMI = MRI.getVRegDef(VReg);
877  unsigned DefOpc = DefMI->getOpcode();
878  const LLT SrcTy = MRI.getType(VReg);
879  if (all_of(MI.operands(), [&](const MachineOperand &Op) {
880  return Op.isDef() || MRI.getVRegDef(Op.getReg())->getOpcode() ==
881  TargetOpcode::G_CONSTANT;
882  }))
883  break;
885  SrcTy.getSizeInBits() < 32 ||
886  getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank) {
887  // Have a floating point op.
888  // Make sure every operand gets mapped to a FPR register class.
889  unsigned NumOperands = MI.getNumOperands();
890  for (unsigned Idx = 0; Idx < NumOperands; ++Idx)
891  OpRegBankIdx[Idx] = PMI_FirstFPR;
892  }
893  break;
894  }
895  case TargetOpcode::G_VECREDUCE_FADD:
896  case TargetOpcode::G_VECREDUCE_FMUL:
897  case TargetOpcode::G_VECREDUCE_FMAX:
898  case TargetOpcode::G_VECREDUCE_FMIN:
899  case TargetOpcode::G_VECREDUCE_ADD:
900  case TargetOpcode::G_VECREDUCE_MUL:
901  case TargetOpcode::G_VECREDUCE_AND:
902  case TargetOpcode::G_VECREDUCE_OR:
903  case TargetOpcode::G_VECREDUCE_XOR:
904  case TargetOpcode::G_VECREDUCE_SMAX:
905  case TargetOpcode::G_VECREDUCE_SMIN:
906  case TargetOpcode::G_VECREDUCE_UMAX:
907  case TargetOpcode::G_VECREDUCE_UMIN:
908  // Reductions produce a scalar value from a vector, the scalar should be on
909  // FPR bank.
910  OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
911  break;
912  case TargetOpcode::G_VECREDUCE_SEQ_FADD:
913  case TargetOpcode::G_VECREDUCE_SEQ_FMUL:
914  // These reductions also take a scalar accumulator input.
915  // Assign them FPR for now.
916  OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR, PMI_FirstFPR};
917  break;
918  }
919 
920  // Finally construct the computed mapping.
921  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
922  for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
923  if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) {
924  auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
925  if (!Mapping->isValid())
927 
928  OpdsMapping[Idx] = Mapping;
929  }
930  }
931 
933  getOperandsMapping(OpdsMapping), NumOperands);
934 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::AArch64GenRegisterBankInfo::getFPExtMapping
static const RegisterBankInfo::ValueMapping * getFPExtMapping(unsigned DstSize, unsigned SrcSize)
Get the instruction mapping for G_FPEXT.
LowLevelType.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
MachineInstr.h
CHECK_VALUEMAP_FPEXT
#define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize)
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:69
llvm
Definition: AllocatorList.h:23
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:100
AArch64RegisterBankInfo.h
llvm::RegisterBankInfo::getInstrMappingImpl
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
Definition: RegisterBankInfo.cpp:162
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::isPreISelGenericOptimizationHint
bool isPreISelGenericOptimizationHint(unsigned Opcode)
Definition: TargetOpcodes.h:42
llvm::RegisterBankInfo::verify
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
Definition: RegisterBankInfo.cpp:69
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::isPreISelGenericOpcode
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
Definition: TargetOpcodes.h:30
llvm::RegisterBankInfo::getRegBank
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
Definition: RegisterBankInfo.h:432
ErrorHandling.h
CHECK_VALUEMAP_CROSSREGCPY
#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)
RegisterBankInfo.h
llvm::RegisterBankInfo::applyDefaultMapping
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
Definition: RegisterBankInfo.cpp:438
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::MachineRegisterInfo::use_nodbg_instructions
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
Definition: MachineRegisterInfo.h:543
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:231
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:34
llvm::LLT::isValid
bool isValid() const
Definition: LowLevelTypeImpl.h:90
FPR
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
Definition: PPCISelLowering.cpp:3662
isPreISelGenericFloatingPointOpcode
static bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
Definition: AArch64RegisterBankInfo.cpp:396
STLExtras.h
llvm::RegisterBankInfo::InstructionMapping::isValid
bool isValid() const
Check whether this object is valid.
Definition: RegisterBankInfo.h:254
llvm::AArch64GenRegisterBankInfo::PMI_GPR64
@ PMI_GPR64
Definition: AArch64RegisterBankInfo.h:36
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
MachineRegisterInfo.h
llvm::AArch64GenRegisterBankInfo::PMI_LastGPR
@ PMI_LastGPR
Definition: AArch64RegisterBankInfo.h:38
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1505
llvm::AArch64RegisterBankInfo::copyCost
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.
Definition: AArch64RegisterBankInfo.cpp:208
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
llvm::AArch64GenRegisterBankInfo::PMI_FirstGPR
@ PMI_FirstGPR
Definition: AArch64RegisterBankInfo.h:37
AArch64InstrInfo.h
llvm::RegisterBank
This class implements the register bank concept.
Definition: RegisterBank.h:28
llvm::AArch64GenRegisterBankInfo::PMI_FPR512
@ PMI_FPR512
Definition: AArch64RegisterBankInfo.h:34
llvm::LLT::getSizeInBits
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:109
llvm::Register::isPhysicalRegister
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::AArch64GenRegisterBankInfo::PMI_FPR32
@ PMI_FPR32
Definition: AArch64RegisterBankInfo.h:30
llvm::AArch64GenRegisterBankInfo::Shift64Imm
@ Shift64Imm
Definition: AArch64RegisterBankInfo.h:60
TargetOpcodes.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::RegisterBank::getID
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:47
llvm::AArch64GenRegisterBankInfo::checkPartialMappingIdx
static bool checkPartialMappingIdx(PartialMappingIdx FirstAlias, PartialMappingIdx LastAlias, ArrayRef< PartialMappingIdx > Order)
llvm::AArch64RegisterBankInfo::getInstrAlternativeMappings
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
Definition: AArch64RegisterBankInfo.cpp:277
llvm::AArch64GenRegisterBankInfo::PMI_None
@ PMI_None
Definition: AArch64RegisterBankInfo.h:28
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:400
llvm::RegisterBankInfo::getInstrAlternativeMappings
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
Definition: RegisterBankInfo.cpp:433
llvm::RegisterBankInfo::getSizeInBits
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
Definition: RegisterBankInfo.cpp:493
llvm::AArch64GenRegisterBankInfo::PartMappings
static RegisterBankInfo::PartialMapping PartMappings[]
Definition: AArch64RegisterBankInfo.h:44
CHECK_VALUEMAP
#define CHECK_VALUEMAP(RBName, Size)
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:555
llvm::AArch64GenRegisterBankInfo::PartialMappingIdx
PartialMappingIdx
Definition: AArch64RegisterBankInfo.h:27
llvm::TargetRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Definition: TargetRegisterInfo.h:723
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::RegisterBankInfo::InstructionMapping
Helper class that represents how the value of an instruction may be mapped and what is the related co...
Definition: RegisterBankInfo.h:189
llvm::AArch64GenRegisterBankInfo::getValueMapping
static const RegisterBankInfo::ValueMapping * getValueMapping(PartialMappingIdx RBIdx, unsigned Size)
Get the pointer to the ValueMapping representing the RegisterBank at RBIdx with a size of Size.
llvm::AArch64GenRegisterBankInfo::PMI_FPR64
@ PMI_FPR64
Definition: AArch64RegisterBankInfo.h:31
llvm::AArch64GenRegisterBankInfo::PMI_GPR32
@ PMI_GPR32
Definition: AArch64RegisterBankInfo.h:35
llvm::RegisterBankInfo::DefaultMappingID
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
Definition: RegisterBankInfo.h:652
llvm::RegisterBankInfo::getOperandsMapping
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End.
Definition: RegisterBankInfo.cpp:332
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:96
llvm::RegisterBank::covers
bool covers(const TargetRegisterClass &RC) const
Check whether this register bank covers RC.
Definition: RegisterBank.cpp:61
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::RegisterBankInfo::getInstructionMapping
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
Definition: RegisterBankInfo.h:526
llvm::AArch64RegisterBankInfo::getRegBankFromRegClass
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const override
Get a register bank that covers RC.
Definition: AArch64RegisterBankInfo.cpp:230
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:1512
CHECK_PARTIALMAP
#define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)
llvm::AArch64GenRegisterBankInfo::PMI_FPR256
@ PMI_FPR256
Definition: AArch64RegisterBankInfo.h:33
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:478
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
TargetSubtargetInfo.h
llvm::AArch64RegisterBankInfo::getInstrMapping
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
Definition: AArch64RegisterBankInfo.cpp:540
llvm::once_flag
std::once_flag once_flag
Definition: Threading.h:89
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:281
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:59
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::AArch64GenRegisterBankInfo::getCopyMapping
static const RegisterBankInfo::ValueMapping * getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size)
Get the pointer to the ValueMapping of the operands of a copy instruction from the SrcBankID register...
llvm::call_once
void call_once(once_flag &flag, Function &&F, Args &&... ArgList)
Execute the function specified as a parameter once.
Definition: Threading.h:119
llvm::AArch64GenRegisterBankInfo::PMI_FPR16
@ PMI_FPR16
Definition: AArch64RegisterBankInfo.h:29
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::AArch64GenRegisterBankInfo::ValMappings
static RegisterBankInfo::ValueMapping ValMappings[]
Definition: AArch64RegisterBankInfo.h:45
llvm::RegisterBank::getSize
unsigned getSize() const
Get the maximal size in bits that fits in this register bank.
Definition: RegisterBank.h:54
llvm::AArch64GenRegisterBankInfo::PMI_FirstFPR
@ PMI_FirstFPR
Definition: AArch64RegisterBankInfo.h:39
CHECK_VALUEMAP_3OPS
#define CHECK_VALUEMAP_3OPS(RBName, Size)
llvm::RegisterBankInfo::getInvalidInstructionMapping
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
Definition: RegisterBankInfo.h:534
llvm::AArch64GenRegisterBankInfo
Definition: AArch64RegisterBankInfo.h:25
llvm::RegisterBankInfo::copyCost
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.
Definition: RegisterBankInfo.h:614
SmallVector.h
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:732
RegisterBank.h
llvm::AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset
static unsigned getRegBankBaseIdxOffset(unsigned RBIdx, unsigned Size)
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:101
llvm::AArch64GenRegisterBankInfo::PMI_FPR128
@ PMI_FPR128
Definition: AArch64RegisterBankInfo.h:32
MachineOperand.h
MachineFunction.h
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:43
TargetRegisterInfo.h
llvm::AArch64GenRegisterBankInfo::PMI_LastFPR
@ PMI_LastFPR
Definition: AArch64RegisterBankInfo.h:40
llvm::AArch64RegisterBankInfo::AArch64RegisterBankInfo
AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
Definition: AArch64RegisterBankInfo.cpp:40
llvm::LLT
Definition: LowLevelTypeImpl.h:40