Machine Model (-schedmodel only). Added SchedAliases.
Allow subtargets to tie SchedReadWrite types to processor specific
sequences or variants.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164451 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
index e7dc983..4127b37 100644
--- a/utils/TableGen/SubtargetEmitter.cpp
+++ b/utils/TableGen/SubtargetEmitter.cpp
@@ -81,9 +81,10 @@
char Separator);
void EmitProcessorResources(const CodeGenProcModel &ProcModel,
raw_ostream &OS);
- Record *FindWriteResources(Record *WriteDef,
+ Record *FindWriteResources(const CodeGenSchedRW &SchedWrite,
const CodeGenProcModel &ProcModel);
- Record *FindReadAdvance(Record *ReadDef, const CodeGenProcModel &ProcModel);
+ Record *FindReadAdvance(const CodeGenSchedRW &SchedRead,
+ const CodeGenProcModel &ProcModel);
void GenSchedClassTables(const CodeGenProcModel &ProcModel,
SchedClassTables &SchedTables);
void EmitSchedClassTables(SchedClassTables &SchedTables, raw_ostream &OS);
@@ -654,48 +655,107 @@
// Find the WriteRes Record that defines processor resources for this
// SchedWrite.
Record *SubtargetEmitter::FindWriteResources(
- Record *WriteDef, const CodeGenProcModel &ProcModel) {
+ const CodeGenSchedRW &SchedWrite, const CodeGenProcModel &ProcModel) {
// Check if the SchedWrite is already subtarget-specific and directly
// specifies a set of processor resources.
- if (WriteDef->isSubClassOf("SchedWriteRes"))
- return WriteDef;
+ if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes"))
+ return SchedWrite.TheDef;
+
+ // Check this processor's list of aliases for SchedWrite.
+ Record *AliasDef = 0;
+ for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end();
+ AI != AE; ++AI) {
+ const CodeGenSchedRW &AliasRW =
+ SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
+ Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
+ if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
+ continue;
+ if (AliasDef)
+ throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases "
+ "defined for processor " + ProcModel.ModelName +
+ " Ensure only one SchedAlias exists per RW.");
+ AliasDef = AliasRW.TheDef;
+ }
+ if (AliasDef && AliasDef->isSubClassOf("SchedWriteRes"))
+ return AliasDef;
// Check this processor's list of write resources.
+ Record *ResDef = 0;
for (RecIter WRI = ProcModel.WriteResDefs.begin(),
WRE = ProcModel.WriteResDefs.end(); WRI != WRE; ++WRI) {
if (!(*WRI)->isSubClassOf("WriteRes"))
continue;
- if (WriteDef == (*WRI)->getValueAsDef("WriteType"))
- return *WRI;
+ if (AliasDef == (*WRI)->getValueAsDef("WriteType")
+ || SchedWrite.TheDef == (*WRI)->getValueAsDef("WriteType")) {
+ if (ResDef) {
+ throw TGError((*WRI)->getLoc(), "Resources are defined for both "
+ "SchedWrite and its alias on processor " +
+ ProcModel.ModelName);
+ }
+ ResDef = *WRI;
+ }
}
- throw TGError(ProcModel.ModelDef->getLoc(),
- std::string("Processor does not define resources for ")
- + WriteDef->getName());
+ // TODO: If ProcModel has a base model (previous generation processor),
+ // then call FindWriteResources recursively with that model here.
+ if (!ResDef) {
+ throw TGError(ProcModel.ModelDef->getLoc(),
+ std::string("Processor does not define resources for ")
+ + SchedWrite.TheDef->getName());
+ }
+ return ResDef;
}
/// Find the ReadAdvance record for the given SchedRead on this processor or
/// return NULL.
-Record *SubtargetEmitter::FindReadAdvance(Record *ReadDef,
+Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
const CodeGenProcModel &ProcModel) {
// Check for SchedReads that directly specify a ReadAdvance.
- if (ReadDef->isSubClassOf("SchedReadAdvance"))
- return ReadDef;
+ if (SchedRead.TheDef->isSubClassOf("SchedReadAdvance"))
+ return SchedRead.TheDef;
+
+ // Check this processor's list of aliases for SchedRead.
+ Record *AliasDef = 0;
+ for (RecIter AI = SchedRead.Aliases.begin(), AE = SchedRead.Aliases.end();
+ AI != AE; ++AI) {
+ const CodeGenSchedRW &AliasRW =
+ SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
+ Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
+ if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
+ continue;
+ if (AliasDef)
+ throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases "
+ "defined for processor " + ProcModel.ModelName +
+ " Ensure only one SchedAlias exists per RW.");
+ AliasDef = AliasRW.TheDef;
+ }
+ if (AliasDef && AliasDef->isSubClassOf("SchedReadAdvance"))
+ return AliasDef;
// Check this processor's ReadAdvanceList.
+ Record *ResDef = 0;
for (RecIter RAI = ProcModel.ReadAdvanceDefs.begin(),
RAE = ProcModel.ReadAdvanceDefs.end(); RAI != RAE; ++RAI) {
if (!(*RAI)->isSubClassOf("ReadAdvance"))
continue;
- if (ReadDef == (*RAI)->getValueAsDef("ReadType"))
- return *RAI;
+ if (AliasDef == (*RAI)->getValueAsDef("ReadType")
+ || SchedRead.TheDef == (*RAI)->getValueAsDef("ReadType")) {
+ if (ResDef) {
+ throw TGError((*RAI)->getLoc(), "Resources are defined for both "
+ "SchedRead and its alias on processor " +
+ ProcModel.ModelName);
+ }
+ ResDef = *RAI;
+ }
}
- if (ReadDef->getName() != "ReadDefault") {
+ // TODO: If ProcModel has a base model (previous generation processor),
+ // then call FindReadAdvance recursively with that model here.
+ if (!ResDef && SchedRead.TheDef->getName() != "ReadDefault") {
throw TGError(ProcModel.ModelDef->getLoc(),
std::string("Processor does not define resources for ")
- + ReadDef->getName());
+ + SchedRead.TheDef->getName());
}
- return NULL;
+ return ResDef;
}
// Generate the SchedClass table for this processor and update global
@@ -797,8 +857,8 @@
for (IdxIter WSI = WriteSeq.begin(), WSE = WriteSeq.end();
WSI != WSE; ++WSI) {
- Record *WriteDef = SchedModels.getSchedWrite(*WSI).TheDef;
- Record *WriteRes = FindWriteResources(WriteDef, ProcModel);
+ Record *WriteRes =
+ FindWriteResources(SchedModels.getSchedWrite(*WSI), ProcModel);
// Mark the parent class as invalid for unsupported write types.
if (WriteRes->getValueAsBit("Unsupported")) {
@@ -832,8 +892,8 @@
// Entries must be sorted first by UseIdx then by WriteResourceID.
for (unsigned UseIdx = 0, EndIdx = Reads.size();
UseIdx != EndIdx; ++UseIdx) {
- Record *ReadDef = SchedModels.getSchedRead(Reads[UseIdx]).TheDef;
- Record *ReadAdvance = FindReadAdvance(ReadDef, ProcModel);
+ Record *ReadAdvance =
+ FindReadAdvance(SchedModels.getSchedRead(Reads[UseIdx]), ProcModel);
if (!ReadAdvance)
continue;