diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index 0930f514c02..b8193ce1850 100644 --- a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -47,8 +47,8 @@ protected: /// Add \p RC to the set of register class that the register bank /// identified \p ID covers. - /// This method transitively adds all the sub classes of \p RC - /// to the set of covered register classes. + /// This method transitively adds all the sub classes and the subreg-classes + /// of \p RC 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. /// @@ -56,6 +56,9 @@ protected: /// The rationale is if \p ID covers the registers of \p RC, that /// does not necessarily mean that \p ID covers the set of registers /// of RC'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, const TargetRegisterClass &RC, diff --git a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 8c86491ec8a..80c0b0380be 100644 --- a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -76,15 +76,23 @@ void RegisterBankInfo::addRegBankCoverage(unsigned ID, const uint32_t *SubClassMask = CurRC.getSubClassMask(); // The subclasses mask is broken down into chunks of uint32_t, but it still // represents all register classes. + bool First = true; for (unsigned Base = 0; Base < NbOfRegClasses; Base += 32) { unsigned Idx = Base; for (uint32_t Mask = *SubClassMask++; Mask; Mask >>= 1, ++Idx) { unsigned Offset = countTrailingZeros(Mask); unsigned SubRCId = Idx + Offset; - if (!Covered.test(SubRCId)) + 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); + // Remember that we saw the sub class. + Covered.set(SubRCId); + First = false; + } + // Move the cursor to the next sub class. // I.e., eat up the zeros then move to the next bit. // This last part is done as part of the loop increment. @@ -96,6 +104,61 @@ void RegisterBankInfo::addRegBankCoverage(unsigned ID, Idx += Offset; } } + 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; + const uint32_t *SuperRCMask = SuperRCIt.getMask(); + for (unsigned Base = 0; Base < NbOfRegClasses; Base += 32) { + unsigned Idx = Base; + for (uint32_t Mask = *SuperRCMask++; Mask; Mask >>= 1, ++Idx) { + unsigned Offset = countTrailingZeros(Mask); + unsigned SuperRCId = Idx + Offset; + 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; + } + + // Move the cursor to the next sub class. + // I.e., eat up the zeros then move to the next bit. + // This last part is done as part of the loop increment. + + // By construction, Offset must be less than 32. + // Otherwise, than means Mask was zero. I.e., no UB. + Mask >>= Offset; + // Remember that we shifted the base offset. + Idx += Offset; + } + } + } + } + if (!First) + DEBUG(dbgs() << '\n'); } while (!WorkList.empty()); }