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