From: Jakob Stoklund Olesen Date: Wed, 15 Jun 2011 04:50:36 +0000 (+0000) Subject: Give CodeGenRegisterClass a real sorted member set. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ae1920b1efa72c1789d562df4746110d0c2e10bd;p=oota-llvm.git Give CodeGenRegisterClass a real sorted member set. Make the Elements vector private and expose an ArrayRef through getOrder() instead. getOrder will eventually provide multiple user-specified allocation orders. Use the sorted member set for member and subclass tests. Clean up a lot of ad hoc searches. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133040 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index bbe43493d10..1d7a67bf669 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -896,8 +896,8 @@ BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { // Gather the defined sets. for (std::vector::const_iterator it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) - RegisterSets.insert(std::set(it->Elements.begin(), - it->Elements.end())); + RegisterSets.insert(std::set(it->getOrder().begin(), + it->getOrder().end())); // Add any required singleton sets. for (SmallPtrSet::iterator it = SingletonRegisters.begin(), @@ -971,8 +971,8 @@ BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { // Name the register classes which correspond to a user defined RegisterClass. for (std::vector::const_iterator it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) { - ClassInfo *CI = RegisterSetClasses[std::set(it->Elements.begin(), - it->Elements.end())]; + ClassInfo *CI = RegisterSetClasses[std::set(it->getOrder().begin(), + it->getOrder().end())]; if (CI->ValueName.empty()) { CI->ClassName = it->getName(); CI->Name = "MCK_" + it->getName(); diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index bfc63c0cf85..818053a3c42 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -805,16 +805,16 @@ void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) { O << " case RC_" << Name << ":\n"; // Emit the register list now. - unsigned IE = RC.Elements.size(); + unsigned IE = RC.getOrder().size(); if (IE == 1) { - O << " if (Reg == " << getQualifiedName(RC.Elements[0]) << ")\n"; + O << " if (Reg == " << getQualifiedName(RC.getOrder()[0]) << ")\n"; O << " return true;\n"; } else { O << " switch (Reg) {\n"; O << " default: break;\n"; for (unsigned II = 0; II != IE; ++II) { - Record *Reg = RC.Elements[II]; + Record *Reg = RC.getOrder()[II]; O << " case " << getQualifiedName(Reg) << ":\n"; } diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 5b0aedfbc83..73fe9162585 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -417,7 +417,8 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, if (!InstOpRec->isSubClassOf("RegisterClass")) return false; - if (!T.getRegisterClass(InstOpRec).containsRegister(ADI->getDef())) + if (!T.getRegisterClass(InstOpRec) + .contains(T.getRegBank().getReg(ADI->getDef()))) throw TGError(Loc, "fixed register " +ADI->getDef()->getName() + " is not a member of the " + InstOpRec->getName() + " register class!"); diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 37c6856f408..1df9cc10bf1 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -154,7 +154,8 @@ CodeGenRegister::addSubRegsPreOrder(SetVector &OSet) const { // CodeGenRegisterClass //===----------------------------------------------------------------------===// -CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { +CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) + : TheDef(R) { // Rename anonymous register classes. if (R->getName().size() > 9 && R->getName()[9] == '.') { static unsigned AnonCounter = 0; @@ -171,14 +172,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { } assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!"); - std::vector RegList = R->getValueAsListOfDefs("MemberList"); - for (unsigned i = 0, e = RegList.size(); i != e; ++i) { - Record *Reg = RegList[i]; - if (!Reg->isSubClassOf("Register")) - throw "Register Class member '" + Reg->getName() + - "' does not derive from the Register class!"; - Elements.push_back(Reg); - } + Elements = R->getValueAsListOfDefs("MemberList"); + for (unsigned i = 0, e = Elements.size(); i != e; ++i) + Members.insert(RegBank.getReg(Elements[i])); // SubRegClasses is a list containing (RC, subregindex, ...) dags. ListInit *SRC = R->getValueAsListInit("SubRegClasses"); @@ -215,6 +211,26 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { MethodProtos = R->getValueAsCode("MethodProtos"); } +bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { + return Members.count(Reg); +} + +// Returns true if RC is a strict subclass. +// RC is a sub-class of this class if it is a valid replacement for any +// instruction operand where a register of this classis required. It must +// satisfy these conditions: +// +// 1. All RC registers are also in this. +// 2. The RC spill size must not be smaller than our spill size. +// 3. RC spill alignment must be compatible with ours. +// +bool CodeGenRegisterClass::hasSubClass(const CodeGenRegisterClass *RC) const { + return SpillAlignment && RC->SpillAlignment % SpillAlignment == 0 && + SpillSize <= RC->SpillSize && + std::includes(Members.begin(), Members.end(), + RC->Members.begin(), RC->Members.end()); +} + const std::string &CodeGenRegisterClass::getName() const { return TheDef->getName(); } @@ -244,7 +260,8 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { throw std::string("No 'RegisterClass' subclasses defined!"); RegClasses.reserve(RCs.size()); - RegClasses.assign(RCs.begin(), RCs.end()); + for (unsigned i = 0, e = RCs.size(); i != e; ++i) + RegClasses.push_back(CodeGenRegisterClass(*this, RCs[i])); } CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { @@ -432,11 +449,12 @@ void CodeGenRegBank::computeDerivedInfo() { /// superclass. Otherwise return null. const CodeGenRegisterClass* CodeGenRegBank::getRegClassForRegister(Record *R) { + const CodeGenRegister *Reg = getReg(R); const std::vector &RCs = getRegClasses(); const CodeGenRegisterClass *FoundRC = 0; for (unsigned i = 0, e = RCs.size(); i != e; ++i) { const CodeGenRegisterClass &RC = RCs[i]; - if (!RC.containsRegister(R)) + if (!RC.contains(Reg)) continue; // If this is the first class that contains the register, @@ -450,16 +468,10 @@ CodeGenRegBank::getRegClassForRegister(Record *R) { if (RC.getValueTypes() != FoundRC->getValueTypes()) return 0; - std::vector Elements(RC.Elements); - std::vector FoundElements(FoundRC->Elements); - std::sort(Elements.begin(), Elements.end()); - std::sort(FoundElements.begin(), FoundElements.end()); - // Check to see if the previously found class that contains // the register is a subclass of the current class. If so, // prefer the superclass. - if (std::includes(Elements.begin(), Elements.end(), - FoundElements.begin(), FoundElements.end())) { + if (RC.hasSubClass(FoundRC)) { FoundRC = &RC; continue; } @@ -467,8 +479,7 @@ CodeGenRegBank::getRegClassForRegister(Record *R) { // Check to see if the previously found class that contains // the register is a superclass of the current class. If so, // prefer the superclass. - if (std::includes(FoundElements.begin(), FoundElements.end(), - Elements.begin(), Elements.end())) + if (FoundRC->hasSubClass(&RC)) continue; // Multiple classes, and neither is a superclass of the other. diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 26305b6e3b2..d096ccd3f39 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -17,6 +17,7 @@ #include "Record.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include @@ -65,13 +66,14 @@ namespace llvm { // Order CodeGenRegister pointers by EnumValue. struct Less { - bool operator()(const CodeGenRegister *A, const CodeGenRegister *B) { + bool operator()(const CodeGenRegister *A, + const CodeGenRegister *B) const { return A->EnumValue < B->EnumValue; } }; // Canonically ordered set. - typedef std::set Set; + typedef std::set Set; private: bool SubRegsComplete; @@ -80,10 +82,12 @@ namespace llvm { }; - struct CodeGenRegisterClass { + class CodeGenRegisterClass { + CodeGenRegister::Set Members; + std::vector Elements; + public: Record *TheDef; std::string Namespace; - std::vector Elements; std::vector VTs; unsigned SpillSize; unsigned SpillAlignment; @@ -104,13 +108,10 @@ namespace llvm { abort(); } - bool containsRegister(Record *R) const { - for (unsigned i = 0, e = Elements.size(); i != e; ++i) - if (Elements[i] == R) return true; - return false; - } + // Return true if this this class contains the register. + bool contains(const CodeGenRegister*) const; - // Returns true if RC is a strict subclass. + // Returns true if RC is a subclass. // RC is a sub-class of this class if it is a valid replacement for any // instruction operand where a register of this classis required. It must // satisfy these conditions: @@ -119,29 +120,15 @@ namespace llvm { // 2. The RC spill size must not be smaller than our spill size. // 3. RC spill alignment must be compatible with ours. // - bool hasSubClass(const CodeGenRegisterClass *RC) const { - - if (RC->Elements.size() > Elements.size() || - (SpillAlignment && RC->SpillAlignment % SpillAlignment) || - SpillSize > RC->SpillSize) - return false; - - std::set RegSet; - for (unsigned i = 0, e = Elements.size(); i != e; ++i) { - Record *Reg = Elements[i]; - RegSet.insert(Reg); - } - - for (unsigned i = 0, e = RC->Elements.size(); i != e; ++i) { - Record *Reg = RC->Elements[i]; - if (!RegSet.count(Reg)) - return false; - } + bool hasSubClass(const CodeGenRegisterClass *RC) const; - return true; + // Returns an ordered list of class members. + // The order of registers is the same as in the .td file. + ArrayRef getOrder() const { + return Elements; } - CodeGenRegisterClass(Record *R); + CodeGenRegisterClass(CodeGenRegBank&, Record *R); }; // CodeGenRegBank - Represent a target's registers and the relations between diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 9d0aadfdc9c..6751ae7ca85 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -178,15 +178,14 @@ const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const { std::vector CodeGenTarget:: getRegisterVTs(Record *R) const { + const CodeGenRegister *Reg = getRegBank().getReg(R); std::vector Result; const std::vector &RCs = getRegisterClasses(); for (unsigned i = 0, e = RCs.size(); i != e; ++i) { const CodeGenRegisterClass &RC = RCs[i]; - for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) { - if (R == RC.Elements[ei]) { - const std::vector &InVTs = RC.getValueTypes(); - Result.insert(Result.end(), InVTs.begin(), InVTs.end()); - } + if (RC.contains(Reg)) { + const std::vector &InVTs = RC.getValueTypes(); + Result.insert(Result.end(), InVTs.begin(), InVTs.end()); } } diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 402a239ec55..a8736fa2f69 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -25,12 +25,12 @@ static MVT::SimpleValueType getRegisterValueType(Record *R, const CodeGenTarget &T) { bool FoundRC = false; MVT::SimpleValueType VT = MVT::Other; + const CodeGenRegister *Reg = T.getRegBank().getReg(R); const std::vector &RCs = T.getRegisterClasses(); - std::vector::const_iterator Element; for (unsigned rc = 0, e = RCs.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RCs[rc]; - if (!std::count(RC.Elements.begin(), RC.Elements.end(), R)) + if (!RC.contains(Reg)) continue; if (!FoundRC) { diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 67cce0e55f2..fc544ee658b 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -166,13 +166,13 @@ void InstrInfoEmitter::DetectRegisterClassBarriers(std::vector &Defs, for (unsigned i = 0, e = RCs.size(); i != e; ++i) { const CodeGenRegisterClass &RC = RCs[i]; - unsigned NumRegs = RC.Elements.size(); - if (NumRegs > NumDefs) + ArrayRef Order = RC.getOrder(); + if (Order.size() > NumDefs) continue; // Can't possibly clobber this RC. bool Clobber = true; - for (unsigned j = 0; j < NumRegs; ++j) { - Record *Reg = RC.Elements[j]; + for (unsigned j = 0; j < Order.size(); ++j) { + Record *Reg = Order[j]; if (!DefSet.count(Reg)) { Clobber = false; break; diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 6853a0fff86..5e2143614e8 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -214,20 +214,21 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { // Emit the register enum value arrays for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RegisterClasses[rc]; + ArrayRef Order = RC.getOrder(); // Collect allocatable registers. if (RC.Allocatable) - AllocatableRegs.insert(RC.Elements.begin(), RC.Elements.end()); + AllocatableRegs.insert(Order.begin(), Order.end()); // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); + std::string Name = RC.getName(); // Emit the register list now. OS << " // " << Name << " Register Class...\n" << " static const unsigned " << Name << "[] = {\n "; - for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) { - Record *Reg = RC.Elements[i]; + for (unsigned i = 0, e = Order.size(); i != e; ++i) { + Record *Reg = Order[i]; OS << getQualifiedName(Reg) << ", "; } OS << "\n };\n\n"; @@ -238,7 +239,7 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { const CodeGenRegisterClass &RC = RegisterClasses[rc]; // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName() + "VTs"; + std::string Name = RC.getName() + "VTs"; // Emit the register list now. OS << " // " << Name @@ -425,7 +426,8 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { << RC.SpillAlignment/8 << ", " << RC.CopyCost << ", " << RC.Allocatable << ", " - << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size() + << RC.getName() << ", " << RC.getName() << " + " + << RC.getOrder().size() << ") {}\n"; }