diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h index f528d1a460128c..8a8d3ce200409a 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h @@ -29,18 +29,23 @@ class RegisterBank { private: unsigned ID; const char *Name; - unsigned Size; + const unsigned *Sizes; BitVector ContainedRegClasses; - /// Sentinel value used to recognize register bank not properly + /// HwMode of the target. Not initialized by the constructor, initialized + /// within generated RegisterBankInfo class constructor. + unsigned HwMode; + + /// Sentinel values used to recognize register bank not properly /// initialized yet. static const unsigned InvalidID; + static const unsigned InvalidHwMode; /// Only the RegisterBankInfo can initialize RegisterBank properly. friend RegisterBankInfo; public: - RegisterBank(unsigned ID, const char *Name, unsigned Size, + RegisterBank(unsigned ID, const char *Name, const unsigned *Sizes, const uint32_t *CoveredClasses, unsigned NumRegClasses); /// Get the identifier of this register bank. @@ -51,7 +56,7 @@ class RegisterBank { const char *getName() const { return Name; } /// Get the maximal size in bits that fits in this register bank. - unsigned getSize() const { return Size; } + unsigned getSize() const { return Sizes[HwMode]; } /// Check whether this instance is ready to be used. bool isValid() const; diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index 8725d96efd8214..b86d2d10322f0d 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -415,7 +415,8 @@ class RegisterBankInfo { /// Create a RegisterBankInfo that can accommodate up to \p NumRegBanks /// RegisterBank instances. - RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks); + RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks, + unsigned HwMode); /// This constructor is meaningless. /// It just provides a default constructor that can be used at link time diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp index fc9c802693abdc..54e5d48edf2761 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp @@ -19,11 +19,12 @@ using namespace llvm; const unsigned RegisterBank::InvalidID = UINT_MAX; +const unsigned RegisterBank::InvalidHwMode = UINT_MAX; RegisterBank::RegisterBank( - unsigned ID, const char *Name, unsigned Size, + unsigned ID, const char *Name, const unsigned *Sizes, const uint32_t *CoveredClasses, unsigned NumRegClasses) - : ID(ID), Name(Name), Size(Size) { + : ID(ID), Name(Name), Sizes(Sizes), HwMode(InvalidHwMode) { ContainedRegClasses.resize(NumRegClasses); ContainedRegClasses.setBitsInMask(CoveredClasses); } @@ -63,7 +64,8 @@ bool RegisterBank::covers(const TargetRegisterClass &RC) const { } bool RegisterBank::isValid() const { - return ID != InvalidID && Name != nullptr && Size != 0 && + return ID != InvalidID && Name != nullptr && Sizes != nullptr && + HwMode != InvalidID && // A register bank that does not cover anything is useless. !ContainedRegClasses.empty(); } diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 255ea693b5c4ab..3a8d0a9d3c4fc9 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -56,8 +56,11 @@ const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1; // RegisterBankInfo implementation. //------------------------------------------------------------------------------ RegisterBankInfo::RegisterBankInfo(RegisterBank **RegBanks, - unsigned NumRegBanks) + unsigned NumRegBanks, unsigned HwMode) : RegBanks(RegBanks), NumRegBanks(NumRegBanks) { + // Initialize HwMode for all RegBanks + for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) + RegBanks[Idx]->HwMode = HwMode; #ifndef NDEBUG for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) { assert(RegBanks[Idx] != nullptr && "Invalid RegisterBank"); diff --git a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp index bd3b95a98b9f78..9db3107da0733f 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp @@ -22,5 +22,5 @@ using namespace llvm; -RISCVRegisterBankInfo::RISCVRegisterBankInfo(const TargetRegisterInfo &TRI) - : RISCVGenRegisterBankInfo() {} +RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode) + : RISCVGenRegisterBankInfo(HwMode) {} diff --git a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h index 05fac992734d99..71dddd28380dec 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h +++ b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h @@ -31,7 +31,7 @@ class RISCVGenRegisterBankInfo : public RegisterBankInfo { /// This class provides the information for the target register banks. class RISCVRegisterBankInfo final : public RISCVGenRegisterBankInfo { public: - RISCVRegisterBankInfo(const TargetRegisterInfo &TRI); + RISCVRegisterBankInfo(unsigned HwMode); }; } // end namespace llvm #endif diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp index 47a48c820a290c..9815a785268906 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp @@ -56,7 +56,7 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef FS, CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering())); Legalizer.reset(new RISCVLegalizerInfo(*this)); - auto *RBI = new RISCVRegisterBankInfo(*getRegisterInfo()); + auto *RBI = new RISCVRegisterBankInfo(getHwMode()); RegBankInfo.reset(RBI); InstSelector.reset(createRISCVInstructionSelector( *static_cast(&TM), *this, *RBI)); diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp index 586f857b1fb0d0..5d0751d144516b 100644 --- a/llvm/utils/TableGen/RegisterBankEmitter.cpp +++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp @@ -37,12 +37,12 @@ class RegisterBank { /// The register classes that are covered by the register bank. RegisterClassesTy RCs; - /// The register class with the largest register size. - const CodeGenRegisterClass *RCWithLargestRegsSize; + /// The register classes with the largest register size for each HwMode. + std::vector RCsWithLargestRegSize; public: - RegisterBank(const Record &TheDef) - : TheDef(TheDef), RCs(), RCWithLargestRegsSize(nullptr) {} + RegisterBank(const Record &TheDef, unsigned NumModeIds) + : TheDef(TheDef), RCs(), RCsWithLargestRegSize(NumModeIds) {} /// Get the human-readable name for the bank. StringRef getName() const { return TheDef.getValueAsString("Name"); } @@ -54,6 +54,10 @@ class RegisterBank { return (TheDef.getName() + "CoverageData").str(); } + std::string getSizesArrayName() const { + return (TheDef.getName() + "Sizes").str(); + } + /// Get the name of the global instance variable. StringRef getInstanceVarName() const { return TheDef.getName(); } @@ -83,18 +87,20 @@ class RegisterBank { // register size anywhere (we could sum the sizes of the subregisters // but there may be additional bits too) and we can't derive it from // the VT's reliably due to Untyped. - if (RCWithLargestRegsSize == nullptr) - RCWithLargestRegsSize = RC; - else if (RCWithLargestRegsSize->RSI.get(DefaultMode).SpillSize < - RC->RSI.get(DefaultMode).SpillSize) - RCWithLargestRegsSize = RC; - assert(RCWithLargestRegsSize && "RC was nullptr?"); - + unsigned NumModeIds = RCsWithLargestRegSize.size(); + for (unsigned M = 0; M < NumModeIds; ++M) { + if (RCsWithLargestRegSize[M] == nullptr) + RCsWithLargestRegSize[M] = RC; + else if (RCsWithLargestRegSize[M]->RSI.get(M).SpillSize < + RC->RSI.get(M).SpillSize) + RCsWithLargestRegSize[M] = RC; + assert(RCsWithLargestRegSize[M] && "RC was nullptr?"); + } RCs.emplace_back(RC); } - const CodeGenRegisterClass *getRCWithLargestRegsSize() const { - return RCWithLargestRegsSize; + const CodeGenRegisterClass *getRCWithLargestRegsSize(unsigned HwMode) const { + return RCsWithLargestRegSize[HwMode]; } iterator_range @@ -147,7 +153,7 @@ void RegisterBankEmitter::emitBaseClassDefinition( OS << "private:\n" << " static RegisterBank *RegBanks[];\n\n" << "protected:\n" - << " " << TargetName << "GenRegisterBankInfo();\n" + << " " << TargetName << "GenRegisterBankInfo(unsigned HwMode = 0);\n" << "\n"; } @@ -213,6 +219,7 @@ void RegisterBankEmitter::emitBaseClassImplementation( raw_ostream &OS, StringRef TargetName, std::vector &Banks) { const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank(); + const CodeGenHwModes &CGH = Target.getHwModes(); OS << "namespace llvm {\n" << "namespace " << TargetName << " {\n"; @@ -240,14 +247,30 @@ void RegisterBankEmitter::emitBaseClassImplementation( } OS << "\n"; + unsigned NumModeIds = CGH.getNumModeIds(); + for (const auto &Bank : Banks) { + OS << "const unsigned " << Bank.getSizesArrayName() << "[] = {\n"; + for (unsigned M = 0; M < NumModeIds; ++M) { + const CodeGenRegisterClass &RC = *Bank.getRCWithLargestRegsSize(M); + unsigned Size = RC.RSI.get(M).SpillSize; + OS << " // Mode = " << M << " ("; + if (M == 0) + OS << "Default"; + else + OS << CGH.getMode(M).Name; + OS << ")\n"; + OS << " " << Size << ",\n"; + } + OS << "};\n"; + } + OS << "\n"; + for (const auto &Bank : Banks) { std::string QualifiedBankID = (TargetName + "::" + Bank.getEnumeratorName()).str(); - const CodeGenRegisterClass &RC = *Bank.getRCWithLargestRegsSize(); - unsigned Size = RC.RSI.get(DefaultMode).SpillSize; OS << "RegisterBank " << Bank.getInstanceVarName() << "(/* ID */ " << QualifiedBankID << ", /* Name */ \"" << Bank.getName() - << "\", /* Size */ " << Size << ", " + << "\", /* Sizes */ " << Bank.getInstanceVarName() << "Sizes, " << "/* CoveredRegClasses */ " << Bank.getCoverageArrayName() << ", /* NumRegClasses */ " << RegisterClassHierarchy.getRegClasses().size() << ");\n"; @@ -262,9 +285,9 @@ void RegisterBankEmitter::emitBaseClassImplementation( OS << "};\n\n"; OS << TargetName << "GenRegisterBankInfo::" << TargetName - << "GenRegisterBankInfo()\n" + << "GenRegisterBankInfo(unsigned HwMode)\n" << " : RegisterBankInfo(RegBanks, " << TargetName - << "::NumRegisterBanks) {\n" + << "::NumRegisterBanks, HwMode) {\n" << " // Assert that RegBank indices match their ID's\n" << "#ifndef NDEBUG\n" << " unsigned Index = 0;\n" @@ -278,11 +301,12 @@ void RegisterBankEmitter::emitBaseClassImplementation( void RegisterBankEmitter::run(raw_ostream &OS) { StringRef TargetName = Target.getName(); const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank(); + const CodeGenHwModes &CGH = Target.getHwModes(); std::vector Banks; for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) { SmallPtrSet VisitedRCs; - RegisterBank Bank(*V); + RegisterBank Bank(*V, CGH.getNumModeIds()); for (const CodeGenRegisterClass *RC : Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {