From: Jakob Stoklund Olesen Date: Fri, 30 Sep 2011 22:19:07 +0000 (+0000) Subject: Store sub-class lists as a bit vector. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=c8e2bb68bbc4a71cc10084c8f89565b9f05e12ef;p=oota-llvm.git 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 --- diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index e0e40054d22..bf9174cbc67 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -40,17 +40,17 @@ public: private: const MCRegisterClass *MC; const vt_iterator VTs; - const sc_iterator SubClasses; + const unsigned *SubClassMask; const sc_iterator SuperClasses; const sc_iterator SubRegClasses; const sc_iterator SuperRegClasses; public: TargetRegisterClass(const MCRegisterClass *MC, const EVT *vts, - const TargetRegisterClass * const *subcs, + const unsigned *subcm, const TargetRegisterClass * const *supcs, const TargetRegisterClass * const *subregcs, const TargetRegisterClass * const *superregcs) - : MC(MC), VTs(vts), SubClasses(subcs), SuperClasses(supcs), + : MC(MC), VTs(vts), SubClassMask(subcm), SuperClasses(supcs), SubRegClasses(subregcs), SuperRegClasses(superregcs) {} virtual ~TargetRegisterClass() {} // Allow subclasses @@ -159,57 +159,42 @@ public: } /// hasSubClass - return true if the specified TargetRegisterClass - /// is a proper subset of this TargetRegisterClass. - bool hasSubClass(const TargetRegisterClass *cs) const { - for (int i = 0; SubClasses[i] != NULL; ++i) - if (SubClasses[i] == cs) - return true; - return false; + /// is a proper sub-class of this TargetRegisterClass. + bool hasSubClass(const TargetRegisterClass *RC) const { + return RC != this && hasSubClassEq(RC); } - /// hasSubClassEq - Returns true if RC is a subclass of or equal to this + /// hasSubClassEq - Returns true if RC is a sub-class of or equal to this /// class. bool hasSubClassEq(const TargetRegisterClass *RC) const { - return RC == this || hasSubClass(RC); - } - - /// subclasses_begin / subclasses_end - Loop over all of the classes - /// that are proper subsets of this register class. - sc_iterator subclasses_begin() const { - return SubClasses; - } - - sc_iterator subclasses_end() const { - sc_iterator I = SubClasses; - while (*I != NULL) ++I; - return I; + unsigned ID = RC->getID(); + return (SubClassMask[ID / 32] >> (ID % 32)) & 1; } /// hasSuperClass - return true if the specified TargetRegisterClass is a - /// proper superset of this TargetRegisterClass. - bool hasSuperClass(const TargetRegisterClass *cs) const { - for (int i = 0; SuperClasses[i] != NULL; ++i) - if (SuperClasses[i] == cs) - return true; - return false; + /// proper super-class of this TargetRegisterClass. + bool hasSuperClass(const TargetRegisterClass *RC) const { + return RC->hasSubClass(this); } - /// hasSuperClassEq - Returns true if RC is a superclass of or equal to this + /// hasSuperClassEq - Returns true if RC is a super-class of or equal to this /// class. bool hasSuperClassEq(const TargetRegisterClass *RC) const { - return RC == this || hasSuperClass(RC); + return RC->hasSubClassEq(this); } - /// superclasses_begin / superclasses_end - Loop over all of the classes - /// that are proper supersets of this register class. - sc_iterator superclasses_begin() const { - return SuperClasses; + /// getSubClassMask - Returns a bit vector of subclasses, including this one. + /// The vector is indexed by class IDs, see hasSubClassEq() above for how to + /// use it. + const unsigned *getSubClassMask() const { + return SubClassMask; } - sc_iterator superclasses_end() const { - sc_iterator I = SuperClasses; - while (*I != NULL) ++I; - return I; + /// getSuperClasses - Returns a NULL terminated list of super-classes. The + /// classes are ordered by ID which is also a topological ordering from large + /// to small classes. The list does NOT include the current class. + sc_iterator getSuperClasses() const { + return SuperClasses; } /// isASubClass - return true if this TargetRegisterClass is a subset diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index aabef25ea6a..7c42342229a 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -353,7 +353,7 @@ const TargetRegisterClass* ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC) const { const TargetRegisterClass *Super = RC; - TargetRegisterClass::sc_iterator I = RC->superclasses_begin(); + TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); do { switch (Super->getID()) { case ARM::GPRRegClassID: diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp index c4b084dfc82..67239b830eb 100644 --- a/lib/Target/TargetRegisterInfo.cpp +++ b/lib/Target/TargetRegisterInfo.cpp @@ -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 - - // 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; + // 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)); + + // No common sub-class exists. + return NULL; } diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index ba8be69fe35..70402f3fdb8 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -235,7 +235,7 @@ X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass* X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC) const{ const TargetRegisterClass *Super = RC; - TargetRegisterClass::sc_iterator I = RC->superclasses_begin(); + TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); do { switch (Super->getID()) { case X86::GR8RegClassID: diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index c00c7aa62df..e5185020b7c 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -622,26 +622,9 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Give the register class a legal C name if it's anonymous. std::string Name = RC.TheDef->getName(); - OS << " // " << Name - << " Register Class sub-classes...\n" - << " static const TargetRegisterClass* const " - << Name << "Subclasses[] = {\n "; - - bool Empty = true; - for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) { - const CodeGenRegisterClass &RC2 = *RegisterClasses[rc2]; - - // Sub-classes are used to determine if a virtual register can be used - // as an instruction operand, or if it must be copied first. - if (rc == rc2 || !RC.hasSubClass(&RC2)) continue; - - if (!Empty) OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; - Empty = false; - } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; + OS << " static const unsigned " << Name << "SubclassMask[] = { "; + printBitVectorAsHex(OS, RC.getSubClasses(), 32); + OS << "};\n\n"; } // Emit NULL terminated super-class lists. @@ -668,7 +651,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << Target.getName() << "MCRegisterClasses[" << RC.getName() + "RegClassID" << "], " << RC.getName() + "VTs" << ", " - << RC.getName() + "Subclasses" << ", "; + << RC.getName() + "SubclassMask" << ", "; if (RC.getSuperClasses().empty()) OS << "NullRegClasses, "; else