[RegisterBankInfo] Make addRegBankCoverage more capable to ease

targeting jobs.
Now, addRegBankCoverage also adds the subreg-classes not just the
sub-classes of the given register class.

llvm-svn: 265469
This commit is contained in:
Quentin Colombet 2016-04-05 21:20:12 +00:00
parent c92c4f5e10
commit 7a53b05767
2 changed files with 71 additions and 5 deletions

View File

@ -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,

View File

@ -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());
}