Home | History | Annotate | Download | only in AArch64
      1 //===- AArch64RegisterBankInfo.cpp ----------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// This file implements the targeting of the RegisterBankInfo class for
     11 /// AArch64.
     12 /// \todo This should be generated by TableGen.
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "AArch64RegisterBankInfo.h"
     16 #include "AArch64InstrInfo.h"
     17 #include "llvm/ADT/SmallVector.h"
     18 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
     19 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
     20 #include "llvm/CodeGen/LowLevelType.h"
     21 #include "llvm/CodeGen/MachineFunction.h"
     22 #include "llvm/CodeGen/MachineInstr.h"
     23 #include "llvm/CodeGen/MachineOperand.h"
     24 #include "llvm/CodeGen/MachineRegisterInfo.h"
     25 #include "llvm/CodeGen/TargetOpcodes.h"
     26 #include "llvm/CodeGen/TargetRegisterInfo.h"
     27 #include "llvm/CodeGen/TargetSubtargetInfo.h"
     28 #include "llvm/Support/ErrorHandling.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 
     40 AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
     41     : AArch64GenRegisterBankInfo() {
     42   static bool AlreadyInit = false;
     43   // We have only one set of register banks, whatever the subtarget
     44   // is. Therefore, the initialization of the RegBanks table should be
     45   // done only once. Indeed the table of all register banks
     46   // (AArch64::RegBanks) is unique in the compiler. At some point, it
     47   // will get tablegen'ed and the whole constructor becomes empty.
     48   if (AlreadyInit)
     49     return;
     50   AlreadyInit = true;
     51 
     52   const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
     53   (void)RBGPR;
     54   assert(&AArch64::GPRRegBank == &RBGPR &&
     55          "The order in RegBanks is messed up");
     56 
     57   const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
     58   (void)RBFPR;
     59   assert(&AArch64::FPRRegBank == &RBFPR &&
     60          "The order in RegBanks is messed up");
     61 
     62   const RegisterBank &RBCCR = getRegBank(AArch64::CCRegBankID);
     63   (void)RBCCR;
     64   assert(&AArch64::CCRegBank == &RBCCR && "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.
     87   assert(checkPartialMappingIdx(PMI_FirstGPR, PMI_LastGPR,
     88                                 {PMI_GPR32, PMI_GPR64}) &&
     89          "PartialMappingIdx's are incorrectly ordered");
     90   assert(checkPartialMappingIdx(PMI_FirstFPR, PMI_LastFPR,
     91                                 {PMI_FPR16, PMI_FPR32, PMI_FPR64, PMI_FPR128,
     92                                  PMI_FPR256, PMI_FPR512}) &&
     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);
    143   CHECK_VALUEMAP_3OPS(FPR, 32);
    144   CHECK_VALUEMAP_3OPS(FPR, 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);
    170   CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 32);
    171   CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 64);
    172   CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 64);
    173   CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 32);
    174   CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 32);
    175   CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 64);
    176   CHECK_VALUEMAP_CROSSREGCPY(FPR, 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 unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
    206                                            const RegisterBank &B,
    207                                            unsigned Size) const {
    208   // What do we do with different size?
    209   // copy are same size.
    210   // Will introduce other hooks for different size:
    211   // * extract cost.
    212   // * build_sequence cost.
    213 
    214   // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
    215   // FIXME: This should be deduced from the scheduling model.
    216   if (&A == &AArch64::GPRRegBank && &B == &AArch64::FPRRegBank)
    217     // FMOVXDr or FMOVWSr.
    218     return 5;
    219   if (&A == &AArch64::FPRRegBank && &B == &AArch64::GPRRegBank)
    220     // FMOVDXr or FMOVSWr.
    221     return 4;
    222 
    223   return RegisterBankInfo::copyCost(A, B, Size);
    224 }
    225 
    226 const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass(
    227     const TargetRegisterClass &RC) const {
    228   switch (RC.getID()) {
    229   case AArch64::FPR8RegClassID:
    230   case AArch64::FPR16RegClassID:
    231   case AArch64::FPR32RegClassID:
    232   case AArch64::FPR64RegClassID:
    233   case AArch64::FPR128RegClassID:
    234   case AArch64::FPR128_loRegClassID:
    235   case AArch64::DDRegClassID:
    236   case AArch64::DDDRegClassID:
    237   case AArch64::DDDDRegClassID:
    238   case AArch64::QQRegClassID:
    239   case AArch64::QQQRegClassID:
    240   case AArch64::QQQQRegClassID:
    241     return getRegBank(AArch64::FPRRegBankID);
    242   case AArch64::GPR32commonRegClassID:
    243   case AArch64::GPR32RegClassID:
    244   case AArch64::GPR32spRegClassID:
    245   case AArch64::GPR32sponlyRegClassID:
    246   case AArch64::GPR32allRegClassID:
    247   case AArch64::GPR64commonRegClassID:
    248   case AArch64::GPR64RegClassID:
    249   case AArch64::GPR64spRegClassID:
    250   case AArch64::GPR64sponlyRegClassID:
    251   case AArch64::GPR64allRegClassID:
    252   case AArch64::tcGPR64RegClassID:
    253   case AArch64::WSeqPairsClassRegClassID:
    254   case AArch64::XSeqPairsClassRegClassID:
    255     return getRegBank(AArch64::GPRRegBankID);
    256   case AArch64::CCRRegClassID:
    257     return getRegBank(AArch64::CCRegBankID);
    258   default:
    259     llvm_unreachable("Register class not supported");
    260   }
    261 }
    262 
    263 RegisterBankInfo::InstructionMappings
    264 AArch64RegisterBankInfo::getInstrAlternativeMappings(
    265     const MachineInstr &MI) const {
    266   const MachineFunction &MF = *MI.getParent()->getParent();
    267   const TargetSubtargetInfo &STI = MF.getSubtarget();
    268   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
    269   const MachineRegisterInfo &MRI = MF.getRegInfo();
    270 
    271   switch (MI.getOpcode()) {
    272   case TargetOpcode::G_OR: {
    273     // 32 and 64-bit or can be mapped on either FPR or
    274     // GPR for the same cost.
    275     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
    276     if (Size != 32 && Size != 64)
    277       break;
    278 
    279     // If the instruction has any implicit-defs or uses,
    280     // do not mess with it.
    281     if (MI.getNumOperands() != 3)
    282       break;
    283     InstructionMappings AltMappings;
    284     const InstructionMapping &GPRMapping = getInstructionMapping(
    285         /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
    286         /*NumOperands*/ 3);
    287     const InstructionMapping &FPRMapping = getInstructionMapping(
    288         /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
    289         /*NumOperands*/ 3);
    290 
    291     AltMappings.push_back(&GPRMapping);
    292     AltMappings.push_back(&FPRMapping);
    293     return AltMappings;
    294   }
    295   case TargetOpcode::G_BITCAST: {
    296     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
    297     if (Size != 32 && Size != 64)
    298       break;
    299 
    300     // If the instruction has any implicit-defs or uses,
    301     // do not mess with it.
    302     if (MI.getNumOperands() != 2)
    303       break;
    304 
    305     InstructionMappings AltMappings;
    306     const InstructionMapping &GPRMapping = getInstructionMapping(
    307         /*ID*/ 1, /*Cost*/ 1,
    308         getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
    309         /*NumOperands*/ 2);
    310     const InstructionMapping &FPRMapping = getInstructionMapping(
    311         /*ID*/ 2, /*Cost*/ 1,
    312         getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
    313         /*NumOperands*/ 2);
    314     const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
    315         /*ID*/ 3,
    316         /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
    317         getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
    318         /*NumOperands*/ 2);
    319     const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
    320         /*ID*/ 3,
    321         /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
    322         getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
    323         /*NumOperands*/ 2);
    324 
    325     AltMappings.push_back(&GPRMapping);
    326     AltMappings.push_back(&FPRMapping);
    327     AltMappings.push_back(&GPRToFPRMapping);
    328     AltMappings.push_back(&FPRToGPRMapping);
    329     return AltMappings;
    330   }
    331   case TargetOpcode::G_LOAD: {
    332     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
    333     if (Size != 64)
    334       break;
    335 
    336     // If the instruction has any implicit-defs or uses,
    337     // do not mess with it.
    338     if (MI.getNumOperands() != 2)
    339       break;
    340 
    341     InstructionMappings AltMappings;
    342     const InstructionMapping &GPRMapping = getInstructionMapping(
    343         /*ID*/ 1, /*Cost*/ 1,
    344         getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
    345                             // Addresses are GPR 64-bit.
    346                             getValueMapping(PMI_FirstGPR, 64)}),
    347         /*NumOperands*/ 2);
    348     const InstructionMapping &FPRMapping = getInstructionMapping(
    349         /*ID*/ 2, /*Cost*/ 1,
    350         getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
    351                             // Addresses are GPR 64-bit.
    352                             getValueMapping(PMI_FirstGPR, 64)}),
    353         /*NumOperands*/ 2);
    354 
    355     AltMappings.push_back(&GPRMapping);
    356     AltMappings.push_back(&FPRMapping);
    357     return AltMappings;
    358   }
    359   default:
    360     break;
    361   }
    362   return RegisterBankInfo::getInstrAlternativeMappings(MI);
    363 }
    364 
    365 void AArch64RegisterBankInfo::applyMappingImpl(
    366     const OperandsMapper &OpdMapper) const {
    367   switch (OpdMapper.getMI().getOpcode()) {
    368   case TargetOpcode::G_OR:
    369   case TargetOpcode::G_BITCAST:
    370   case TargetOpcode::G_LOAD:
    371     // Those ID must match getInstrAlternativeMappings.
    372     assert((OpdMapper.getInstrMapping().getID() >= 1 &&
    373             OpdMapper.getInstrMapping().getID() <= 4) &&
    374            "Don't know how to handle that ID");
    375     return applyDefaultMapping(OpdMapper);
    376   default:
    377     llvm_unreachable("Don't know how to handle that operation");
    378   }
    379 }
    380 
    381 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
    382 /// having only floating-point operands.
    383 static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
    384   switch (Opc) {
    385   case TargetOpcode::G_FADD:
    386   case TargetOpcode::G_FSUB:
    387   case TargetOpcode::G_FMUL:
    388   case TargetOpcode::G_FDIV:
    389   case TargetOpcode::G_FCONSTANT:
    390   case TargetOpcode::G_FPEXT:
    391   case TargetOpcode::G_FPTRUNC:
    392     return true;
    393   }
    394   return false;
    395 }
    396 
    397 const RegisterBankInfo::InstructionMapping &
    398 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
    399     const MachineInstr &MI) const {
    400   const unsigned Opc = MI.getOpcode();
    401   const MachineFunction &MF = *MI.getParent()->getParent();
    402   const MachineRegisterInfo &MRI = MF.getRegInfo();
    403 
    404   unsigned NumOperands = MI.getNumOperands();
    405   assert(NumOperands <= 3 &&
    406          "This code is for instructions with 3 or less operands");
    407 
    408   LLT Ty = MRI.getType(MI.getOperand(0).getReg());
    409   unsigned Size = Ty.getSizeInBits();
    410   bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
    411 
    412   PartialMappingIdx RBIdx = IsFPR ? PMI_FirstFPR : PMI_FirstGPR;
    413 
    414 #ifndef NDEBUG
    415   // Make sure all the operands are using similar size and type.
    416   // Should probably be checked by the machine verifier.
    417   // This code won't catch cases where the number of lanes is
    418   // different between the operands.
    419   // If we want to go to that level of details, it is probably
    420   // best to check that the types are the same, period.
    421   // Currently, we just check that the register banks are the same
    422   // for each types.
    423   for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
    424     LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
    425     assert(
    426         AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(
    427             RBIdx, OpTy.getSizeInBits()) ==
    428             AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(RBIdx, Size) &&
    429         "Operand has incompatible size");
    430     bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
    431     (void)OpIsFPR;
    432     assert(IsFPR == OpIsFPR && "Operand has incompatible type");
    433   }
    434 #endif // End NDEBUG.
    435 
    436   return getInstructionMapping(DefaultMappingID, 1,
    437                                getValueMapping(RBIdx, Size), NumOperands);
    438 }
    439 
    440 const RegisterBankInfo::InstructionMapping &
    441 AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
    442   const unsigned Opc = MI.getOpcode();
    443 
    444   // Try the default logic for non-generic instructions that are either copies
    445   // or already have some operands assigned to banks.
    446   if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opc)) ||
    447       Opc == TargetOpcode::G_PHI) {
    448     const RegisterBankInfo::InstructionMapping &Mapping =
    449         getInstrMappingImpl(MI);
    450     if (Mapping.isValid())
    451       return Mapping;
    452   }
    453 
    454   const MachineFunction &MF = *MI.getParent()->getParent();
    455   const MachineRegisterInfo &MRI = MF.getRegInfo();
    456   const TargetSubtargetInfo &STI = MF.getSubtarget();
    457   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
    458 
    459   switch (Opc) {
    460     // G_{F|S|U}REM are not listed because they are not legal.
    461     // Arithmetic ops.
    462   case TargetOpcode::G_ADD:
    463   case TargetOpcode::G_SUB:
    464   case TargetOpcode::G_GEP:
    465   case TargetOpcode::G_MUL:
    466   case TargetOpcode::G_SDIV:
    467   case TargetOpcode::G_UDIV:
    468     // Bitwise ops.
    469   case TargetOpcode::G_AND:
    470   case TargetOpcode::G_OR:
    471   case TargetOpcode::G_XOR:
    472     // Shifts.
    473   case TargetOpcode::G_SHL:
    474   case TargetOpcode::G_LSHR:
    475   case TargetOpcode::G_ASHR:
    476     // Floating point ops.
    477   case TargetOpcode::G_FADD:
    478   case TargetOpcode::G_FSUB:
    479   case TargetOpcode::G_FMUL:
    480   case TargetOpcode::G_FDIV:
    481     return getSameKindOfOperandsMapping(MI);
    482   case TargetOpcode::G_FPEXT: {
    483     LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
    484     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
    485     return getInstructionMapping(
    486         DefaultMappingID, /*Cost*/ 1,
    487         getFPExtMapping(DstTy.getSizeInBits(), SrcTy.getSizeInBits()),
    488         /*NumOperands*/ 2);
    489   }
    490   case TargetOpcode::COPY: {
    491     unsigned DstReg = MI.getOperand(0).getReg();
    492     unsigned SrcReg = MI.getOperand(1).getReg();
    493     // Check if one of the register is not a generic register.
    494     if ((TargetRegisterInfo::isPhysicalRegister(DstReg) ||
    495          !MRI.getType(DstReg).isValid()) ||
    496         (TargetRegisterInfo::isPhysicalRegister(SrcReg) ||
    497          !MRI.getType(SrcReg).isValid())) {
    498       const RegisterBank *DstRB = getRegBank(DstReg, MRI, TRI);
    499       const RegisterBank *SrcRB = getRegBank(SrcReg, MRI, TRI);
    500       if (!DstRB)
    501         DstRB = SrcRB;
    502       else if (!SrcRB)
    503         SrcRB = DstRB;
    504       // If both RB are null that means both registers are generic.
    505       // We shouldn't be here.
    506       assert(DstRB && SrcRB && "Both RegBank were nullptr");
    507       unsigned Size = getSizeInBits(DstReg, MRI, TRI);
    508       return getInstructionMapping(
    509           DefaultMappingID, copyCost(*DstRB, *SrcRB, Size),
    510           getCopyMapping(DstRB->getID(), SrcRB->getID(), Size),
    511           // We only care about the mapping of the destination.
    512           /*NumOperands*/ 1);
    513     }
    514     // Both registers are generic, use G_BITCAST.
    515     LLVM_FALLTHROUGH;
    516   }
    517   case TargetOpcode::G_BITCAST: {
    518     LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
    519     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
    520     unsigned Size = DstTy.getSizeInBits();
    521     bool DstIsGPR = !DstTy.isVector() && DstTy.getSizeInBits() <= 64;
    522     bool SrcIsGPR = !SrcTy.isVector() && SrcTy.getSizeInBits() <= 64;
    523     const RegisterBank &DstRB =
    524         DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
    525     const RegisterBank &SrcRB =
    526         SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
    527     return getInstructionMapping(
    528         DefaultMappingID, copyCost(DstRB, SrcRB, Size),
    529         getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
    530         // We only care about the mapping of the destination for COPY.
    531         /*NumOperands*/ Opc == TargetOpcode::G_BITCAST ? 2 : 1);
    532   }
    533   default:
    534     break;
    535   }
    536 
    537   unsigned NumOperands = MI.getNumOperands();
    538 
    539   // Track the size and bank of each register.  We don't do partial mappings.
    540   SmallVector<unsigned, 4> OpSize(NumOperands);
    541   SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
    542   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
    543     auto &MO = MI.getOperand(Idx);
    544     if (!MO.isReg() || !MO.getReg())
    545       continue;
    546 
    547     LLT Ty = MRI.getType(MO.getReg());
    548     OpSize[Idx] = Ty.getSizeInBits();
    549 
    550     // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
    551     // For floating-point instructions, scalars go in FPRs.
    552     if (Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc) ||
    553         Ty.getSizeInBits() > 64)
    554       OpRegBankIdx[Idx] = PMI_FirstFPR;
    555     else
    556       OpRegBankIdx[Idx] = PMI_FirstGPR;
    557   }
    558 
    559   unsigned Cost = 1;
    560   // Some of the floating-point instructions have mixed GPR and FPR operands:
    561   // fine-tune the computed mapping.
    562   switch (Opc) {
    563   case TargetOpcode::G_SITOFP:
    564   case TargetOpcode::G_UITOFP:
    565     OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
    566     break;
    567   case TargetOpcode::G_FPTOSI:
    568   case TargetOpcode::G_FPTOUI:
    569     OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
    570     break;
    571   case TargetOpcode::G_FCMP:
    572     OpRegBankIdx = {PMI_FirstGPR,
    573                     /* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
    574     break;
    575   case TargetOpcode::G_BITCAST:
    576     // This is going to be a cross register bank copy and this is expensive.
    577     if (OpRegBankIdx[0] != OpRegBankIdx[1])
    578       Cost = copyCost(
    579           *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
    580           *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
    581           OpSize[0]);
    582     break;
    583   case TargetOpcode::G_LOAD:
    584     // Loading in vector unit is slightly more expensive.
    585     // This is actually only true for the LD1R and co instructions,
    586     // but anyway for the fast mode this number does not matter and
    587     // for the greedy mode the cost of the cross bank copy will
    588     // offset this number.
    589     // FIXME: Should be derived from the scheduling model.
    590     if (OpRegBankIdx[0] != PMI_FirstGPR)
    591       Cost = 2;
    592     else
    593       // Check if that load feeds fp instructions.
    594       // In that case, we want the default mapping to be on FPR
    595       // instead of blind map every scalar to GPR.
    596       for (const MachineInstr &UseMI :
    597            MRI.use_instructions(MI.getOperand(0).getReg())) {
    598         // If we have at least one direct use in a FP instruction,
    599         // assume this was a floating point load in the IR.
    600         // If it was not, we would have had a bitcast before
    601         // reaching that instruction.
    602         unsigned UseOpc = UseMI.getOpcode();
    603         if (isPreISelGenericFloatingPointOpcode(UseOpc) ||
    604             // Check if we feed a copy-like instruction with
    605             // floating point constraints. In that case, we are still
    606             // feeding fp instructions, but indirectly
    607             // (e.g., through ABI copies).
    608             ((UseOpc == TargetOpcode::COPY || UseMI.isPHI()) &&
    609              getRegBank(UseMI.getOperand(0).getReg(), MRI, TRI) ==
    610                  &AArch64::FPRRegBank)) {
    611           OpRegBankIdx[0] = PMI_FirstFPR;
    612           break;
    613         }
    614       }
    615     break;
    616   case TargetOpcode::G_STORE:
    617     // Check if that store is fed by fp instructions.
    618     if (OpRegBankIdx[0] == PMI_FirstGPR) {
    619       unsigned VReg = MI.getOperand(0).getReg();
    620       if (!VReg)
    621         break;
    622       MachineInstr *DefMI = MRI.getVRegDef(VReg);
    623       unsigned DefOpc = DefMI->getOpcode();
    624       if (isPreISelGenericFloatingPointOpcode(DefOpc) ||
    625           // Check if we come from a copy-like instruction with
    626           // floating point constraints. In that case, we are still
    627           // fed by fp instructions, but indirectly
    628           // (e.g., through ABI copies).
    629           ((DefOpc == TargetOpcode::COPY || DefMI->isPHI()) &&
    630            getRegBank(DefMI->getOperand(0).getReg(), MRI, TRI) ==
    631                &AArch64::FPRRegBank))
    632         OpRegBankIdx[0] = PMI_FirstFPR;
    633       break;
    634     }
    635   }
    636 
    637   // Finally construct the computed mapping.
    638   SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
    639   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
    640     if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) {
    641       auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
    642       if (!Mapping->isValid())
    643         return getInvalidInstructionMapping();
    644 
    645       OpdsMapping[Idx] = Mapping;
    646     }
    647   }
    648 
    649   return getInstructionMapping(DefaultMappingID, Cost,
    650                                getOperandsMapping(OpdsMapping), NumOperands);
    651 }
    652