Machine model. Allow mixed itinerary classes and SchedRW lists.

We always supported a mixture of the old itinerary model and new
per-operand model, but it required a level of indirection to map
itinerary classes to SchedRW lists. This was done for ARM A9.

Now we want to define x86 SchedRW lists, with the goal of removing its
itinerary classes, but still support the itineraries in the mean
time. When I original developed the model, Atom did not have
itineraries, so there was no reason to expect this requirement.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177226 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick
2013-03-16 18:58:55 +00:00
parent 229aa6d23b
commit 1ab961f6d3
3 changed files with 175 additions and 206 deletions
+35 -43
View File
@@ -447,17 +447,15 @@ EmitStageAndOperandCycleData(raw_ostream &OS,
// If this processor defines no itineraries, then leave the itinerary list
// empty.
std::vector<InstrItinerary> &ItinList = ProcItinLists.back();
if (ProcModel.ItinDefList.empty())
if (!ProcModel.hasItineraries())
continue;
// Reserve index==0 for NoItinerary.
ItinList.resize(SchedModels.numItineraryClasses()+1);
const std::string &Name = ProcModel.ItinsDef->getName();
// For each itinerary data
for (unsigned SchedClassIdx = 0,
SchedClassEnd = ProcModel.ItinDefList.size();
ItinList.resize(SchedModels.numInstrSchedClasses());
assert(ProcModel.ItinDefList.size() == ItinList.size() && "bad Itins");
for (unsigned SchedClassIdx = 0, SchedClassEnd = ItinList.size();
SchedClassIdx < SchedClassEnd; ++SchedClassIdx) {
// Next itinerary data
@@ -869,27 +867,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
}
IdxVec Writes = SCI->Writes;
IdxVec Reads = SCI->Reads;
if (SCI->ItinClassDef) {
assert(SCI->InstRWs.empty() && "ItinClass should not have InstRWs");
// Check this processor's itinerary class resources.
for (RecIter II = ProcModel.ItinRWDefs.begin(),
IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) {
RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef)
!= Matched.end()) {
SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"),
Writes, Reads);
break;
}
}
if (Writes.empty()) {
DEBUG(dbgs() << ProcModel.ModelName
<< " does not have resources for itinerary class "
<< SCI->ItinClassDef->getName() << '\n');
}
}
else if (!SCI->InstRWs.empty()) {
// This class may have a default ReadWrite list which can be overriden by
if (!SCI->InstRWs.empty()) {
// This class has a default ReadWrite list which can be overriden by
// InstRW definitions.
Record *RWDef = 0;
for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end();
@@ -907,6 +886,23 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
Writes, Reads);
}
}
if (Writes.empty()) {
// Check this processor's itinerary class resources.
for (RecIter II = ProcModel.ItinRWDefs.begin(),
IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) {
RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef)
!= Matched.end()) {
SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"),
Writes, Reads);
break;
}
}
if (Writes.empty()) {
DEBUG(dbgs() << ProcModel.ModelName
<< " does not have resources for class " << SCI->Name << '\n');
}
}
// Sum resources across all operand writes.
std::vector<MCWriteProcResEntry> WriteProcResources;
std::vector<MCWriteLatencyEntry> WriteLatencies;
@@ -924,7 +920,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
WriterNames.push_back(SchedModels.getSchedWrite(WriteID).Name);
// If this Write is not referenced by a ReadAdvance, don't distinguish it
// from other WriteLatency entries.
if (!SchedModels.hasReadOfWrite(SchedModels.getSchedWrite(WriteID).TheDef)) {
if (!SchedModels.hasReadOfWrite(
SchedModels.getSchedWrite(WriteID).TheDef)) {
WriteID = 0;
}
WLEntry.WriteResourceID = WriteID;
@@ -1140,7 +1137,7 @@ void SubtargetEmitter::EmitSchedClassTables(SchedClassTables &SchedTables,
// The first class is always invalid. We no way to distinguish it except by
// name and position.
assert(SchedModels.getSchedClass(0).Name == "NoItinerary"
assert(SchedModels.getSchedClass(0).Name == "NoInstrModel"
&& "invalid class not first");
OS << " {DBGFIELD(\"InvalidSchedClass\") "
<< MCSchedClassDesc::InvalidNumMicroOps
@@ -1197,7 +1194,7 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
- SchedModels.schedClassBegin()) << ",\n";
else
OS << " 0, 0, 0, 0, // No instruction-level machine model.\n";
if (SchedModels.hasItineraryClasses())
if (SchedModels.hasItineraries())
OS << " " << PI->ItinsDef->getName() << ");\n";
else
OS << " 0); // No Itinerary\n";
@@ -1254,7 +1251,7 @@ void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) {
<< "#define DBGFIELD(x)\n"
<< "#endif\n";
if (SchedModels.hasItineraryClasses()) {
if (SchedModels.hasItineraries()) {
std::vector<std::vector<InstrItinerary> > ProcItinLists;
// Emit the stage data
EmitStageAndOperandCycleData(OS, ProcItinLists);
@@ -1295,7 +1292,7 @@ void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName,
SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) {
if (SCI->Transitions.empty())
continue;
VariantClasses.push_back(SCI - SchedModels.schedClassBegin());
VariantClasses.push_back(SCI->Index);
}
if (!VariantClasses.empty()) {
OS << " switch (SchedClass) {\n";
@@ -1342,13 +1339,8 @@ void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName,
if (*PI == 0)
break;
}
unsigned SCIdx = 0;
if (SC.ItinClassDef)
SCIdx = SchedModels.getSchedClassIdxForItin(SC.ItinClassDef);
else
SCIdx = SchedModels.findSchedClassIdx(SC.Writes, SC.Reads);
if (SCIdx != *VCI)
OS << " return " << SCIdx << ";\n";
if (SC.isInferred())
OS << " return " << SC.Index << ";\n";
OS << " break;\n";
}
OS << " };\n";
@@ -1454,7 +1446,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
<< Target << "WriteProcResTable, "
<< Target << "WriteLatencyTable, "
<< Target << "ReadAdvanceTable, ";
if (SchedModels.hasItineraryClasses()) {
if (SchedModels.hasItineraries()) {
OS << '\n'; OS.indent(22);
OS << Target << "Stages, "
<< Target << "OperandCycles, "
@@ -1511,7 +1503,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << "extern const llvm::MCReadAdvanceEntry "
<< Target << "ReadAdvanceTable[];\n";
if (SchedModels.hasItineraryClasses()) {
if (SchedModels.hasItineraries()) {
OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
OS << "extern const unsigned " << Target << "OperandCycles[];\n";
OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
@@ -1535,7 +1527,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
<< Target << "WriteLatencyTable, "
<< Target << "ReadAdvanceTable, ";
OS << '\n'; OS.indent(22);
if (SchedModels.hasItineraryClasses()) {
if (SchedModels.hasItineraries()) {
OS << Target << "Stages, "
<< Target << "OperandCycles, "
<< Target << "ForwardingPaths, ";