From: Benjamin Kramer Date: Fri, 22 Jul 2011 00:44:39 +0000 (+0000) Subject: Teach tblgen to emit MCRegisterClasses. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=8ca9a862038e8c4e9a2ca73b3b75e1be3425155f;p=oota-llvm.git Teach tblgen to emit MCRegisterClasses. - This currently introduces more instances of the static DenseSet dtor, but that should be fixable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135735 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 7593c07493a..7ed84f214d0 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -40,10 +40,15 @@ public: unsigned RS, unsigned Al, int CC, bool Allocable, iterator RB, iterator RE) : ID(id), Name(name), RegSize(RS), Alignment(Al), CopyCost(CC), - Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE) { - for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I) - RegSet.insert(*I); - } + Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE) {} + + /// initMCRegisterClass - Initialize initMCRegisterClass. *DO NOT USE*. + // FIXME: This could go away if RegSet would use a constant bit field. + void initMCRegisterClass() { + RegSet.resize(getNumRegs()); + for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I) + RegSet.insert(*I); + } /// getID() - Return the register class ID number. /// @@ -128,10 +133,14 @@ struct MCRegisterDesc { /// virtual methods. /// class MCRegisterInfo { +public: + typedef const MCRegisterClass *regclass_iterator; private: const MCRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array unsigned RAReg; // Return address register + const MCRegisterClass *Classes; // Pointer to the regclass array + unsigned NumClasses; // Number of entries in the array DenseMap L2DwarfRegs; // LLVM to Dwarf regs mapping DenseMap EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH DenseMap Dwarf2LRegs; // Dwarf to LLVM regs mapping @@ -141,10 +150,16 @@ private: public: /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. - void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA) { + void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, + MCRegisterClass *C, unsigned NC) { Desc = D; NumRegs = NR; RAReg = RA; + Classes = C; + NumClasses = NC; + // FIXME: This should go away. + for (unsigned i = 0; i != NC; ++i) + C[i].initMCRegisterClass(); } /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf @@ -273,6 +288,20 @@ public: if (I == L2SEHRegs.end()) return (int)RegNum; return I->second; } + + regclass_iterator regclass_begin() const { return Classes; } + regclass_iterator regclass_end() const { return Classes+NumClasses; } + + unsigned getNumRegClasses() const { + return (unsigned)(regclass_end()-regclass_begin()); + } + + /// getRegClass - Returns the register class associated with the enumeration + /// value. See class MCOperandInfo. + const MCRegisterClass getRegClass(unsigned i) const { + assert(i < getNumRegClasses() && "Register Class ID out of range"); + return Classes[i]; + } }; } // End llvm namespace diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 03eb79c4294..cdc35908066 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -52,7 +52,9 @@ public: iterator RB, iterator RE) : MCRegisterClass(id, name, RS, Al, CC, Allocable, RB, RE), VTs(vts), SubClasses(subcs), SuperClasses(supcs), SubRegClasses(subregcs), - SuperRegClasses(superregcs) {} + SuperRegClasses(superregcs) { + initMCRegisterClass(); + } virtual ~TargetRegisterClass() {} // Allow subclasses diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index e107f5611f7..270b01779c8 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -297,12 +297,62 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, } OS << "};\n\n"; // End of register descriptors... + // FIXME: This code is duplicated in the TargetRegisterClass emitter. + const std::vector &RegisterClasses = + Target.getRegisterClasses(); + + // Loop over all of the register classes... emitting each one. + OS << "namespace { // Register classes...\n"; + + // Emit the register enum value arrays for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + ArrayRef Order = RC.getOrder(); + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.getName(); + + // Emit the register list now. + OS << " // " << Name << " Register Class...\n" + << " static const unsigned " << Name + << "[] = {\n "; + for (unsigned i = 0, e = Order.size(); i != e; ++i) { + Record *Reg = Order[i]; + OS << getQualifiedName(Reg) << ", "; + } + OS << "\n };\n\n"; + } + OS << "}\n\n"; + + OS << "MCRegisterClass " << TargetName << "MCRegisterClasses[] = {\n"; + + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + ArrayRef Order = RC.getOrder(); + + std::string Name = RC.getName(); + + OS << " MCRegisterClass(" + << rc << ", " + << '\"' << RC.getName() << "\", " + << RC.SpillSize/8 << ", " + << RC.SpillAlignment/8 << ", " + << RC.CopyCost << ", " + << RC.Allocatable << ", " + << RC.getName() << ", " << RC.getName() << " + " + << RC.getOrder().size() + << "),\n"; + } + + OS << "};\n\n"; + // MCRegisterInfo initialization routine. OS << "static inline void Init" << TargetName << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"; OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " - << Regs.size()+1 << ", RA);\n\n"; + << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " + << RegisterClasses.size() << ");\n\n"; EmitRegMapping(OS, Regs, false); @@ -773,6 +823,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the constructor of the class... OS << "extern MCRegisterDesc " << TargetName << "RegDesc[];\n"; + OS << "extern MCRegisterClass " << TargetName << "MCRegisterClasses[];\n"; OS << ClassName << "::" << ClassName << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n" @@ -780,7 +831,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" << " " << TargetName << "SubRegIndexTable) {\n" << " InitMCRegisterInfo(" << TargetName << "RegDesc, " - << Regs.size()+1 << ", RA);\n\n"; + << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " + << RegisterClasses.size() << ");\n\n"; EmitRegMapping(OS, Regs, true); diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h index ba88a6b7070..4ad9cfa97f2 100644 --- a/utils/TableGen/RegisterInfoEmitter.h +++ b/utils/TableGen/RegisterInfoEmitter.h @@ -50,6 +50,7 @@ public: private: void EmitRegMapping(raw_ostream &o, const std::vector &Regs, bool isCtor); + void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target); }; } // End llvm namespace