mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-02 08:46:23 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
70f2f65aac
commit
8a17870da4
@ -19,6 +19,7 @@
|
||||
|
||||
#include "CodeGenRegisters.h"
|
||||
#include "CodeGenInstruction.h"
|
||||
#include <algorithm>
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
|
||||
@ -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<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]) {
|
||||
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<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;
|
||||
|
Loading…
Reference in New Issue
Block a user