diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 5ae4866f5e6..ab6a4e2cdb1 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -128,6 +128,11 @@ class RegisterClass regTypes, int alignment, // dags: (RegClass SubRegIndex, SubRegindex, ...) list 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 eb2a0af798f..f6a84145907 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 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 7244d5f03a9..08ff5bb7152 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 4811ba5cc48..1c3f2dda33c 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 39b92c515ad..8727340bd1e 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 SubRegClasses; std::string MethodProtos, MethodBodies; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index b1c594449b6..301ffdd01c4 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 156c1455407..d05474feaea 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 &RegisterClasses = Target.getRegisterClasses(); + // Collect all registers belonging to any allocatable class. + std::set 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 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...