Index: include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -384,10 +384,6 @@ /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks /// RegisterBank instances. - /// - /// \note For the verify method to succeed all the \p NumRegBanks - /// must be initialized by createRegisterBank and updated with - /// addRegBankCoverage RegisterBank. RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks); /// This constructor is meaningless. @@ -400,32 +396,8 @@ llvm_unreachable("This constructor should not be executed"); } - /// Create a new register bank with the given parameter and add it - /// to RegBanks. - /// \pre \p ID must not already be used. - /// \pre \p ID < NumRegBanks. - void createRegisterBank(unsigned ID, const char *Name); - - /// Add \p RCId to the set of register class that the register bank, - /// identified \p ID, covers. - /// This method transitively adds all the sub classes and the subreg-classes - /// of \p RCId to the set of covered register classes. - /// It also adjusts the size of the register bank to reflect the maximal - /// size of a value that can be hold into that register bank. - /// - /// \note This method does *not* add the super classes of \p RCId. - /// The rationale is if \p ID covers the registers of \p RCId, that - /// does not necessarily mean that \p ID covers the set of registers - /// of RCId's superclasses. - /// This method does *not* add the superreg classes as well for consistents. - /// The expected use is to add the coverage top-down with respect to the - /// register hierarchy. - /// - /// \todo TableGen should just generate the BitSet vector for us. - void addRegBankCoverage(unsigned ID, unsigned RCId, - const TargetRegisterInfo &TRI); - void setRegBankData(unsigned ID, unsigned Size); - void setRegBankCoverage(unsigned ID, const uint32_t *CoveredClasses); + void setRegBankData(unsigned ID, const char *Name, unsigned Size, + const uint32_t *CoveredClasses); /// Get the register bank identified by \p ID. RegisterBank &getRegBank(unsigned ID) { Index: lib/CodeGen/GlobalISel/RegisterBankInfo.cpp =================================================================== --- lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -82,120 +82,13 @@ return true; } -void RegisterBankInfo::createRegisterBank(unsigned ID, const char *Name) { - DEBUG(dbgs() << "Create register bank: " << ID << " with name \"" << Name - << "\"\n"); - RegisterBank &RegBank = getRegBank(ID); - assert(RegBank.getID() == RegisterBank::InvalidID && - "A register bank should be created only once"); - RegBank.ID = ID; - RegBank.Name = Name; -} - -void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId, - const TargetRegisterInfo &TRI) { - RegisterBank &RB = getRegBank(ID); - unsigned NbOfRegClasses = TRI.getNumRegClasses(); - - DEBUG(dbgs() << "Add coverage for: " << RB << '\n'); - - // Check if RB is underconstruction. - if (!RB.isValid()) - RB.ContainedRegClasses.resize(NbOfRegClasses); - else if (RB.covers(*TRI.getRegClass(RCId))) - // If RB already covers this register class, there is nothing - // to do. - return; - - BitVector &Covered = RB.ContainedRegClasses; - SmallVector WorkList; - - WorkList.push_back(RCId); - Covered.set(RCId); - - unsigned &MaxSize = RB.Size; - do { - unsigned RCId = WorkList.pop_back_val(); - - const TargetRegisterClass &CurRC = *TRI.getRegClass(RCId); - - DEBUG(dbgs() << "Examine: " << TRI.getRegClassName(&CurRC) - << "(Size*8: " << (CurRC.getSize() * 8) << ")\n"); - - // Remember the biggest size in bits. - MaxSize = std::max(MaxSize, CurRC.getSize() * 8); - - // Walk through all sub register classes and push them into the worklist. - bool First = true; - for (BitMaskClassIterator It(CurRC.getSubClassMask(), TRI); It.isValid(); - ++It) { - unsigned SubRCId = It.getID(); - if (!Covered.test(SubRCId)) { - if (First) - DEBUG(dbgs() << " Enqueue sub-class: "); - DEBUG(dbgs() << TRI.getRegClassName(TRI.getRegClass(SubRCId)) << ", "); - WorkList.push_back(SubRCId); - // Remember that we saw the sub class. - Covered.set(SubRCId); - First = false; - } - } - if (!First) - DEBUG(dbgs() << '\n'); - - // Push also all the register classes that can be accessed via a - // subreg index, i.e., its subreg-class (which is different than - // its subclass). - // - // Note: It would probably be faster to go the other way around - // and have this method add only super classes, since this - // information is available in a more efficient way. However, it - // feels less natural for the client of this APIs plus we will - // TableGen the whole bitset at some point, so compile time for - // the initialization is not very important. - First = true; - for (unsigned SubRCId = 0; SubRCId < NbOfRegClasses; ++SubRCId) { - if (Covered.test(SubRCId)) - continue; - bool Pushed = false; - const TargetRegisterClass *SubRC = TRI.getRegClass(SubRCId); - for (SuperRegClassIterator SuperRCIt(SubRC, &TRI); SuperRCIt.isValid(); - ++SuperRCIt) { - if (Pushed) - break; - for (BitMaskClassIterator It(SuperRCIt.getMask(), TRI); It.isValid(); - ++It) { - unsigned SuperRCId = It.getID(); - if (SuperRCId == RCId) { - if (First) - DEBUG(dbgs() << " Enqueue subreg-class: "); - DEBUG(dbgs() << TRI.getRegClassName(SubRC) << ", "); - WorkList.push_back(SubRCId); - // Remember that we saw the sub class. - Covered.set(SubRCId); - Pushed = true; - First = false; - break; - } - } - } - } - if (!First) - DEBUG(dbgs() << '\n'); - } while (!WorkList.empty()); - - RB.dump(&TRI); - llvm_unreachable("Please call setRegBankData() and setRegBankCoverage() instead"); -} - -void RegisterBankInfo::setRegBankData(unsigned ID, unsigned Size) { +void RegisterBankInfo::setRegBankData(unsigned ID, const char *Name, + unsigned Size, + const uint32_t *CoveredClasses) { RegisterBank &RB = getRegBank(ID); + RB.ID = ID; + RB.Name = Name; RB.Size = Size; -} - -void RegisterBankInfo::setRegBankCoverage(unsigned ID, - const uint32_t *CoveredClasses) { - RegisterBank &RB = getRegBank(ID); RB.ContainedRegClasses.resize(200); RB.ContainedRegClasses.setBitsInMask(CoveredClasses); } Index: lib/Target/AArch64/AArch64GenRegisterBankInfo.def =================================================================== --- lib/Target/AArch64/AArch64GenRegisterBankInfo.def +++ lib/Target/AArch64/AArch64GenRegisterBankInfo.def @@ -18,6 +18,129 @@ namespace llvm { namespace AArch64 { +const uint32_t GPRCoverageData[] = { + // Classes 0-31 + (1u << AArch64::GPR32allRegClassID) | (1u << AArch64::GPR32RegClassID) | + (1u << AArch64::GPR32spRegClassID) | + (1u << AArch64::GPR32commonRegClassID) | + (1u << AArch64::GPR32sponlyRegClassID) | + (1u << AArch64::GPR64allRegClassID) | (1u << AArch64::GPR64RegClassID) | + (1u << AArch64::GPR64spRegClassID) | + (1u << AArch64::GPR64commonRegClassID) | + (1u << AArch64::tcGPR64RegClassID) | + (1u << AArch64::GPR64sponlyRegClassID), + // Classes 32-63 + 0, + // FIXME: The entries below this point can be safely removed once this is + // tablegenerated. It's only needed because of the hardcoded register class + // limit. + // Classes 64-96 + 0, + // Classes 97-128 + 0, + // Classes 129-160 + 0, + // Classes 161-192 + 0, + // Classes 193-224 + 0, +}; + +const uint32_t FPRCoverageData[] = { + // Classes 0-31 + (1u << AArch64::FPR8RegClassID) | (1u << AArch64::FPR16RegClassID) | + (1u << AArch64::FPR32RegClassID) | (1u << AArch64::FPR64RegClassID) | + (1u << AArch64::DDRegClassID) | (1u << AArch64::FPR128RegClassID) | + (1u << AArch64::FPR128_loRegClassID) | (1u << AArch64::DDDRegClassID) | + (1u << AArch64::DDDDRegClassID), + // Classes 32-63 + (1u << (AArch64::QQRegClassID - 32)) | + (1u << (AArch64::QQ_with_qsub0_in_FPR128_loRegClassID - 32)) | + (1u << (AArch64::QQ_with_qsub1_in_FPR128_loRegClassID - 32)) | + (1u + << (AArch64:: + QQQ_with_qsub1_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID - + 32)) | + (1u + << (AArch64:: + QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID - + 32)) | + (1u << (AArch64::QQQQRegClassID - 32)) | + (1u << (AArch64::QQQQ_with_qsub0_in_FPR128_loRegClassID - 32)) | + (1u << (AArch64::QQQQ_with_qsub1_in_FPR128_loRegClassID - 32)) | + (1u << (AArch64::QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | + (1u << (AArch64::QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) | + (1u + << (AArch64:: + QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub1_in_FPR128_loRegClassID - + 32)) | + (1u + << (AArch64:: + QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID - + 32)) | + (1u + << (AArch64:: + QQQQ_with_qsub2_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - + 32)) | + (1u + << (AArch64:: + QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID - + 32)) | + (1u + << (AArch64:: + QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - + 32)) | + (1u + << (AArch64:: + QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - + 32)) | + (1u + << (AArch64:: + QQ_with_qsub0_in_FPR128_lo_and_QQ_with_qsub1_in_FPR128_loRegClassID - + 32)) | + (1u << (AArch64::QQQRegClassID - 32)) | + (1u << (AArch64::QQQ_with_qsub0_in_FPR128_loRegClassID - 32)) | + (1u << (AArch64::QQQ_with_qsub1_in_FPR128_loRegClassID - 32)) | + (1u << (AArch64::QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | + (1u + << (AArch64:: + QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub1_in_FPR128_loRegClassID - + 32)), + // FIXME: The entries below this point can be safely removed once this + // is tablegenerated. It's only needed because of the hardcoded register + // class limit. + // Classes 64-96 + 0, + // Classes 97-128 + 0, + // Classes 129-160 + 0, + // Classes 161-192 + 0, + // Classes 193-224 + 0, +}; + +const uint32_t CCRCoverageData[] = { + // Classes 0-31 + 1u << AArch64::CCRRegClassID, + // Classes 32-63 + 0, + // FIXME: The entries below this point can be safely removed once this + // is tablegenerated. It's only needed because of the hardcoded register + // class limit. + // Classes 64-96 + 0, + // Classes 97-128 + 0, + // Classes 129-160 + 0, + // Classes 161-192 + 0, + // Classes 193-224 + 0, +}; + RegisterBank GPRRegBank; RegisterBank FPRRegBank; RegisterBank CCRRegBank; Index: lib/Target/AArch64/AArch64RegisterBankInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -30,129 +30,6 @@ #error "You shouldn't build this" #endif -const uint32_t GPRCoverageData[] = { - // Classes 0-31 - (1u << AArch64::GPR32allRegClassID) | (1u << AArch64::GPR32RegClassID) | - (1u << AArch64::GPR32spRegClassID) | - (1u << AArch64::GPR32commonRegClassID) | - (1u << AArch64::GPR32sponlyRegClassID) | - (1u << AArch64::GPR64allRegClassID) | (1u << AArch64::GPR64RegClassID) | - (1u << AArch64::GPR64spRegClassID) | - (1u << AArch64::GPR64commonRegClassID) | - (1u << AArch64::tcGPR64RegClassID) | - (1u << AArch64::GPR64sponlyRegClassID), - // Classes 32-63 - 0, - // FIXME: The entries below this point can be safely removed once this is - // tablegenerated. It's only needed because of the hardcoded register class - // limit. - // Classes 64-96 - 0, - // Classes 97-128 - 0, - // Classes 129-160 - 0, - // Classes 161-192 - 0, - // Classes 193-224 - 0, -}; - -const uint32_t FPRCoverageData[] = { - // Classes 0-31 - (1u << AArch64::FPR8RegClassID) | (1u << AArch64::FPR16RegClassID) | - (1u << AArch64::FPR32RegClassID) | (1u << AArch64::FPR64RegClassID) | - (1u << AArch64::DDRegClassID) | (1u << AArch64::FPR128RegClassID) | - (1u << AArch64::FPR128_loRegClassID) | (1u << AArch64::DDDRegClassID) | - (1u << AArch64::DDDDRegClassID), - // Classes 32-63 - (1u << (AArch64::QQRegClassID - 32)) | - (1u << (AArch64::QQ_with_qsub0_in_FPR128_loRegClassID - 32)) | - (1u << (AArch64::QQ_with_qsub1_in_FPR128_loRegClassID - 32)) | - (1u - << (AArch64:: - QQQ_with_qsub1_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID - - 32)) | - (1u - << (AArch64:: - QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID - - 32)) | - (1u << (AArch64::QQQQRegClassID - 32)) | - (1u << (AArch64::QQQQ_with_qsub0_in_FPR128_loRegClassID - 32)) | - (1u << (AArch64::QQQQ_with_qsub1_in_FPR128_loRegClassID - 32)) | - (1u << (AArch64::QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | - (1u << (AArch64::QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) | - (1u - << (AArch64:: - QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub1_in_FPR128_loRegClassID - - 32)) | - (1u - << (AArch64:: - QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID - - 32)) | - (1u - << (AArch64:: - QQQQ_with_qsub2_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - - 32)) | - (1u - << (AArch64:: - QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID - - 32)) | - (1u - << (AArch64:: - QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - - 32)) | - (1u - << (AArch64:: - QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - - 32)) | - (1u - << (AArch64:: - QQ_with_qsub0_in_FPR128_lo_and_QQ_with_qsub1_in_FPR128_loRegClassID - - 32)) | - (1u << (AArch64::QQQRegClassID - 32)) | - (1u << (AArch64::QQQ_with_qsub0_in_FPR128_loRegClassID - 32)) | - (1u << (AArch64::QQQ_with_qsub1_in_FPR128_loRegClassID - 32)) | - (1u << (AArch64::QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | - (1u - << (AArch64:: - QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub1_in_FPR128_loRegClassID - - 32)), - // FIXME: The entries below this point can be safely removed once this - // is tablegenerated. It's only needed because of the hardcoded register - // class limit. - // Classes 64-96 - 0, - // Classes 97-128 - 0, - // Classes 129-160 - 0, - // Classes 161-192 - 0, - // Classes 193-224 - 0, -}; - -const uint32_t CCRCoverageData[] = { - // Classes 0-31 - 1u << AArch64::CCRRegClassID, - // Classes 32-63 - 0, - // FIXME: The entries below this point can be safely removed once this - // is tablegenerated. It's only needed because of the hardcoded register - // class limit. - // Classes 64-96 - 0, - // Classes 97-128 - 0, - // Classes 129-160 - 0, - // Classes 161-192 - 0, - // Classes 193-224 - 0, -}; - AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI) : RegisterBankInfo(AArch64::RegBanks, AArch64::NumRegisterBanks) { static bool AlreadyInit = false; @@ -164,12 +41,9 @@ if (AlreadyInit) return; AlreadyInit = true; - // Initialize the GPR bank. - createRegisterBank(AArch64::GPRRegBankID, "GPR"); // The GPR register bank is fully defined by all the registers in // GR64all + its subclasses. - setRegBankData(AArch64::GPRRegBankID, 64); - setRegBankCoverage(AArch64::GPRRegBankID, GPRCoverageData); + setRegBankData(AArch64::GPRRegBankID, "GPR", 64, AArch64::GPRCoverageData); const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID); (void)RBGPR; assert(&AArch64::GPRRegBank == &RBGPR && @@ -178,12 +52,9 @@ "Subclass not added?"); assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit"); - // Initialize the FPR bank. - createRegisterBank(AArch64::FPRRegBankID, "FPR"); // The FPR register bank is fully defined by all the registers in // GR64all + its subclasses. - setRegBankData(AArch64::FPRRegBankID, 512); - setRegBankCoverage(AArch64::FPRRegBankID, FPRCoverageData); + setRegBankData(AArch64::FPRRegBankID, "FPR", 512, AArch64::FPRCoverageData); const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID); (void)RBFPR; @@ -197,9 +68,7 @@ "FPRs should hold up to 512-bit via QQQQ sequence"); // Initialize the CCR bank. - createRegisterBank(AArch64::CCRRegBankID, "CCR"); - setRegBankData(AArch64::CCRRegBankID, 32); - setRegBankCoverage(AArch64::CCRRegBankID, CCRCoverageData); + setRegBankData(AArch64::CCRRegBankID, "CCR", 32, AArch64::CCRCoverageData); const RegisterBank &RBCCR = getRegBank(AArch64::CCRRegBankID); (void)RBCCR; assert(&AArch64::CCRRegBank == &RBCCR && Index: lib/Target/ARM/ARMRegisterBankInfo.cpp =================================================================== --- lib/Target/ARM/ARMRegisterBankInfo.cpp +++ lib/Target/ARM/ARMRegisterBankInfo.cpp @@ -111,9 +111,7 @@ AlreadyInit = true; // Initialize the GPR bank. - createRegisterBank(ARM::GPRRegBankID, "GPRB"); - setRegBankData(ARM::GPRRegBankID, 32); - setRegBankCoverage(ARM::GPRRegBankID, ARM::GPRCoverageData); + setRegBankData(ARM::GPRRegBankID, "GPRB", 32, ARM::GPRCoverageData); const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID); (void)RBGPR; assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up");