Store sub-class lists as a bit vector.

This uses less memory and it reduces the complexity of sub-class
operations:

- hasSubClassEq() and friends become O(1) instead of O(N).

- getCommonSubClass() becomes O(N) instead of O(N^2).

In the future, TableGen will infer register classes.  This makes it
cheap to add them.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140898 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen
2011-09-30 22:19:07 +00:00
parent b7359e384f
commit c8e2bb68bb
5 changed files with 43 additions and 94 deletions

View File

@@ -100,42 +100,23 @@ BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF,
const TargetRegisterClass *
TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A,
const TargetRegisterClass *B) const {
// First take care of the trivial cases
// First take care of the trivial cases.
if (A == B)
return A;
if (!A || !B)
return 0;
// If B is a subclass of A, it will be handled in the loop below
if (B->hasSubClass(A))
return A;
// Register classes are ordered topologically, so the largest common
// sub-class it the common sub-class with the smallest ID.
const unsigned *SubA = A->getSubClassMask();
const unsigned *SubB = B->getSubClassMask();
const TargetRegisterClass *Best = 0;
for (TargetRegisterClass::sc_iterator I = A->subclasses_begin();
const TargetRegisterClass *X = *I; ++I) {
if (X == B)
return B; // B is a subclass of A
// We could start the search from max(A.ID, B.ID), but we are only going to
// execute 2-3 iterations anyway.
for (unsigned Base = 0, BaseE = getNumRegClasses(); Base < BaseE; Base += 32)
if (unsigned Common = *SubA++ & *SubB++)
return getRegClass(Base + CountTrailingZeros_32(Common));
// X must be a common subclass of A and B
if (!B->hasSubClass(X))
continue;
// A superclass is definitely better.
if (!Best || Best->hasSuperClass(X)) {
Best = X;
continue;
}
// A subclass is definitely worse
if (Best->hasSubClass(X))
continue;
// Best and *I have no super/sub class relation - pick the larger class, or
// the smaller spill size.
int nb = std::distance(Best->begin(), Best->end());
int ni = std::distance(X->begin(), X->end());
if (ni>nb || (ni==nb && X->getSize() < Best->getSize()))
Best = X;
}
return Best;
// No common sub-class exists.
return NULL;
}