From e14b8d985353ff07d504fac4014031ab9adca86a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Apr 2009 15:24:11 +0000 Subject: [PATCH] Generalize getRegisterClassForRegister to handle registers in multiple classes in the case that the classes are all in subset/superset relations. This function is used by the fast-isel emitter, which always wants the super-most set. llvm-svn: 68957 --- llvm/utils/TableGen/CodeGenTarget.h | 44 ++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/llvm/utils/TableGen/CodeGenTarget.h b/llvm/utils/TableGen/CodeGenTarget.h index ef46b6c61851..c7cc77ccd41a 100644 --- a/llvm/utils/TableGen/CodeGenTarget.h +++ b/llvm/utils/TableGen/CodeGenTarget.h @@ -19,6 +19,7 @@ #include "CodeGenRegisters.h" #include "CodeGenInstruction.h" +#include #include #include @@ -110,19 +111,54 @@ public: } /// getRegisterClassForRegister - Find the register class that contains the - /// specified physical register. If there register exists in multiple - /// register classes or is not in a register class, return null. + /// 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 &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]) { - if (FoundRC) return 0; // In multiple RC's + 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 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())) { + 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;