mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-20 18:56:04 +00:00
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. llvm-svn: 131058
This commit is contained in:
parent
f608aeaefa
commit
3bc1816380
@ -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<Record*> RegClasses =
|
||||
Records.getAllDerivedDefinitions("RegisterClass");
|
||||
|
@ -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<CodeGenRegisterClass> &getRegisterClasses() const {
|
||||
if (RegisterClasses.empty()) ReadRegisterClasses();
|
||||
return RegisterClasses;
|
||||
|
@ -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<Record*, SubRegMap> 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<Record*> 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";
|
||||
|
Loading…
x
Reference in New Issue
Block a user