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