181ad6265SDimitry Andric //===- llvm/CodeGen/GlobalISel/RegisterBankInfo.cpp --------------*- C++ -*-==//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric /// \file
981ad6265SDimitry Andric /// This file implements the RegisterBankInfo class.
1081ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1181ad6265SDimitry Andric 
1281ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h"
1306c3fb27SDimitry Andric #include "llvm/ADT/APInt.h"
1481ad6265SDimitry Andric #include "llvm/ADT/SmallVector.h"
1581ad6265SDimitry Andric #include "llvm/ADT/Statistic.h"
1681ad6265SDimitry Andric #include "llvm/ADT/iterator_range.h"
1781ad6265SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
1881ad6265SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
1981ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
2081ad6265SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
2181ad6265SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
2281ad6265SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
2381ad6265SDimitry Andric #include "llvm/Config/llvm-config.h"
2481ad6265SDimitry Andric #include "llvm/Support/Debug.h"
2581ad6265SDimitry Andric #include "llvm/Support/raw_ostream.h"
2681ad6265SDimitry Andric 
2781ad6265SDimitry Andric #include <algorithm> // For std::max.
2881ad6265SDimitry Andric 
2981ad6265SDimitry Andric #define DEBUG_TYPE "registerbankinfo"
3081ad6265SDimitry Andric 
3181ad6265SDimitry Andric using namespace llvm;
3281ad6265SDimitry Andric 
3381ad6265SDimitry Andric STATISTIC(NumPartialMappingsCreated,
3481ad6265SDimitry Andric           "Number of partial mappings dynamically created");
3581ad6265SDimitry Andric STATISTIC(NumPartialMappingsAccessed,
3681ad6265SDimitry Andric           "Number of partial mappings dynamically accessed");
3781ad6265SDimitry Andric STATISTIC(NumValueMappingsCreated,
3881ad6265SDimitry Andric           "Number of value mappings dynamically created");
3981ad6265SDimitry Andric STATISTIC(NumValueMappingsAccessed,
4081ad6265SDimitry Andric           "Number of value mappings dynamically accessed");
4181ad6265SDimitry Andric STATISTIC(NumOperandsMappingsCreated,
4281ad6265SDimitry Andric           "Number of operands mappings dynamically created");
4381ad6265SDimitry Andric STATISTIC(NumOperandsMappingsAccessed,
4481ad6265SDimitry Andric           "Number of operands mappings dynamically accessed");
4581ad6265SDimitry Andric STATISTIC(NumInstructionMappingsCreated,
4681ad6265SDimitry Andric           "Number of instruction mappings dynamically created");
4781ad6265SDimitry Andric STATISTIC(NumInstructionMappingsAccessed,
4881ad6265SDimitry Andric           "Number of instruction mappings dynamically accessed");
4981ad6265SDimitry Andric 
5081ad6265SDimitry Andric const unsigned RegisterBankInfo::DefaultMappingID = UINT_MAX;
5181ad6265SDimitry Andric const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1;
5281ad6265SDimitry Andric 
5381ad6265SDimitry Andric //------------------------------------------------------------------------------
5481ad6265SDimitry Andric // RegisterBankInfo implementation.
5581ad6265SDimitry Andric //------------------------------------------------------------------------------
RegisterBankInfo(const RegisterBank ** RegBanks,unsigned NumRegBanks,const unsigned * Sizes,unsigned HwMode)5606c3fb27SDimitry Andric RegisterBankInfo::RegisterBankInfo(const RegisterBank **RegBanks,
5706c3fb27SDimitry Andric                                    unsigned NumRegBanks, const unsigned *Sizes,
5806c3fb27SDimitry Andric                                    unsigned HwMode)
5906c3fb27SDimitry Andric     : RegBanks(RegBanks), NumRegBanks(NumRegBanks), Sizes(Sizes),
6006c3fb27SDimitry Andric       HwMode(HwMode) {
6181ad6265SDimitry Andric #ifndef NDEBUG
6281ad6265SDimitry Andric   for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) {
6381ad6265SDimitry Andric     assert(RegBanks[Idx] != nullptr && "Invalid RegisterBank");
64*5f757f3fSDimitry Andric     assert(RegBanks[Idx]->getID() == Idx &&
65*5f757f3fSDimitry Andric            "RegisterBank ID should match index");
6681ad6265SDimitry Andric   }
6781ad6265SDimitry Andric #endif // NDEBUG
6881ad6265SDimitry Andric }
6981ad6265SDimitry Andric 
verify(const TargetRegisterInfo & TRI) const7081ad6265SDimitry Andric bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const {
7181ad6265SDimitry Andric #ifndef NDEBUG
7281ad6265SDimitry Andric   for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) {
7381ad6265SDimitry Andric     const RegisterBank &RegBank = getRegBank(Idx);
7481ad6265SDimitry Andric     assert(Idx == RegBank.getID() &&
7581ad6265SDimitry Andric            "ID does not match the index in the array");
7681ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << "Verify " << RegBank << '\n');
7706c3fb27SDimitry Andric     assert(RegBank.verify(*this, TRI) && "RegBank is invalid");
7881ad6265SDimitry Andric   }
7981ad6265SDimitry Andric #endif // NDEBUG
8081ad6265SDimitry Andric   return true;
8181ad6265SDimitry Andric }
8281ad6265SDimitry Andric 
8381ad6265SDimitry Andric const RegisterBank *
getRegBank(Register Reg,const MachineRegisterInfo & MRI,const TargetRegisterInfo & TRI) const8481ad6265SDimitry Andric RegisterBankInfo::getRegBank(Register Reg, const MachineRegisterInfo &MRI,
8581ad6265SDimitry Andric                              const TargetRegisterInfo &TRI) const {
8606c3fb27SDimitry Andric   if (!Reg.isVirtual()) {
8781ad6265SDimitry Andric     // FIXME: This was probably a copy to a virtual register that does have a
8881ad6265SDimitry Andric     // type we could use.
8906c3fb27SDimitry Andric     const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, TRI);
9006c3fb27SDimitry Andric     return RC ? &getRegBankFromRegClass(*RC, LLT()) : nullptr;
9181ad6265SDimitry Andric   }
9281ad6265SDimitry Andric 
9381ad6265SDimitry Andric   const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);
9406c3fb27SDimitry Andric   if (auto *RB = dyn_cast_if_present<const RegisterBank *>(RegClassOrBank))
9581ad6265SDimitry Andric     return RB;
9606c3fb27SDimitry Andric   if (auto *RC =
9706c3fb27SDimitry Andric           dyn_cast_if_present<const TargetRegisterClass *>(RegClassOrBank))
9881ad6265SDimitry Andric     return &getRegBankFromRegClass(*RC, MRI.getType(Reg));
9981ad6265SDimitry Andric   return nullptr;
10081ad6265SDimitry Andric }
10181ad6265SDimitry Andric 
10206c3fb27SDimitry Andric const TargetRegisterClass *
getMinimalPhysRegClass(Register Reg,const TargetRegisterInfo & TRI) const10381ad6265SDimitry Andric RegisterBankInfo::getMinimalPhysRegClass(Register Reg,
10481ad6265SDimitry Andric                                          const TargetRegisterInfo &TRI) const {
105bdd1243dSDimitry Andric   assert(Reg.isPhysical() && "Reg must be a physreg");
10681ad6265SDimitry Andric   const auto &RegRCIt = PhysRegMinimalRCs.find(Reg);
10781ad6265SDimitry Andric   if (RegRCIt != PhysRegMinimalRCs.end())
10806c3fb27SDimitry Andric     return RegRCIt->second;
10906c3fb27SDimitry Andric   const TargetRegisterClass *PhysRC = TRI.getMinimalPhysRegClassLLT(Reg, LLT());
11081ad6265SDimitry Andric   PhysRegMinimalRCs[Reg] = PhysRC;
11106c3fb27SDimitry Andric   return PhysRC;
11281ad6265SDimitry Andric }
11381ad6265SDimitry Andric 
getRegBankFromConstraints(const MachineInstr & MI,unsigned OpIdx,const TargetInstrInfo & TII,const MachineRegisterInfo & MRI) const11481ad6265SDimitry Andric const RegisterBank *RegisterBankInfo::getRegBankFromConstraints(
11581ad6265SDimitry Andric     const MachineInstr &MI, unsigned OpIdx, const TargetInstrInfo &TII,
11681ad6265SDimitry Andric     const MachineRegisterInfo &MRI) const {
11781ad6265SDimitry Andric   const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
11881ad6265SDimitry Andric 
11981ad6265SDimitry Andric   // The mapping of the registers may be available via the
12081ad6265SDimitry Andric   // register class constraints.
12181ad6265SDimitry Andric   const TargetRegisterClass *RC = MI.getRegClassConstraint(OpIdx, &TII, TRI);
12281ad6265SDimitry Andric 
12381ad6265SDimitry Andric   if (!RC)
12481ad6265SDimitry Andric     return nullptr;
12581ad6265SDimitry Andric 
12681ad6265SDimitry Andric   Register Reg = MI.getOperand(OpIdx).getReg();
12781ad6265SDimitry Andric   const RegisterBank &RegBank = getRegBankFromRegClass(*RC, MRI.getType(Reg));
12881ad6265SDimitry Andric   // Check that the target properly implemented getRegBankFromRegClass.
12981ad6265SDimitry Andric   assert(RegBank.covers(*RC) &&
13081ad6265SDimitry Andric          "The mapping of the register bank does not make sense");
13181ad6265SDimitry Andric   return &RegBank;
13281ad6265SDimitry Andric }
13381ad6265SDimitry Andric 
constrainGenericRegister(Register Reg,const TargetRegisterClass & RC,MachineRegisterInfo & MRI)13481ad6265SDimitry Andric const TargetRegisterClass *RegisterBankInfo::constrainGenericRegister(
13581ad6265SDimitry Andric     Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI) {
13681ad6265SDimitry Andric 
13781ad6265SDimitry Andric   // If the register already has a class, fallback to MRI::constrainRegClass.
13881ad6265SDimitry Andric   auto &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);
13906c3fb27SDimitry Andric   if (isa<const TargetRegisterClass *>(RegClassOrBank))
14081ad6265SDimitry Andric     return MRI.constrainRegClass(Reg, &RC);
14181ad6265SDimitry Andric 
14206c3fb27SDimitry Andric   const RegisterBank *RB = cast<const RegisterBank *>(RegClassOrBank);
14381ad6265SDimitry Andric   // Otherwise, all we can do is ensure the bank covers the class, and set it.
14481ad6265SDimitry Andric   if (RB && !RB->covers(RC))
14581ad6265SDimitry Andric     return nullptr;
14681ad6265SDimitry Andric 
14781ad6265SDimitry Andric   // If nothing was set or the class is simply compatible, set it.
14881ad6265SDimitry Andric   MRI.setRegClass(Reg, &RC);
14981ad6265SDimitry Andric   return &RC;
15081ad6265SDimitry Andric }
15181ad6265SDimitry Andric 
15281ad6265SDimitry Andric /// Check whether or not \p MI should be treated like a copy
15381ad6265SDimitry Andric /// for the mappings.
15481ad6265SDimitry Andric /// Copy like instruction are special for mapping because
15581ad6265SDimitry Andric /// they don't have actual register constraints. Moreover,
15681ad6265SDimitry Andric /// they sometimes have register classes assigned and we can
15781ad6265SDimitry Andric /// just use that instead of failing to provide a generic mapping.
isCopyLike(const MachineInstr & MI)15881ad6265SDimitry Andric static bool isCopyLike(const MachineInstr &MI) {
15981ad6265SDimitry Andric   return MI.isCopy() || MI.isPHI() ||
16081ad6265SDimitry Andric          MI.getOpcode() == TargetOpcode::REG_SEQUENCE;
16181ad6265SDimitry Andric }
16281ad6265SDimitry Andric 
16381ad6265SDimitry Andric const RegisterBankInfo::InstructionMapping &
getInstrMappingImpl(const MachineInstr & MI) const16481ad6265SDimitry Andric RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
16581ad6265SDimitry Andric   // For copies we want to walk over the operands and try to find one
16681ad6265SDimitry Andric   // that has a register bank since the instruction itself will not get
16781ad6265SDimitry Andric   // us any constraint.
16881ad6265SDimitry Andric   bool IsCopyLike = isCopyLike(MI);
16981ad6265SDimitry Andric   // For copy like instruction, only the mapping of the definition
17081ad6265SDimitry Andric   // is important. The rest is not constrained.
17181ad6265SDimitry Andric   unsigned NumOperandsForMapping = IsCopyLike ? 1 : MI.getNumOperands();
17281ad6265SDimitry Andric 
17381ad6265SDimitry Andric   const MachineFunction &MF = *MI.getMF();
17481ad6265SDimitry Andric   const TargetSubtargetInfo &STI = MF.getSubtarget();
17581ad6265SDimitry Andric   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
17681ad6265SDimitry Andric   const MachineRegisterInfo &MRI = MF.getRegInfo();
17781ad6265SDimitry Andric   // We may need to query the instruction encoding to guess the mapping.
17881ad6265SDimitry Andric   const TargetInstrInfo &TII = *STI.getInstrInfo();
17981ad6265SDimitry Andric 
18081ad6265SDimitry Andric   // Before doing anything complicated check if the mapping is not
18181ad6265SDimitry Andric   // directly available.
18281ad6265SDimitry Andric   bool CompleteMapping = true;
18381ad6265SDimitry Andric 
18481ad6265SDimitry Andric   SmallVector<const ValueMapping *, 8> OperandsMapping(NumOperandsForMapping);
18581ad6265SDimitry Andric   for (unsigned OpIdx = 0, EndIdx = MI.getNumOperands(); OpIdx != EndIdx;
18681ad6265SDimitry Andric        ++OpIdx) {
18781ad6265SDimitry Andric     const MachineOperand &MO = MI.getOperand(OpIdx);
18881ad6265SDimitry Andric     if (!MO.isReg())
18981ad6265SDimitry Andric       continue;
19081ad6265SDimitry Andric     Register Reg = MO.getReg();
19181ad6265SDimitry Andric     if (!Reg)
19281ad6265SDimitry Andric       continue;
19381ad6265SDimitry Andric     // The register bank of Reg is just a side effect of the current
19481ad6265SDimitry Andric     // excution and in particular, there is no reason to believe this
19581ad6265SDimitry Andric     // is the best default mapping for the current instruction.  Keep
19681ad6265SDimitry Andric     // it as an alternative register bank if we cannot figure out
19781ad6265SDimitry Andric     // something.
19881ad6265SDimitry Andric     const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI);
19981ad6265SDimitry Andric     // For copy-like instruction, we want to reuse the register bank
20081ad6265SDimitry Andric     // that is already set on Reg, if any, since those instructions do
20181ad6265SDimitry Andric     // not have any constraints.
20281ad6265SDimitry Andric     const RegisterBank *CurRegBank = IsCopyLike ? AltRegBank : nullptr;
20381ad6265SDimitry Andric     if (!CurRegBank) {
20481ad6265SDimitry Andric       // If this is a target specific instruction, we can deduce
20581ad6265SDimitry Andric       // the register bank from the encoding constraints.
20681ad6265SDimitry Andric       CurRegBank = getRegBankFromConstraints(MI, OpIdx, TII, MRI);
20781ad6265SDimitry Andric       if (!CurRegBank) {
20881ad6265SDimitry Andric         // All our attempts failed, give up.
20981ad6265SDimitry Andric         CompleteMapping = false;
21081ad6265SDimitry Andric 
21181ad6265SDimitry Andric         if (!IsCopyLike)
21281ad6265SDimitry Andric           // MI does not carry enough information to guess the mapping.
21381ad6265SDimitry Andric           return getInvalidInstructionMapping();
21481ad6265SDimitry Andric         continue;
21581ad6265SDimitry Andric       }
21681ad6265SDimitry Andric     }
21781ad6265SDimitry Andric 
21881ad6265SDimitry Andric     unsigned Size = getSizeInBits(Reg, MRI, TRI);
21981ad6265SDimitry Andric     const ValueMapping *ValMapping = &getValueMapping(0, Size, *CurRegBank);
22081ad6265SDimitry Andric     if (IsCopyLike) {
22181ad6265SDimitry Andric       if (!OperandsMapping[0]) {
22281ad6265SDimitry Andric         if (MI.isRegSequence()) {
22381ad6265SDimitry Andric           // For reg_sequence, the result size does not match the input.
22481ad6265SDimitry Andric           unsigned ResultSize = getSizeInBits(MI.getOperand(0).getReg(),
22581ad6265SDimitry Andric                                               MRI, TRI);
22681ad6265SDimitry Andric           OperandsMapping[0] = &getValueMapping(0, ResultSize, *CurRegBank);
22781ad6265SDimitry Andric         } else {
22881ad6265SDimitry Andric           OperandsMapping[0] = ValMapping;
22981ad6265SDimitry Andric         }
23081ad6265SDimitry Andric       }
23181ad6265SDimitry Andric 
23281ad6265SDimitry Andric       // The default handling assumes any register bank can be copied to any
23381ad6265SDimitry Andric       // other. If this isn't the case, the target should specially deal with
23481ad6265SDimitry Andric       // reg_sequence/phi. There may also be unsatisfiable copies.
23581ad6265SDimitry Andric       for (; OpIdx != EndIdx; ++OpIdx) {
23681ad6265SDimitry Andric         const MachineOperand &MO = MI.getOperand(OpIdx);
23781ad6265SDimitry Andric         if (!MO.isReg())
23881ad6265SDimitry Andric           continue;
23981ad6265SDimitry Andric         Register Reg = MO.getReg();
24081ad6265SDimitry Andric         if (!Reg)
24181ad6265SDimitry Andric           continue;
24281ad6265SDimitry Andric 
24381ad6265SDimitry Andric         const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI);
24481ad6265SDimitry Andric         if (AltRegBank &&
24581ad6265SDimitry Andric             cannotCopy(*CurRegBank, *AltRegBank, getSizeInBits(Reg, MRI, TRI)))
24681ad6265SDimitry Andric           return getInvalidInstructionMapping();
24781ad6265SDimitry Andric       }
24881ad6265SDimitry Andric 
24981ad6265SDimitry Andric       CompleteMapping = true;
25081ad6265SDimitry Andric       break;
25181ad6265SDimitry Andric     }
25281ad6265SDimitry Andric 
25381ad6265SDimitry Andric     OperandsMapping[OpIdx] = ValMapping;
25481ad6265SDimitry Andric   }
25581ad6265SDimitry Andric 
25681ad6265SDimitry Andric   if (IsCopyLike && !CompleteMapping) {
25781ad6265SDimitry Andric     // No way to deduce the type from what we have.
25881ad6265SDimitry Andric     return getInvalidInstructionMapping();
25981ad6265SDimitry Andric   }
26081ad6265SDimitry Andric 
26181ad6265SDimitry Andric   assert(CompleteMapping && "Setting an uncomplete mapping");
26281ad6265SDimitry Andric   return getInstructionMapping(
26381ad6265SDimitry Andric       DefaultMappingID, /*Cost*/ 1,
26481ad6265SDimitry Andric       /*OperandsMapping*/ getOperandsMapping(OperandsMapping),
26581ad6265SDimitry Andric       NumOperandsForMapping);
26681ad6265SDimitry Andric }
26781ad6265SDimitry Andric 
26881ad6265SDimitry Andric /// Hashing function for PartialMapping.
hashPartialMapping(unsigned StartIdx,unsigned Length,const RegisterBank * RegBank)26981ad6265SDimitry Andric static hash_code hashPartialMapping(unsigned StartIdx, unsigned Length,
27081ad6265SDimitry Andric                                     const RegisterBank *RegBank) {
27181ad6265SDimitry Andric   return hash_combine(StartIdx, Length, RegBank ? RegBank->getID() : 0);
27281ad6265SDimitry Andric }
27381ad6265SDimitry Andric 
27481ad6265SDimitry Andric /// Overloaded version of hash_value for a PartialMapping.
27581ad6265SDimitry Andric hash_code
hash_value(const RegisterBankInfo::PartialMapping & PartMapping)27681ad6265SDimitry Andric llvm::hash_value(const RegisterBankInfo::PartialMapping &PartMapping) {
27781ad6265SDimitry Andric   return hashPartialMapping(PartMapping.StartIdx, PartMapping.Length,
27881ad6265SDimitry Andric                             PartMapping.RegBank);
27981ad6265SDimitry Andric }
28081ad6265SDimitry Andric 
28181ad6265SDimitry Andric const RegisterBankInfo::PartialMapping &
getPartialMapping(unsigned StartIdx,unsigned Length,const RegisterBank & RegBank) const28281ad6265SDimitry Andric RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length,
28381ad6265SDimitry Andric                                     const RegisterBank &RegBank) const {
28481ad6265SDimitry Andric   ++NumPartialMappingsAccessed;
28581ad6265SDimitry Andric 
28681ad6265SDimitry Andric   hash_code Hash = hashPartialMapping(StartIdx, Length, &RegBank);
28781ad6265SDimitry Andric   const auto &It = MapOfPartialMappings.find(Hash);
28881ad6265SDimitry Andric   if (It != MapOfPartialMappings.end())
28981ad6265SDimitry Andric     return *It->second;
29081ad6265SDimitry Andric 
29181ad6265SDimitry Andric   ++NumPartialMappingsCreated;
29281ad6265SDimitry Andric 
29381ad6265SDimitry Andric   auto &PartMapping = MapOfPartialMappings[Hash];
29481ad6265SDimitry Andric   PartMapping = std::make_unique<PartialMapping>(StartIdx, Length, RegBank);
29581ad6265SDimitry Andric   return *PartMapping;
29681ad6265SDimitry Andric }
29781ad6265SDimitry Andric 
29881ad6265SDimitry Andric const RegisterBankInfo::ValueMapping &
getValueMapping(unsigned StartIdx,unsigned Length,const RegisterBank & RegBank) const29981ad6265SDimitry Andric RegisterBankInfo::getValueMapping(unsigned StartIdx, unsigned Length,
30081ad6265SDimitry Andric                                   const RegisterBank &RegBank) const {
30181ad6265SDimitry Andric   return getValueMapping(&getPartialMapping(StartIdx, Length, RegBank), 1);
30281ad6265SDimitry Andric }
30381ad6265SDimitry Andric 
30481ad6265SDimitry Andric static hash_code
hashValueMapping(const RegisterBankInfo::PartialMapping * BreakDown,unsigned NumBreakDowns)30581ad6265SDimitry Andric hashValueMapping(const RegisterBankInfo::PartialMapping *BreakDown,
30681ad6265SDimitry Andric                  unsigned NumBreakDowns) {
30781ad6265SDimitry Andric   if (LLVM_LIKELY(NumBreakDowns == 1))
30881ad6265SDimitry Andric     return hash_value(*BreakDown);
30981ad6265SDimitry Andric   SmallVector<size_t, 8> Hashes(NumBreakDowns);
31081ad6265SDimitry Andric   for (unsigned Idx = 0; Idx != NumBreakDowns; ++Idx)
31181ad6265SDimitry Andric     Hashes.push_back(hash_value(BreakDown[Idx]));
31281ad6265SDimitry Andric   return hash_combine_range(Hashes.begin(), Hashes.end());
31381ad6265SDimitry Andric }
31481ad6265SDimitry Andric 
31581ad6265SDimitry Andric const RegisterBankInfo::ValueMapping &
getValueMapping(const PartialMapping * BreakDown,unsigned NumBreakDowns) const31681ad6265SDimitry Andric RegisterBankInfo::getValueMapping(const PartialMapping *BreakDown,
31781ad6265SDimitry Andric                                   unsigned NumBreakDowns) const {
31881ad6265SDimitry Andric   ++NumValueMappingsAccessed;
31981ad6265SDimitry Andric 
32081ad6265SDimitry Andric   hash_code Hash = hashValueMapping(BreakDown, NumBreakDowns);
32181ad6265SDimitry Andric   const auto &It = MapOfValueMappings.find(Hash);
32281ad6265SDimitry Andric   if (It != MapOfValueMappings.end())
32381ad6265SDimitry Andric     return *It->second;
32481ad6265SDimitry Andric 
32581ad6265SDimitry Andric   ++NumValueMappingsCreated;
32681ad6265SDimitry Andric 
32781ad6265SDimitry Andric   auto &ValMapping = MapOfValueMappings[Hash];
32881ad6265SDimitry Andric   ValMapping = std::make_unique<ValueMapping>(BreakDown, NumBreakDowns);
32981ad6265SDimitry Andric   return *ValMapping;
33081ad6265SDimitry Andric }
33181ad6265SDimitry Andric 
33281ad6265SDimitry Andric template <typename Iterator>
33381ad6265SDimitry Andric const RegisterBankInfo::ValueMapping *
getOperandsMapping(Iterator Begin,Iterator End) const33481ad6265SDimitry Andric RegisterBankInfo::getOperandsMapping(Iterator Begin, Iterator End) const {
33581ad6265SDimitry Andric 
33681ad6265SDimitry Andric   ++NumOperandsMappingsAccessed;
33781ad6265SDimitry Andric 
33881ad6265SDimitry Andric   // The addresses of the value mapping are unique.
33981ad6265SDimitry Andric   // Therefore, we can use them directly to hash the operand mapping.
34081ad6265SDimitry Andric   hash_code Hash = hash_combine_range(Begin, End);
34181ad6265SDimitry Andric   auto &Res = MapOfOperandsMappings[Hash];
34281ad6265SDimitry Andric   if (Res)
34381ad6265SDimitry Andric     return Res.get();
34481ad6265SDimitry Andric 
34581ad6265SDimitry Andric   ++NumOperandsMappingsCreated;
34681ad6265SDimitry Andric 
34781ad6265SDimitry Andric   // Create the array of ValueMapping.
34881ad6265SDimitry Andric   // Note: this array will not hash to this instance of operands
34981ad6265SDimitry Andric   // mapping, because we use the pointer of the ValueMapping
35081ad6265SDimitry Andric   // to hash and we expect them to uniquely identify an instance
35181ad6265SDimitry Andric   // of value mapping.
35281ad6265SDimitry Andric   Res = std::make_unique<ValueMapping[]>(std::distance(Begin, End));
35381ad6265SDimitry Andric   unsigned Idx = 0;
35481ad6265SDimitry Andric   for (Iterator It = Begin; It != End; ++It, ++Idx) {
35581ad6265SDimitry Andric     const ValueMapping *ValMap = *It;
35681ad6265SDimitry Andric     if (!ValMap)
35781ad6265SDimitry Andric       continue;
35881ad6265SDimitry Andric     Res[Idx] = *ValMap;
35981ad6265SDimitry Andric   }
36081ad6265SDimitry Andric   return Res.get();
36181ad6265SDimitry Andric }
36281ad6265SDimitry Andric 
getOperandsMapping(const SmallVectorImpl<const RegisterBankInfo::ValueMapping * > & OpdsMapping) const36381ad6265SDimitry Andric const RegisterBankInfo::ValueMapping *RegisterBankInfo::getOperandsMapping(
36481ad6265SDimitry Andric     const SmallVectorImpl<const RegisterBankInfo::ValueMapping *> &OpdsMapping)
36581ad6265SDimitry Andric     const {
36681ad6265SDimitry Andric   return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end());
36781ad6265SDimitry Andric }
36881ad6265SDimitry Andric 
getOperandsMapping(std::initializer_list<const RegisterBankInfo::ValueMapping * > OpdsMapping) const36981ad6265SDimitry Andric const RegisterBankInfo::ValueMapping *RegisterBankInfo::getOperandsMapping(
37081ad6265SDimitry Andric     std::initializer_list<const RegisterBankInfo::ValueMapping *> OpdsMapping)
37181ad6265SDimitry Andric     const {
37281ad6265SDimitry Andric   return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end());
37381ad6265SDimitry Andric }
37481ad6265SDimitry Andric 
37581ad6265SDimitry Andric static hash_code
hashInstructionMapping(unsigned ID,unsigned Cost,const RegisterBankInfo::ValueMapping * OperandsMapping,unsigned NumOperands)37681ad6265SDimitry Andric hashInstructionMapping(unsigned ID, unsigned Cost,
37781ad6265SDimitry Andric                        const RegisterBankInfo::ValueMapping *OperandsMapping,
37881ad6265SDimitry Andric                        unsigned NumOperands) {
37981ad6265SDimitry Andric   return hash_combine(ID, Cost, OperandsMapping, NumOperands);
38081ad6265SDimitry Andric }
38181ad6265SDimitry Andric 
38281ad6265SDimitry Andric const RegisterBankInfo::InstructionMapping &
getInstructionMappingImpl(bool IsInvalid,unsigned ID,unsigned Cost,const RegisterBankInfo::ValueMapping * OperandsMapping,unsigned NumOperands) const38381ad6265SDimitry Andric RegisterBankInfo::getInstructionMappingImpl(
38481ad6265SDimitry Andric     bool IsInvalid, unsigned ID, unsigned Cost,
38581ad6265SDimitry Andric     const RegisterBankInfo::ValueMapping *OperandsMapping,
38681ad6265SDimitry Andric     unsigned NumOperands) const {
38781ad6265SDimitry Andric   assert(((IsInvalid && ID == InvalidMappingID && Cost == 0 &&
38881ad6265SDimitry Andric            OperandsMapping == nullptr && NumOperands == 0) ||
38981ad6265SDimitry Andric           !IsInvalid) &&
39081ad6265SDimitry Andric          "Mismatch argument for invalid input");
39181ad6265SDimitry Andric   ++NumInstructionMappingsAccessed;
39281ad6265SDimitry Andric 
39381ad6265SDimitry Andric   hash_code Hash =
39481ad6265SDimitry Andric       hashInstructionMapping(ID, Cost, OperandsMapping, NumOperands);
39581ad6265SDimitry Andric   const auto &It = MapOfInstructionMappings.find(Hash);
39681ad6265SDimitry Andric   if (It != MapOfInstructionMappings.end())
39781ad6265SDimitry Andric     return *It->second;
39881ad6265SDimitry Andric 
39981ad6265SDimitry Andric   ++NumInstructionMappingsCreated;
40081ad6265SDimitry Andric 
40181ad6265SDimitry Andric   auto &InstrMapping = MapOfInstructionMappings[Hash];
40281ad6265SDimitry Andric   InstrMapping = std::make_unique<InstructionMapping>(
40381ad6265SDimitry Andric       ID, Cost, OperandsMapping, NumOperands);
40481ad6265SDimitry Andric   return *InstrMapping;
40581ad6265SDimitry Andric }
40681ad6265SDimitry Andric 
40781ad6265SDimitry Andric const RegisterBankInfo::InstructionMapping &
getInstrMapping(const MachineInstr & MI) const40881ad6265SDimitry Andric RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
40981ad6265SDimitry Andric   const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
41081ad6265SDimitry Andric   if (Mapping.isValid())
41181ad6265SDimitry Andric     return Mapping;
41281ad6265SDimitry Andric   llvm_unreachable("The target must implement this");
41381ad6265SDimitry Andric }
41481ad6265SDimitry Andric 
41581ad6265SDimitry Andric RegisterBankInfo::InstructionMappings
getInstrPossibleMappings(const MachineInstr & MI) const41681ad6265SDimitry Andric RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const {
41781ad6265SDimitry Andric   InstructionMappings PossibleMappings;
41881ad6265SDimitry Andric   const auto &Mapping = getInstrMapping(MI);
41981ad6265SDimitry Andric   if (Mapping.isValid()) {
42081ad6265SDimitry Andric     // Put the default mapping first.
42181ad6265SDimitry Andric     PossibleMappings.push_back(&Mapping);
42281ad6265SDimitry Andric   }
42381ad6265SDimitry Andric 
42481ad6265SDimitry Andric   // Then the alternative mapping, if any.
42581ad6265SDimitry Andric   InstructionMappings AltMappings = getInstrAlternativeMappings(MI);
42681ad6265SDimitry Andric   append_range(PossibleMappings, AltMappings);
42781ad6265SDimitry Andric #ifndef NDEBUG
42881ad6265SDimitry Andric   for (const InstructionMapping *Mapping : PossibleMappings)
42981ad6265SDimitry Andric     assert(Mapping->verify(MI) && "Mapping is invalid");
43081ad6265SDimitry Andric #endif
43181ad6265SDimitry Andric   return PossibleMappings;
43281ad6265SDimitry Andric }
43381ad6265SDimitry Andric 
43481ad6265SDimitry Andric RegisterBankInfo::InstructionMappings
getInstrAlternativeMappings(const MachineInstr & MI) const43581ad6265SDimitry Andric RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
43681ad6265SDimitry Andric   // No alternative for MI.
43781ad6265SDimitry Andric   return InstructionMappings();
43881ad6265SDimitry Andric }
43981ad6265SDimitry Andric 
applyDefaultMapping(const OperandsMapper & OpdMapper)44081ad6265SDimitry Andric void RegisterBankInfo::applyDefaultMapping(const OperandsMapper &OpdMapper) {
44181ad6265SDimitry Andric   MachineInstr &MI = OpdMapper.getMI();
44281ad6265SDimitry Andric   MachineRegisterInfo &MRI = OpdMapper.getMRI();
44381ad6265SDimitry Andric   LLVM_DEBUG(dbgs() << "Applying default-like mapping\n");
44481ad6265SDimitry Andric   for (unsigned OpIdx = 0,
44581ad6265SDimitry Andric                 EndIdx = OpdMapper.getInstrMapping().getNumOperands();
44681ad6265SDimitry Andric        OpIdx != EndIdx; ++OpIdx) {
44781ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << "OpIdx " << OpIdx);
44881ad6265SDimitry Andric     MachineOperand &MO = MI.getOperand(OpIdx);
44981ad6265SDimitry Andric     if (!MO.isReg()) {
45081ad6265SDimitry Andric       LLVM_DEBUG(dbgs() << " is not a register, nothing to be done\n");
45181ad6265SDimitry Andric       continue;
45281ad6265SDimitry Andric     }
45381ad6265SDimitry Andric     if (!MO.getReg()) {
45481ad6265SDimitry Andric       LLVM_DEBUG(dbgs() << " is $noreg, nothing to be done\n");
45581ad6265SDimitry Andric       continue;
45681ad6265SDimitry Andric     }
457bdd1243dSDimitry Andric     LLT Ty = MRI.getType(MO.getReg());
458bdd1243dSDimitry Andric     if (!Ty.isValid())
459bdd1243dSDimitry Andric       continue;
46081ad6265SDimitry Andric     assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns !=
46181ad6265SDimitry Andric                0 &&
46281ad6265SDimitry Andric            "Invalid mapping");
46381ad6265SDimitry Andric     assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns ==
46481ad6265SDimitry Andric                1 &&
46581ad6265SDimitry Andric            "This mapping is too complex for this function");
46681ad6265SDimitry Andric     iterator_range<SmallVectorImpl<Register>::const_iterator> NewRegs =
46781ad6265SDimitry Andric         OpdMapper.getVRegs(OpIdx);
46881ad6265SDimitry Andric     if (NewRegs.empty()) {
46981ad6265SDimitry Andric       LLVM_DEBUG(dbgs() << " has not been repaired, nothing to be done\n");
47081ad6265SDimitry Andric       continue;
47181ad6265SDimitry Andric     }
47281ad6265SDimitry Andric     Register OrigReg = MO.getReg();
47381ad6265SDimitry Andric     Register NewReg = *NewRegs.begin();
47481ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << " changed, replace " << printReg(OrigReg, nullptr));
47581ad6265SDimitry Andric     MO.setReg(NewReg);
47681ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << " with " << printReg(NewReg, nullptr));
47781ad6265SDimitry Andric 
47881ad6265SDimitry Andric     // The OperandsMapper creates plain scalar, we may have to fix that.
47981ad6265SDimitry Andric     // Check if the types match and if not, fix that.
48081ad6265SDimitry Andric     LLT OrigTy = MRI.getType(OrigReg);
48181ad6265SDimitry Andric     LLT NewTy = MRI.getType(NewReg);
48281ad6265SDimitry Andric     if (OrigTy != NewTy) {
48381ad6265SDimitry Andric       // The default mapping is not supposed to change the size of
48481ad6265SDimitry Andric       // the storage. However, right now we don't necessarily bump all
48581ad6265SDimitry Andric       // the types to storage size. For instance, we can consider
48681ad6265SDimitry Andric       // s16 G_AND legal whereas the storage size is going to be 32.
48781ad6265SDimitry Andric       assert(OrigTy.getSizeInBits() <= NewTy.getSizeInBits() &&
48881ad6265SDimitry Andric              "Types with difference size cannot be handled by the default "
48981ad6265SDimitry Andric              "mapping");
49081ad6265SDimitry Andric       LLVM_DEBUG(dbgs() << "\nChange type of new opd from " << NewTy << " to "
49181ad6265SDimitry Andric                         << OrigTy);
49281ad6265SDimitry Andric       MRI.setType(NewReg, OrigTy);
49381ad6265SDimitry Andric     }
49481ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << '\n');
49581ad6265SDimitry Andric   }
49681ad6265SDimitry Andric }
49781ad6265SDimitry Andric 
getSizeInBits(Register Reg,const MachineRegisterInfo & MRI,const TargetRegisterInfo & TRI) const498*5f757f3fSDimitry Andric TypeSize RegisterBankInfo::getSizeInBits(Register Reg,
49981ad6265SDimitry Andric                                          const MachineRegisterInfo &MRI,
50081ad6265SDimitry Andric                                          const TargetRegisterInfo &TRI) const {
501bdd1243dSDimitry Andric   if (Reg.isPhysical()) {
50281ad6265SDimitry Andric     // The size is not directly available for physical registers.
50381ad6265SDimitry Andric     // Instead, we need to access a register class that contains Reg and
50481ad6265SDimitry Andric     // get the size of that register class.
50581ad6265SDimitry Andric     // Because this is expensive, we'll cache the register class by calling
50606c3fb27SDimitry Andric     auto *RC = getMinimalPhysRegClass(Reg, TRI);
50781ad6265SDimitry Andric     assert(RC && "Expecting Register class");
50881ad6265SDimitry Andric     return TRI.getRegSizeInBits(*RC);
50981ad6265SDimitry Andric   }
51081ad6265SDimitry Andric   return TRI.getRegSizeInBits(Reg, MRI);
51181ad6265SDimitry Andric }
51281ad6265SDimitry Andric 
51381ad6265SDimitry Andric //------------------------------------------------------------------------------
51481ad6265SDimitry Andric // Helper classes implementation.
51581ad6265SDimitry Andric //------------------------------------------------------------------------------
51681ad6265SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const51781ad6265SDimitry Andric LLVM_DUMP_METHOD void RegisterBankInfo::PartialMapping::dump() const {
51881ad6265SDimitry Andric   print(dbgs());
51981ad6265SDimitry Andric   dbgs() << '\n';
52081ad6265SDimitry Andric }
52181ad6265SDimitry Andric #endif
52281ad6265SDimitry Andric 
verify(const RegisterBankInfo & RBI) const52306c3fb27SDimitry Andric bool RegisterBankInfo::PartialMapping::verify(
52406c3fb27SDimitry Andric     const RegisterBankInfo &RBI) const {
52581ad6265SDimitry Andric   assert(RegBank && "Register bank not set");
52681ad6265SDimitry Andric   assert(Length && "Empty mapping");
52781ad6265SDimitry Andric   assert((StartIdx <= getHighBitIdx()) && "Overflow, switch to APInt?");
52881ad6265SDimitry Andric   // Check if the minimum width fits into RegBank.
52906c3fb27SDimitry Andric   assert(RBI.getMaximumSize(RegBank->getID()) >= Length &&
53006c3fb27SDimitry Andric          "Register bank too small for Mask");
53181ad6265SDimitry Andric   return true;
53281ad6265SDimitry Andric }
53381ad6265SDimitry Andric 
print(raw_ostream & OS) const53481ad6265SDimitry Andric void RegisterBankInfo::PartialMapping::print(raw_ostream &OS) const {
53581ad6265SDimitry Andric   OS << "[" << StartIdx << ", " << getHighBitIdx() << "], RegBank = ";
53681ad6265SDimitry Andric   if (RegBank)
53781ad6265SDimitry Andric     OS << *RegBank;
53881ad6265SDimitry Andric   else
53981ad6265SDimitry Andric     OS << "nullptr";
54081ad6265SDimitry Andric }
54181ad6265SDimitry Andric 
partsAllUniform() const54281ad6265SDimitry Andric bool RegisterBankInfo::ValueMapping::partsAllUniform() const {
54381ad6265SDimitry Andric   if (NumBreakDowns < 2)
54481ad6265SDimitry Andric     return true;
54581ad6265SDimitry Andric 
54681ad6265SDimitry Andric   const PartialMapping *First = begin();
54781ad6265SDimitry Andric   for (const PartialMapping *Part = First + 1; Part != end(); ++Part) {
54881ad6265SDimitry Andric     if (Part->Length != First->Length || Part->RegBank != First->RegBank)
54981ad6265SDimitry Andric       return false;
55081ad6265SDimitry Andric   }
55181ad6265SDimitry Andric 
55281ad6265SDimitry Andric   return true;
55381ad6265SDimitry Andric }
55481ad6265SDimitry Andric 
verify(const RegisterBankInfo & RBI,TypeSize MeaningfulBitWidth) const55506c3fb27SDimitry Andric bool RegisterBankInfo::ValueMapping::verify(const RegisterBankInfo &RBI,
556*5f757f3fSDimitry Andric                                             TypeSize MeaningfulBitWidth) const {
55781ad6265SDimitry Andric   assert(NumBreakDowns && "Value mapped nowhere?!");
55881ad6265SDimitry Andric   unsigned OrigValueBitWidth = 0;
55981ad6265SDimitry Andric   for (const RegisterBankInfo::PartialMapping &PartMap : *this) {
56081ad6265SDimitry Andric     // Check that each register bank is big enough to hold the partial value:
56181ad6265SDimitry Andric     // this check is done by PartialMapping::verify
56206c3fb27SDimitry Andric     assert(PartMap.verify(RBI) && "Partial mapping is invalid");
56381ad6265SDimitry Andric     // The original value should completely be mapped.
56481ad6265SDimitry Andric     // Thus the maximum accessed index + 1 is the size of the original value.
56581ad6265SDimitry Andric     OrigValueBitWidth =
56681ad6265SDimitry Andric         std::max(OrigValueBitWidth, PartMap.getHighBitIdx() + 1);
56781ad6265SDimitry Andric   }
568*5f757f3fSDimitry Andric   assert((MeaningfulBitWidth.isScalable() ||
569*5f757f3fSDimitry Andric           OrigValueBitWidth >= MeaningfulBitWidth) &&
57081ad6265SDimitry Andric          "Meaningful bits not covered by the mapping");
57181ad6265SDimitry Andric   APInt ValueMask(OrigValueBitWidth, 0);
57281ad6265SDimitry Andric   for (const RegisterBankInfo::PartialMapping &PartMap : *this) {
57381ad6265SDimitry Andric     // Check that the union of the partial mappings covers the whole value,
57481ad6265SDimitry Andric     // without overlaps.
57581ad6265SDimitry Andric     // The high bit is exclusive in the APInt API, thus getHighBitIdx + 1.
57681ad6265SDimitry Andric     APInt PartMapMask = APInt::getBitsSet(OrigValueBitWidth, PartMap.StartIdx,
57781ad6265SDimitry Andric                                           PartMap.getHighBitIdx() + 1);
57881ad6265SDimitry Andric     ValueMask ^= PartMapMask;
57981ad6265SDimitry Andric     assert((ValueMask & PartMapMask) == PartMapMask &&
58081ad6265SDimitry Andric            "Some partial mappings overlap");
58181ad6265SDimitry Andric   }
58281ad6265SDimitry Andric   assert(ValueMask.isAllOnes() && "Value is not fully mapped");
58381ad6265SDimitry Andric   return true;
58481ad6265SDimitry Andric }
58581ad6265SDimitry Andric 
58681ad6265SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const58781ad6265SDimitry Andric LLVM_DUMP_METHOD void RegisterBankInfo::ValueMapping::dump() const {
58881ad6265SDimitry Andric   print(dbgs());
58981ad6265SDimitry Andric   dbgs() << '\n';
59081ad6265SDimitry Andric }
59181ad6265SDimitry Andric #endif
59281ad6265SDimitry Andric 
print(raw_ostream & OS) const59381ad6265SDimitry Andric void RegisterBankInfo::ValueMapping::print(raw_ostream &OS) const {
59481ad6265SDimitry Andric   OS << "#BreakDown: " << NumBreakDowns << " ";
59581ad6265SDimitry Andric   bool IsFirst = true;
59681ad6265SDimitry Andric   for (const PartialMapping &PartMap : *this) {
59781ad6265SDimitry Andric     if (!IsFirst)
59881ad6265SDimitry Andric       OS << ", ";
59981ad6265SDimitry Andric     OS << '[' << PartMap << ']';
60081ad6265SDimitry Andric     IsFirst = false;
60181ad6265SDimitry Andric   }
60281ad6265SDimitry Andric }
60381ad6265SDimitry Andric 
verify(const MachineInstr & MI) const60481ad6265SDimitry Andric bool RegisterBankInfo::InstructionMapping::verify(
60581ad6265SDimitry Andric     const MachineInstr &MI) const {
60681ad6265SDimitry Andric   // Check that all the register operands are properly mapped.
60781ad6265SDimitry Andric   // Check the constructor invariant.
60881ad6265SDimitry Andric   // For PHI, we only care about mapping the definition.
60981ad6265SDimitry Andric   assert(NumOperands == (isCopyLike(MI) ? 1 : MI.getNumOperands()) &&
61081ad6265SDimitry Andric          "NumOperands must match, see constructor");
61181ad6265SDimitry Andric   assert(MI.getParent() && MI.getMF() &&
61281ad6265SDimitry Andric          "MI must be connected to a MachineFunction");
61381ad6265SDimitry Andric   const MachineFunction &MF = *MI.getMF();
61481ad6265SDimitry Andric   const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo();
61581ad6265SDimitry Andric   (void)RBI;
616bdd1243dSDimitry Andric   const MachineRegisterInfo &MRI = MF.getRegInfo();
61781ad6265SDimitry Andric 
61881ad6265SDimitry Andric   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
61981ad6265SDimitry Andric     const MachineOperand &MO = MI.getOperand(Idx);
62081ad6265SDimitry Andric     if (!MO.isReg()) {
62181ad6265SDimitry Andric       assert(!getOperandMapping(Idx).isValid() &&
62281ad6265SDimitry Andric              "We should not care about non-reg mapping");
62381ad6265SDimitry Andric       continue;
62481ad6265SDimitry Andric     }
62581ad6265SDimitry Andric     Register Reg = MO.getReg();
62681ad6265SDimitry Andric     if (!Reg)
62781ad6265SDimitry Andric       continue;
628bdd1243dSDimitry Andric     LLT Ty = MRI.getType(Reg);
629bdd1243dSDimitry Andric     if (!Ty.isValid())
630bdd1243dSDimitry Andric       continue;
63181ad6265SDimitry Andric     assert(getOperandMapping(Idx).isValid() &&
63281ad6265SDimitry Andric            "We must have a mapping for reg operands");
63381ad6265SDimitry Andric     const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx);
63481ad6265SDimitry Andric     (void)MOMapping;
63581ad6265SDimitry Andric     // Register size in bits.
63681ad6265SDimitry Andric     // This size must match what the mapping expects.
63706c3fb27SDimitry Andric     assert(MOMapping.verify(*RBI, RBI->getSizeInBits(
63806c3fb27SDimitry Andric                                       Reg, MF.getRegInfo(),
63906c3fb27SDimitry Andric                                       *MF.getSubtarget().getRegisterInfo())) &&
64081ad6265SDimitry Andric            "Value mapping is invalid");
64181ad6265SDimitry Andric   }
64281ad6265SDimitry Andric   return true;
64381ad6265SDimitry Andric }
64481ad6265SDimitry Andric 
64581ad6265SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const64681ad6265SDimitry Andric LLVM_DUMP_METHOD void RegisterBankInfo::InstructionMapping::dump() const {
64781ad6265SDimitry Andric   print(dbgs());
64881ad6265SDimitry Andric   dbgs() << '\n';
64981ad6265SDimitry Andric }
65081ad6265SDimitry Andric #endif
65181ad6265SDimitry Andric 
print(raw_ostream & OS) const65281ad6265SDimitry Andric void RegisterBankInfo::InstructionMapping::print(raw_ostream &OS) const {
65381ad6265SDimitry Andric   OS << "ID: " << getID() << " Cost: " << getCost() << " Mapping: ";
65481ad6265SDimitry Andric 
65581ad6265SDimitry Andric   for (unsigned OpIdx = 0; OpIdx != NumOperands; ++OpIdx) {
65681ad6265SDimitry Andric     const ValueMapping &ValMapping = getOperandMapping(OpIdx);
65781ad6265SDimitry Andric     if (OpIdx)
65881ad6265SDimitry Andric       OS << ", ";
65981ad6265SDimitry Andric     OS << "{ Idx: " << OpIdx << " Map: " << ValMapping << '}';
66081ad6265SDimitry Andric   }
66181ad6265SDimitry Andric }
66281ad6265SDimitry Andric 
66381ad6265SDimitry Andric const int RegisterBankInfo::OperandsMapper::DontKnowIdx = -1;
66481ad6265SDimitry Andric 
OperandsMapper(MachineInstr & MI,const InstructionMapping & InstrMapping,MachineRegisterInfo & MRI)66581ad6265SDimitry Andric RegisterBankInfo::OperandsMapper::OperandsMapper(
66681ad6265SDimitry Andric     MachineInstr &MI, const InstructionMapping &InstrMapping,
66781ad6265SDimitry Andric     MachineRegisterInfo &MRI)
66881ad6265SDimitry Andric     : MRI(MRI), MI(MI), InstrMapping(InstrMapping) {
66981ad6265SDimitry Andric   unsigned NumOpds = InstrMapping.getNumOperands();
67081ad6265SDimitry Andric   OpToNewVRegIdx.resize(NumOpds, OperandsMapper::DontKnowIdx);
67181ad6265SDimitry Andric   assert(InstrMapping.verify(MI) && "Invalid mapping for MI");
67281ad6265SDimitry Andric }
67381ad6265SDimitry Andric 
67481ad6265SDimitry Andric iterator_range<SmallVectorImpl<Register>::iterator>
getVRegsMem(unsigned OpIdx)67581ad6265SDimitry Andric RegisterBankInfo::OperandsMapper::getVRegsMem(unsigned OpIdx) {
67681ad6265SDimitry Andric   assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
67781ad6265SDimitry Andric   unsigned NumPartialVal =
67881ad6265SDimitry Andric       getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns;
67981ad6265SDimitry Andric   int StartIdx = OpToNewVRegIdx[OpIdx];
68081ad6265SDimitry Andric 
68181ad6265SDimitry Andric   if (StartIdx == OperandsMapper::DontKnowIdx) {
68281ad6265SDimitry Andric     // This is the first time we try to access OpIdx.
68381ad6265SDimitry Andric     // Create the cells that will hold all the partial values at the
68481ad6265SDimitry Andric     // end of the list of NewVReg.
68581ad6265SDimitry Andric     StartIdx = NewVRegs.size();
68681ad6265SDimitry Andric     OpToNewVRegIdx[OpIdx] = StartIdx;
68781ad6265SDimitry Andric     for (unsigned i = 0; i < NumPartialVal; ++i)
68881ad6265SDimitry Andric       NewVRegs.push_back(0);
68981ad6265SDimitry Andric   }
69081ad6265SDimitry Andric   SmallVectorImpl<Register>::iterator End =
69181ad6265SDimitry Andric       getNewVRegsEnd(StartIdx, NumPartialVal);
69281ad6265SDimitry Andric 
69381ad6265SDimitry Andric   return make_range(&NewVRegs[StartIdx], End);
69481ad6265SDimitry Andric }
69581ad6265SDimitry Andric 
69681ad6265SDimitry Andric SmallVectorImpl<Register>::const_iterator
getNewVRegsEnd(unsigned StartIdx,unsigned NumVal) const69781ad6265SDimitry Andric RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx,
69881ad6265SDimitry Andric                                                  unsigned NumVal) const {
69981ad6265SDimitry Andric   return const_cast<OperandsMapper *>(this)->getNewVRegsEnd(StartIdx, NumVal);
70081ad6265SDimitry Andric }
70181ad6265SDimitry Andric SmallVectorImpl<Register>::iterator
getNewVRegsEnd(unsigned StartIdx,unsigned NumVal)70281ad6265SDimitry Andric RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx,
70381ad6265SDimitry Andric                                                  unsigned NumVal) {
70481ad6265SDimitry Andric   assert((NewVRegs.size() == StartIdx + NumVal ||
70581ad6265SDimitry Andric           NewVRegs.size() > StartIdx + NumVal) &&
70681ad6265SDimitry Andric          "NewVRegs too small to contain all the partial mapping");
70781ad6265SDimitry Andric   return NewVRegs.size() <= StartIdx + NumVal ? NewVRegs.end()
70881ad6265SDimitry Andric                                               : &NewVRegs[StartIdx + NumVal];
70981ad6265SDimitry Andric }
71081ad6265SDimitry Andric 
createVRegs(unsigned OpIdx)71181ad6265SDimitry Andric void RegisterBankInfo::OperandsMapper::createVRegs(unsigned OpIdx) {
71281ad6265SDimitry Andric   assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
71381ad6265SDimitry Andric   iterator_range<SmallVectorImpl<Register>::iterator> NewVRegsForOpIdx =
71481ad6265SDimitry Andric       getVRegsMem(OpIdx);
71581ad6265SDimitry Andric   const ValueMapping &ValMapping = getInstrMapping().getOperandMapping(OpIdx);
71681ad6265SDimitry Andric   const PartialMapping *PartMap = ValMapping.begin();
71781ad6265SDimitry Andric   for (Register &NewVReg : NewVRegsForOpIdx) {
71881ad6265SDimitry Andric     assert(PartMap != ValMapping.end() && "Out-of-bound access");
71981ad6265SDimitry Andric     assert(NewVReg == 0 && "Register has already been created");
72081ad6265SDimitry Andric     // The new registers are always bound to scalar with the right size.
72181ad6265SDimitry Andric     // The actual type has to be set when the target does the mapping
72281ad6265SDimitry Andric     // of the instruction.
72381ad6265SDimitry Andric     // The rationale is that this generic code cannot guess how the
72481ad6265SDimitry Andric     // target plans to split the input type.
72581ad6265SDimitry Andric     NewVReg = MRI.createGenericVirtualRegister(LLT::scalar(PartMap->Length));
72681ad6265SDimitry Andric     MRI.setRegBank(NewVReg, *PartMap->RegBank);
72781ad6265SDimitry Andric     ++PartMap;
72881ad6265SDimitry Andric   }
72981ad6265SDimitry Andric }
73081ad6265SDimitry Andric 
setVRegs(unsigned OpIdx,unsigned PartialMapIdx,Register NewVReg)73181ad6265SDimitry Andric void RegisterBankInfo::OperandsMapper::setVRegs(unsigned OpIdx,
73281ad6265SDimitry Andric                                                 unsigned PartialMapIdx,
73381ad6265SDimitry Andric                                                 Register NewVReg) {
73481ad6265SDimitry Andric   assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
73581ad6265SDimitry Andric   assert(getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns >
73681ad6265SDimitry Andric              PartialMapIdx &&
73781ad6265SDimitry Andric          "Out-of-bound access for partial mapping");
73881ad6265SDimitry Andric   // Make sure the memory is initialized for that operand.
73981ad6265SDimitry Andric   (void)getVRegsMem(OpIdx);
74081ad6265SDimitry Andric   assert(NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] == 0 &&
74181ad6265SDimitry Andric          "This value is already set");
74281ad6265SDimitry Andric   NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] = NewVReg;
74381ad6265SDimitry Andric }
74481ad6265SDimitry Andric 
74581ad6265SDimitry Andric iterator_range<SmallVectorImpl<Register>::const_iterator>
getVRegs(unsigned OpIdx,bool ForDebug) const74681ad6265SDimitry Andric RegisterBankInfo::OperandsMapper::getVRegs(unsigned OpIdx,
74781ad6265SDimitry Andric                                            bool ForDebug) const {
74881ad6265SDimitry Andric   (void)ForDebug;
74981ad6265SDimitry Andric   assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
75081ad6265SDimitry Andric   int StartIdx = OpToNewVRegIdx[OpIdx];
75181ad6265SDimitry Andric 
75281ad6265SDimitry Andric   if (StartIdx == OperandsMapper::DontKnowIdx)
75381ad6265SDimitry Andric     return make_range(NewVRegs.end(), NewVRegs.end());
75481ad6265SDimitry Andric 
75581ad6265SDimitry Andric   unsigned PartMapSize =
75681ad6265SDimitry Andric       getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns;
75781ad6265SDimitry Andric   SmallVectorImpl<Register>::const_iterator End =
75881ad6265SDimitry Andric       getNewVRegsEnd(StartIdx, PartMapSize);
75981ad6265SDimitry Andric   iterator_range<SmallVectorImpl<Register>::const_iterator> Res =
76081ad6265SDimitry Andric       make_range(&NewVRegs[StartIdx], End);
76181ad6265SDimitry Andric #ifndef NDEBUG
76281ad6265SDimitry Andric   for (Register VReg : Res)
76381ad6265SDimitry Andric     assert((VReg || ForDebug) && "Some registers are uninitialized");
76481ad6265SDimitry Andric #endif
76581ad6265SDimitry Andric   return Res;
76681ad6265SDimitry Andric }
76781ad6265SDimitry Andric 
76881ad6265SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const76981ad6265SDimitry Andric LLVM_DUMP_METHOD void RegisterBankInfo::OperandsMapper::dump() const {
77081ad6265SDimitry Andric   print(dbgs(), true);
77181ad6265SDimitry Andric   dbgs() << '\n';
77281ad6265SDimitry Andric }
77381ad6265SDimitry Andric #endif
77481ad6265SDimitry Andric 
print(raw_ostream & OS,bool ForDebug) const77581ad6265SDimitry Andric void RegisterBankInfo::OperandsMapper::print(raw_ostream &OS,
77681ad6265SDimitry Andric                                              bool ForDebug) const {
77781ad6265SDimitry Andric   unsigned NumOpds = getInstrMapping().getNumOperands();
77881ad6265SDimitry Andric   if (ForDebug) {
77981ad6265SDimitry Andric     OS << "Mapping for " << getMI() << "\nwith " << getInstrMapping() << '\n';
78081ad6265SDimitry Andric     // Print out the internal state of the index table.
78181ad6265SDimitry Andric     OS << "Populated indices (CellNumber, IndexInNewVRegs): ";
78281ad6265SDimitry Andric     bool IsFirst = true;
78381ad6265SDimitry Andric     for (unsigned Idx = 0; Idx != NumOpds; ++Idx) {
78481ad6265SDimitry Andric       if (OpToNewVRegIdx[Idx] != DontKnowIdx) {
78581ad6265SDimitry Andric         if (!IsFirst)
78681ad6265SDimitry Andric           OS << ", ";
78781ad6265SDimitry Andric         OS << '(' << Idx << ", " << OpToNewVRegIdx[Idx] << ')';
78881ad6265SDimitry Andric         IsFirst = false;
78981ad6265SDimitry Andric       }
79081ad6265SDimitry Andric     }
79181ad6265SDimitry Andric     OS << '\n';
79281ad6265SDimitry Andric   } else
79381ad6265SDimitry Andric     OS << "Mapping ID: " << getInstrMapping().getID() << ' ';
79481ad6265SDimitry Andric 
79581ad6265SDimitry Andric   OS << "Operand Mapping: ";
79681ad6265SDimitry Andric   // If we have a function, we can pretty print the name of the registers.
79781ad6265SDimitry Andric   // Otherwise we will print the raw numbers.
79881ad6265SDimitry Andric   const TargetRegisterInfo *TRI =
79981ad6265SDimitry Andric       getMI().getParent() && getMI().getMF()
80081ad6265SDimitry Andric           ? getMI().getMF()->getSubtarget().getRegisterInfo()
80181ad6265SDimitry Andric           : nullptr;
80281ad6265SDimitry Andric   bool IsFirst = true;
80381ad6265SDimitry Andric   for (unsigned Idx = 0; Idx != NumOpds; ++Idx) {
80481ad6265SDimitry Andric     if (OpToNewVRegIdx[Idx] == DontKnowIdx)
80581ad6265SDimitry Andric       continue;
80681ad6265SDimitry Andric     if (!IsFirst)
80781ad6265SDimitry Andric       OS << ", ";
80881ad6265SDimitry Andric     IsFirst = false;
80981ad6265SDimitry Andric     OS << '(' << printReg(getMI().getOperand(Idx).getReg(), TRI) << ", [";
81081ad6265SDimitry Andric     bool IsFirstNewVReg = true;
81181ad6265SDimitry Andric     for (Register VReg : getVRegs(Idx)) {
81281ad6265SDimitry Andric       if (!IsFirstNewVReg)
81381ad6265SDimitry Andric         OS << ", ";
81481ad6265SDimitry Andric       IsFirstNewVReg = false;
81581ad6265SDimitry Andric       OS << printReg(VReg, TRI);
81681ad6265SDimitry Andric     }
81781ad6265SDimitry Andric     OS << "])";
81881ad6265SDimitry Andric   }
81981ad6265SDimitry Andric }
820