From 60f09928a0d22d5927ff0a40fe9163cf1ba1014a Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Fri, 21 Jul 2006 20:57:35 +0000 Subject: [PATCH] Use an enumeration to eliminate data relocations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29249 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/MRegisterInfo.h | 18 ++++++++++-- include/llvm/Target/TargetInstrInfo.h | 19 +++--------- lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 29 +++++++++++++++---- .../SelectionDAG/ScheduleDAGRRList.cpp | 2 +- utils/TableGen/InstrInfoEmitter.cpp | 2 +- utils/TableGen/RegisterInfoEmitter.cpp | 12 +++++++- 6 files changed, 55 insertions(+), 27 deletions(-) diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h index 1ca560eab14..7b28d5eeb63 100644 --- a/include/llvm/Target/MRegisterInfo.h +++ b/include/llvm/Target/MRegisterInfo.h @@ -49,6 +49,7 @@ public: typedef const MVT::ValueType* vt_iterator; typedef const TargetRegisterClass* const * sc_iterator; private: + unsigned ID; bool isSubClass; const vt_iterator VTs; const sc_iterator SubClasses; @@ -56,14 +57,18 @@ private: const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: - TargetRegisterClass(const MVT::ValueType *vts, + TargetRegisterClass(unsigned id, + const MVT::ValueType *vts, const TargetRegisterClass * const *subcs, const TargetRegisterClass * const *supcs, unsigned RS, unsigned Al, iterator RB, iterator RE) - : VTs(vts), SubClasses(subcs), SuperClasses(supcs), + : ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} virtual ~TargetRegisterClass() {} // Allow subclasses - + + // getID() - Return the register class ID number. + unsigned getID() const { return ID; } + // begin/end - Return all of the registers in this class. iterator begin() const { return RegsBegin; } iterator end() const { return RegsEnd; } @@ -300,6 +305,13 @@ public: unsigned getNumRegClasses() const { return regclass_end()-regclass_begin(); } + + /// getRegClass - Returns the register class associated with the enumeration + /// value. See class TargetOperandInfo. + const TargetRegisterClass *getRegClass(unsigned i) const { + assert(i <= getNumRegClasses() && "Register Class ID out of range"); + return i ? RegClassBegin[i - 1] : NULL; + } //===--------------------------------------------------------------------===// // Interfaces used by the register allocator and stack frame diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index ae271d2f6cd..905384eaa77 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -90,10 +90,10 @@ const unsigned M_LOOK_UP_PTR_REG_CLASS = 1 << 0; /// class TargetOperandInfo { public: - /// RegClass - This specifies the register class of the operand if the - /// operand is a register. If not, this contains null. - const TargetRegisterClass *RegClass; - unsigned Flags; + /// RegClass - This specifies the register class enumeration of the operand + /// if the operand is a register. If not, this contains 0. + unsigned short RegClass; + unsigned short Flags; /// Currently no other information. }; @@ -146,17 +146,6 @@ public: return get(Opcode).Name; } - const TargetRegisterClass - *getInstrOperandRegClass(const TargetInstrDescriptor *II, unsigned Op) const { - if (Op >= II->numOperands) { - assert((II->Flags & M_VARIABLE_OPS)&& "Invalid operand # of instruction"); - return NULL; - } - const TargetOperandInfo &toi = II->OpInfo[Op]; - return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS) - ? getPointerRegClass() : toi.RegClass; - } - int getNumOperands(MachineOpCode Opcode) const { return get(Opcode).numOperands; } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 186b041b586..97eccb2b959 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -226,7 +226,22 @@ static unsigned CountOperands(SDNode *Node) { return N; } -static unsigned CreateVirtualRegisters(MachineInstr *MI, +static const TargetRegisterClass *getInstrOperandRegClass( + const MRegisterInfo *MRI, + const TargetInstrInfo *TII, + const TargetInstrDescriptor *II, + unsigned Op) { + if (Op >= II->numOperands) { + assert((II->Flags & M_VARIABLE_OPS)&& "Invalid operand # of instruction"); + return NULL; + } + const TargetOperandInfo &toi = II->OpInfo[Op]; + return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS) + ? TII->getPointerRegClass() : MRI->getRegClass(toi.RegClass); +} + +static unsigned CreateVirtualRegisters(const MRegisterInfo *MRI, + MachineInstr *MI, unsigned NumResults, SSARegMap *RegMap, const TargetInstrInfo *TII, @@ -234,10 +249,10 @@ static unsigned CreateVirtualRegisters(MachineInstr *MI, // Create the result registers for this node and add the result regs to // the machine instruction. unsigned ResultReg = - RegMap->createVirtualRegister(TII->getInstrOperandRegClass(&II, 0)); + RegMap->createVirtualRegister(getInstrOperandRegClass(MRI, TII, &II, 0)); MI->addRegOperand(ResultReg, MachineOperand::Def); for (unsigned i = 1; i != NumResults; ++i) { - const TargetRegisterClass *RC = TII->getInstrOperandRegClass(&II, i); + const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, &II, i); assert(RC && "Isn't a register operand!"); MI->addRegOperand(RegMap->createVirtualRegister(RC), MachineOperand::Def); } @@ -276,7 +291,8 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, // Verify that it is right. assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); if (II) { - const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum); + const TargetRegisterClass *RC = + getInstrOperandRegClass(MRI, TII, II, IIOpNum); assert(RC && "Don't have operand info for this instruction!"); assert(RegMap->getRegClass(VReg) == RC && "Register class of operand and regclass of use don't agree!"); @@ -333,7 +349,8 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, // Verify that it is right. assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); if (II) { - const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum); + const TargetRegisterClass *RC = + getInstrOperandRegClass(MRI, TII, II, IIOpNum); assert(RC && "Don't have operand info for this instruction!"); assert(RegMap->getRegClass(VReg) == RC && "Register class of operand and regclass of use don't agree!"); @@ -389,7 +406,7 @@ void ScheduleDAG::EmitNode(SDNode *Node, // Otherwise, create new virtual registers. if (NumResults && VRBase == 0) - VRBase = CreateVirtualRegisters(MI, NumResults, RegMap, TII, II); + VRBase = CreateVirtualRegisters(MRI, MI, NumResults, RegMap, TII, II); // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index b6c2d352b35..3718e64d9ce 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -152,7 +152,7 @@ static const TargetRegisterClass *getRegClass(SUnit *SU, if (SU->Node->isTargetOpcode()) { unsigned Opc = SU->Node->getTargetOpcode(); const TargetInstrDescriptor &II = TII->get(Opc); - return II.OpInfo->RegClass; + return MRI->getRegClass(II.OpInfo->RegClass); } else { assert(SU->Node->getOpcode() == ISD::CopyFromReg); unsigned SrcReg = cast(SU->Node->getOperand(1))->getReg(); diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index f91babcf860..de93792556f 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -137,7 +137,7 @@ void InstrInfoEmitter::run(std::ostream &OS) { Record *RC = OperandInfo[i]; // FIXME: We only care about register operands for now. if (RC && RC->isSubClassOf("RegisterClass")) - OS << "{ &" << getQualifiedName(RC) << "RegClass, 0 }, "; + OS << "{ " << getQualifiedName(RC) << "RegClassID, 0 }, "; else if (RC && RC->getName() == "ptr_rc") // Ptr value whose register class is resolved via callback. OS << "{ 0, 1 }, "; diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index e572544075d..11107f212b9 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -68,6 +68,15 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) { if (!RegisterClasses.empty()) { OS << "namespace " << RegisterClasses[0].Namespace << " { // Register classes\n"; + + OS << " enum {\n"; + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { + if (i) OS << ",\n"; + OS << " " << RegisterClasses[i].getName() << "RegClassID"; + if (!i) OS << " = 1"; + } + OS << "\n };\n\n"; + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { const std::string &Name = RegisterClasses[i].getName(); @@ -165,7 +174,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) OS << " " << RegisterClasses[i].getName() << "Class\t" << RegisterClasses[i].getName() << "RegClass;\n"; - + std::map > SuperClassMap; OS << "\n"; // Emit the sub-classes array for each RegisterClass @@ -244,6 +253,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { OS << RC.MethodBodies << "\n"; OS << RC.getName() << "Class::" << RC.getName() << "Class() : TargetRegisterClass(" + << RC.getName() + "RegClassID" << ", " << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", "