diff options
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeGenRegisters.cpp | 71 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 17 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 12 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.h | 66 | ||||
-rw-r--r-- | utils/TableGen/FastISelEmitter.cpp | 2 |
5 files changed, 92 insertions, 76 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 85834e1..37c6856 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -237,6 +237,14 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { // Assign the enumeration values. for (unsigned i = 0, e = Regs.size(); i != e; ++i) Registers.push_back(CodeGenRegister(Regs[i], i + 1)); + + // Read in register class definitions. + std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass"); + if (RCs.empty()) + throw std::string("No 'RegisterClass' subclasses defined!"); + + RegClasses.reserve(RCs.size()); + RegClasses.assign(RCs.begin(), RCs.end()); } CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { @@ -250,6 +258,17 @@ CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { throw TGError(Def->getLoc(), "Not a known Register!"); } +CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { + if (Def2RC.empty()) + for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) + Def2RC[RegClasses[i].TheDef] = &RegClasses[i]; + + if (CodeGenRegisterClass *RC = Def2RC[Def]) + return RC; + + throw TGError(Def->getLoc(), "Not a known RegisterClass!"); +} + Record *CodeGenRegBank::getCompositeSubRegIndex(Record *A, Record *B, bool create) { // Look for an existing entry. @@ -406,3 +425,55 @@ void CodeGenRegBank::computeDerivedInfo() { computeComposites(); } +/// getRegisterClassForRegister - Find the register class that contains the +/// specified physical register. If the register is not in a register class, +/// return null. If the register is in multiple classes, and the classes have a +/// superset-subset relationship and the same set of types, return the +/// superclass. Otherwise return null. +const CodeGenRegisterClass* +CodeGenRegBank::getRegClassForRegister(Record *R) { + const std::vector<CodeGenRegisterClass> &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)) + continue; + + // If this is the first class that contains the register, + // make a note of it and go on to the next class. + if (!FoundRC) { + FoundRC = &RC; + continue; + } + + // If a register's classes have different types, return null. + if (RC.getValueTypes() != FoundRC->getValueTypes()) + return 0; + + std::vector<Record *> Elements(RC.Elements); + std::vector<Record *> 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())) { + FoundRC = &RC; + continue; + } + + // 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())) + continue; + + // Multiple classes, and neither is a superclass of the other. + // Return null. + return 0; + } + return FoundRC; +} diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 233ceb2..26305b6 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -153,6 +153,9 @@ namespace llvm { std::vector<CodeGenRegister> Registers; DenseMap<Record*, CodeGenRegister*> Def2Reg; + std::vector<CodeGenRegisterClass> RegClasses; + DenseMap<Record*, CodeGenRegisterClass*> Def2RC; + // Composite SubRegIndex instances. // Map (SubRegIndex, SubRegIndex) -> SubRegIndex. typedef DenseMap<std::pair<Record*, Record*>, Record*> CompositeMap; @@ -181,6 +184,20 @@ namespace llvm { // Find a register from its Record def. CodeGenRegister *getReg(Record*); + const std::vector<CodeGenRegisterClass> &getRegClasses() { + return RegClasses; + } + + // Find a register class from its def. + CodeGenRegisterClass *getRegClass(Record*); + + /// getRegisterClassForRegister - Find the register class that contains the + /// specified physical register. If the register is not in a register + /// class, return null. If the register is in multiple classes, and the + /// classes have a superset-subset relationship and the same set of types, + /// return the superclass. Otherwise return null. + const CodeGenRegisterClass* getRegClassForRegister(Record *R); + // Computed derived records such as missing sub-register indices. void computeDerivedInfo(); diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index a0c64ff..9d0aadf 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -163,16 +163,6 @@ CodeGenRegBank &CodeGenTarget::getRegBank() const { return *RegBank; } -void CodeGenTarget::ReadRegisterClasses() const { - std::vector<Record*> RegClasses = - Records.getAllDerivedDefinitions("RegisterClass"); - if (RegClasses.empty()) - throw std::string("No 'RegisterClass' subclasses defined!"); - - RegisterClasses.reserve(RegClasses.size()); - RegisterClasses.assign(RegClasses.begin(), RegClasses.end()); -} - /// getRegisterByName - If there is a register with the specific AsmName, /// return it. const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const { @@ -191,7 +181,7 @@ getRegisterVTs(Record *R) const { std::vector<MVT::SimpleValueType> Result; const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses(); for (unsigned i = 0, e = RCs.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = RegisterClasses[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<MVT::SimpleValueType> &InVTs = RC.getValueTypes(); diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 1f1c34c..2516515 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -66,9 +66,7 @@ class CodeGenTarget { mutable DenseMap<const Record*, CodeGenInstruction*> Instructions; mutable CodeGenRegBank *RegBank; - mutable std::vector<CodeGenRegisterClass> RegisterClasses; mutable std::vector<MVT::SimpleValueType> LegalValueTypes; - void ReadRegisterClasses() const; void ReadInstructions() const; void ReadLegalValueTypes() const; @@ -107,71 +105,11 @@ public: const CodeGenRegister *getRegisterByName(StringRef Name) const; const std::vector<CodeGenRegisterClass> &getRegisterClasses() const { - if (RegisterClasses.empty()) ReadRegisterClasses(); - return RegisterClasses; + return getRegBank().getRegClasses(); } const CodeGenRegisterClass &getRegisterClass(Record *R) const { - const std::vector<CodeGenRegisterClass> &RC = getRegisterClasses(); - for (unsigned i = 0, e = RC.size(); i != e; ++i) - if (RC[i].TheDef == R) - return RC[i]; - assert(0 && "Didn't find the register class"); - abort(); - } - - /// getRegisterClassForRegister - Find the register class that contains the - /// specified physical register. If the register is not in a register - /// class, return null. If the register is in multiple classes, and the - /// classes have a superset-subset relationship and the same set of - /// types, return the superclass. Otherwise return null. - const CodeGenRegisterClass *getRegisterClassForRegister(Record *R) const { - const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses(); - const CodeGenRegisterClass *FoundRC = 0; - for (unsigned i = 0, e = RCs.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = RegisterClasses[i]; - for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) { - if (R != RC.Elements[ei]) - continue; - - // If a register's classes have different types, return null. - if (FoundRC && RC.getValueTypes() != FoundRC->getValueTypes()) - return 0; - - // If this is the first class that contains the register, - // make a note of it and go on to the next class. - if (!FoundRC) { - FoundRC = &RC; - break; - } - - std::vector<Record *> Elements(RC.Elements); - std::vector<Record *> 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())) { - FoundRC = &RC; - break; - } - - // 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())) - break; - - // Multiple classes, and neither is a superclass of the other. - // Return null. - return 0; - } - } - return FoundRC; + return *getRegBank().getRegClass(R); } /// getRegisterVTs - Find the union of all possible SimpleValueTypes for the diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index 78ac556..6c2a767 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -250,7 +250,7 @@ struct OperandsSignature { if (OpLeafRec->isSubClassOf("RegisterClass")) RC = &Target.getRegisterClass(OpLeafRec); else if (OpLeafRec->isSubClassOf("Register")) - RC = Target.getRegisterClassForRegister(OpLeafRec); + RC = Target.getRegBank().getRegClassForRegister(OpLeafRec); else return false; |