aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/Target.td5
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h11
-rw-r--r--lib/CodeGen/MachineRegisterInfo.cpp2
-rw-r--r--lib/Target/TargetRegisterInfo.cpp3
-rw-r--r--utils/TableGen/CodeGenRegisters.h1
-rw-r--r--utils/TableGen/CodeGenTarget.cpp1
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp25
7 files changed, 32 insertions, 16 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 5ae4866f5e..ab6a4e2cdb 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -128,6 +128,11 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// dags: (RegClass SubRegIndex, SubRegindex, ...)
list<dag> SubRegClasses = [];
+ // isAllocatable - Specify that the register class can be used for virtual
+ // registers and register allocation. Some register classes are only used to
+ // model instruction operand constraints, and should have isAllocatable = 0.
+ bit isAllocatable = 1;
+
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
// code into a generated register class. The normal usage of this is to
// overload virtual methods.
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index eb2a0af798..f6a8414590 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -47,6 +47,7 @@ struct TargetRegisterDesc {
const unsigned *SubRegs; // Sub-register set, described above
const unsigned *SuperRegs; // Super-register set, described above
unsigned CostPerUse; // Extra cost of instructions using register.
+ bool inAllocatableClass; // Register belongs to an allocatable regclass.
};
class TargetRegisterClass {
@@ -66,6 +67,7 @@ private:
const sc_iterator SuperRegClasses;
const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
const int CopyCost;
+ const bool Allocatable;
const iterator RegsBegin, RegsEnd;
DenseSet<unsigned> RegSet;
public:
@@ -76,11 +78,12 @@ public:
const TargetRegisterClass * const *supcs,
const TargetRegisterClass * const *subregcs,
const TargetRegisterClass * const *superregcs,
- unsigned RS, unsigned Al, int CC,
+ unsigned RS, unsigned Al, int CC, bool Allocable,
iterator RB, iterator RE)
: ID(id), Name(name), VTs(vts), SubClasses(subcs), SuperClasses(supcs),
SubRegClasses(subregcs), SuperRegClasses(superregcs),
- RegSize(RS), Alignment(Al), CopyCost(CC), RegsBegin(RB), RegsEnd(RE) {
+ RegSize(RS), Alignment(Al), CopyCost(CC), Allocatable(Allocable),
+ RegsBegin(RB), RegsEnd(RE) {
for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I)
RegSet.insert(*I);
}
@@ -268,6 +271,10 @@ public:
/// this class. A negative number means the register class is very expensive
/// to copy e.g. status flag register classes.
int getCopyCost() const { return CopyCost; }
+
+ /// isAllocatable - Return true if this register class may be used to create
+ /// virtual registers.
+ bool isAllocatable() const { return Allocatable; }
};
diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp
index 7244d5f03a..08ff5bb715 100644
--- a/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/lib/CodeGen/MachineRegisterInfo.cpp
@@ -79,6 +79,8 @@ MachineRegisterInfo::constrainRegClass(unsigned Reg,
unsigned
MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){
assert(RegClass && "Cannot create register without RegClass!");
+ assert(RegClass->isAllocatable() &&
+ "Virtual register RegClass must be allocatable.");
// New virtual register number.
unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs());
diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp
index 4811ba5cc4..1c3f2dda33 100644
--- a/lib/Target/TargetRegisterInfo.cpp
+++ b/lib/Target/TargetRegisterInfo.cpp
@@ -96,7 +96,8 @@ BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF,
} else {
for (TargetRegisterInfo::regclass_iterator I = regclass_begin(),
E = regclass_end(); I != E; ++I)
- getAllocatableSetForRC(MF, *I, Allocatable);
+ if ((*I)->isAllocatable())
+ getAllocatableSetForRC(MF, *I, Allocatable);
}
// Mask out the reserved registers
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index 39b92c515a..8727340bd1 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -43,6 +43,7 @@ namespace llvm {
unsigned SpillSize;
unsigned SpillAlignment;
int CopyCost;
+ bool Allocatable;
// Map SubRegIndex -> RegisterClass
DenseMap<Record*,Record*> SubRegClasses;
std::string MethodProtos, MethodBodies;
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index b1c594449b..301ffdd01c 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -289,6 +289,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits();
SpillAlignment = R->getValueAsInt("Alignment");
CopyCost = R->getValueAsInt("CopyCost");
+ Allocatable = R->getValueAsBit("isAllocatable");
MethodBodies = R->getValueAsCode("MethodBodies");
MethodProtos = R->getValueAsCode("MethodProtos");
}
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 156c145540..d05474feae 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -342,24 +342,24 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
OS << "namespace llvm {\n\n";
- // Start out by emitting each of the register classes... to do this, we build
- // a set of registers which belong to a register class, this is to ensure that
- // each register is only in a single register class.
- //
+ // Start out by emitting each of the register classes.
const std::vector<CodeGenRegisterClass> &RegisterClasses =
Target.getRegisterClasses();
+ // Collect all registers belonging to any allocatable class.
+ std::set<Record*> AllocatableRegs;
+
// Loop over all of the register classes... emitting each one.
OS << "namespace { // Register classes...\n";
- // RegClassesBelongedTo - Keep track of which register classes each reg
- // belongs to.
- std::multimap<Record*, const CodeGenRegisterClass*> RegClassesBelongedTo;
-
// Emit the register enum value arrays for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = RegisterClasses[rc];
+ // Collect allocatable registers.
+ if (RC.Allocatable)
+ AllocatableRegs.insert(RC.Elements.begin(), RC.Elements.end());
+
// Give the register class a legal C name if it's anonymous.
std::string Name = RC.TheDef->getName();
@@ -370,9 +370,6 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
Record *Reg = RC.Elements[i];
OS << getQualifiedName(Reg) << ", ";
-
- // Keep track of which regclasses this register is in.
- RegClassesBelongedTo.insert(std::make_pair(Reg, &RC));
}
OS << "\n };\n\n";
}
@@ -568,6 +565,7 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
<< RC.SpillSize/8 << ", "
<< RC.SpillAlignment/8 << ", "
<< RC.CopyCost << ", "
+ << RC.Allocatable << ", "
<< RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size()
<< ") {}\n";
}
@@ -842,7 +840,7 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
}
OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
- OS << " { \"NOREG\",\t0,\t0,\t0,\t0 },\n";
+ OS << " { \"NOREG\",\t0,\t0,\t0,\t0,\t0 },\n";
// Now that register alias and sub-registers sets have been emitted, emit the
// register descriptors now.
@@ -858,7 +856,8 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
OS << Reg.getName() << "_SuperRegsSet,\t";
else
OS << "Empty_SuperRegsSet,\t";
- OS << Reg.CostPerUse << " },\n";
+ OS << Reg.CostPerUse << ",\t"
+ << int(AllocatableRegs.count(Reg.TheDef)) << " },\n";
}
OS << " };\n"; // End of register descriptors...