From: Jakob Stoklund Olesen Date: Sat, 7 May 2011 21:22:39 +0000 (+0000) Subject: Teach TableGen to automatically generate missing SubRegIndex instances. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=123cab9480812e51f6d4cb118fe685691130f625;p=oota-llvm.git Teach TableGen to automatically generate missing SubRegIndex instances. The RegisterInfo.td file should only specify the indexes that sources need to refer to. The rest is inferred. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131058 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 57f7fdc4dc4..0328c9ac917 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -98,14 +98,14 @@ std::string llvm::getEnumName(MVT::SimpleValueType T) { /// namespace qualifier if the record contains one. /// std::string llvm::getQualifiedName(const Record *R) { - std::string Namespace = R->getValueAsString("Namespace"); + std::string Namespace; + if (R->getValue("Namespace")) + Namespace = R->getValueAsString("Namespace"); if (Namespace.empty()) return R->getName(); return Namespace + "::" + R->getName(); } - - /// getTarget - Return the current instance of the Target class. /// CodeGenTarget::CodeGenTarget(RecordKeeper &records) : Records(records) { @@ -182,6 +182,13 @@ void CodeGenTarget::ReadSubRegIndices() const { std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord()); } +Record *CodeGenTarget::createSubRegIndex(const std::string &Name) { + Record *R = new Record(Name, SMLoc(), Records); + Records.addDef(R); + SubRegIndices.push_back(R); + return R; +} + void CodeGenTarget::ReadRegisterClasses() const { std::vector RegClasses = Records.getAllDerivedDefinitions("RegisterClass"); diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 4e041548f5f..891b2d524c7 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -121,6 +121,9 @@ public: return (i - SubRegIndices.begin()) + 1; } + // Create a new SubRegIndex with the given name. + Record *createSubRegIndex(const std::string &Name); + const std::vector &getRegisterClasses() const { if (RegisterClasses.empty()) ReadRegisterClasses(); return RegisterClasses; diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 4ddc47d5519..053d9262654 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -56,7 +56,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) { OS << "enum {\n NoSubRegister,\n"; for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) OS << " " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n"; - OS << " NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n"; + OS << " NUM_TARGET_NAMED_SUBREGS = " << SubRegIndices.size()+1 << "\n"; OS << "};\n"; if (!Namespace.empty()) OS << "}\n"; @@ -172,7 +172,7 @@ struct RegisterMaps { typedef std::map SubRegMaps; SubRegMaps SubReg; - SubRegMap &inferSubRegIndices(Record *Reg); + SubRegMap &inferSubRegIndices(Record *Reg, CodeGenTarget &); // Composite SubRegIndex instances. // Map (SubRegIndex,SubRegIndex) -> SubRegIndex @@ -185,7 +185,8 @@ struct RegisterMaps { }; // Calculate all subregindices for Reg. Loopy subregs cause infinite recursion. -RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) { +RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg, + CodeGenTarget &Target) { SubRegMap &SRM = SubReg[Reg]; if (!SRM.empty()) return SRM; @@ -199,7 +200,7 @@ RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) { if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second) throw "SubRegIndex " + Indices[i]->getName() + " appears twice in Register " + Reg->getName(); - inferSubRegIndices(SubRegs[i]); + inferSubRegIndices(SubRegs[i], Target); } // Keep track of inherited subregs and how they can be reached. @@ -248,18 +249,17 @@ RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) { Orphans.erase(R2); } - // Now, Orphans contains the inherited subregisters without a direct index. - if (!Orphans.empty()) { - errs() << "Error: Register " << getQualifiedName(Reg) - << " inherited subregisters without an index:\n"; - for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e; - ++i) { - errs() << " " << getQualifiedName(i->first) - << " = " << i->second.first->getName() - << ", " << i->second.second->getName() << "\n"; - } - abort(); + // Now Orphans contains the inherited subregisters without a direct index. + // Create inferred indexes for all missing entries. + for (OrphanMap::iterator I = Orphans.begin(), E = Orphans.end(); I != E; + ++I) { + Record *&Comp = Composite[I->second]; + if (!Comp) + Comp = Target.createSubRegIndex(I->second.first->getName() + "_then_" + + I->second.second->getName()); + SRM[Comp] = I->first; } + return SRM; } @@ -861,6 +861,13 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { } OS << " };\n"; // End of register descriptors... + // Calculate the mapping of subregister+index pairs to physical registers. + // This will also create further anonymous indexes. + unsigned NamedIndices = Target.getSubRegIndices().size(); + RegisterMaps RegMaps; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) + RegMaps.inferSubRegIndices(Regs[i].TheDef, Target); + // Emit SubRegIndex names, skipping 0 const std::vector SubRegIndices = Target.getSubRegIndices(); OS << "\n const char *const SubRegIndexTable[] = { \""; @@ -870,13 +877,21 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { OS << "\", \""; } OS << "\" };\n\n"; + + // Emit names of the anonymus subreg indexes. + if (SubRegIndices.size() > NamedIndices) { + OS << " enum {"; + for (unsigned i = NamedIndices, e = SubRegIndices.size(); i != e; ++i) { + OS << "\n " << SubRegIndices[i]->getName() << " = " << i+1; + if (i+1 != e) + OS << ','; + } + OS << "\n };\n\n"; + } OS << "}\n\n"; // End of anonymous namespace... std::string ClassName = Target.getName() + "GenRegisterInfo"; - // Calculate the mapping of subregister+index pairs to physical registers. - RegisterMaps RegMaps; - // Emit the subregister + index mapping function based on the information // calculated above. OS << "unsigned " << ClassName @@ -884,7 +899,7 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { << " switch (RegNo) {\n" << " default:\n return 0;\n"; for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - RegisterMaps::SubRegMap &SRM = RegMaps.inferSubRegIndices(Regs[i].TheDef); + RegisterMaps::SubRegMap &SRM = RegMaps.SubReg[Regs[i].TheDef]; if (SRM.empty()) continue; OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n";