SchedMachineModel: compress the CPU's WriteLatencyTable.

llvm-svn: 164199
This commit is contained in:
Andrew Trick 2012-09-19 04:43:19 +00:00
parent c7bcaf8512
commit cfe222c2a9
3 changed files with 44 additions and 7 deletions

View File

@ -270,6 +270,21 @@ unsigned CodeGenSchedModels::getSchedRWIdx(Record *Def, bool IsRead,
return 0; return 0;
} }
bool CodeGenSchedModels::hasReadOfWrite(Record *WriteDef) const {
for (unsigned i = 0, e = SchedReads.size(); i < e; ++i) {
Record *ReadDef = SchedReads[i].TheDef;
if (!ReadDef || !ReadDef->isSubClassOf("ProcReadAdvance"))
continue;
RecVec ValidWrites = ReadDef->getValueAsListOfDefs("ValidWrites");
if (std::find(ValidWrites.begin(), ValidWrites.end(), WriteDef)
!= ValidWrites.end()) {
return true;
}
}
return false;
}
namespace llvm { namespace llvm {
void splitSchedReadWrites(const RecVec &RWDefs, void splitSchedReadWrites(const RecVec &RWDefs,
RecVec &WriteDefs, RecVec &ReadDefs) { RecVec &WriteDefs, RecVec &ReadDefs) {

View File

@ -284,6 +284,9 @@ public:
unsigned getSchedRWIdx(Record *Def, bool IsRead, unsigned After = 0) const; unsigned getSchedRWIdx(Record *Def, bool IsRead, unsigned After = 0) const;
// Return true if the given write record is referenced by a ReadAdvance.
bool hasReadOfWrite(Record *WriteDef) const;
// Check if any instructions are assigned to an explicit itinerary class other // Check if any instructions are assigned to an explicit itinerary class other
// than NoItinerary. // than NoItinerary.
bool hasItineraryClasses() const { return NumItineraryClasses > 0; } bool hasItineraryClasses() const { return NumItineraryClasses > 0; }

View File

@ -36,6 +36,7 @@ class SubtargetEmitter {
std::vector<std::vector<MCSchedClassDesc> > ProcSchedClasses; std::vector<std::vector<MCSchedClassDesc> > ProcSchedClasses;
std::vector<MCWriteProcResEntry> WriteProcResources; std::vector<MCWriteProcResEntry> WriteProcResources;
std::vector<MCWriteLatencyEntry> WriteLatencies; std::vector<MCWriteLatencyEntry> WriteLatencies;
std::vector<std::string> WriterNames;
std::vector<MCReadAdvanceEntry> ReadAdvanceEntries; std::vector<MCReadAdvanceEntry> ReadAdvanceEntries;
// Reserve an invalid entry at index 0 // Reserve an invalid entry at index 0
@ -43,6 +44,7 @@ class SubtargetEmitter {
ProcSchedClasses.resize(1); ProcSchedClasses.resize(1);
WriteProcResources.resize(1); WriteProcResources.resize(1);
WriteLatencies.resize(1); WriteLatencies.resize(1);
WriterNames.push_back("InvalidWrite");
ReadAdvanceEntries.resize(1); ReadAdvanceEntries.resize(1);
} }
}; };
@ -774,6 +776,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
// Sum resources across all operand writes. // Sum resources across all operand writes.
std::vector<MCWriteProcResEntry> WriteProcResources; std::vector<MCWriteProcResEntry> WriteProcResources;
std::vector<MCWriteLatencyEntry> WriteLatencies; std::vector<MCWriteLatencyEntry> WriteLatencies;
std::vector<std::string> WriterNames;
std::vector<MCReadAdvanceEntry> ReadAdvanceEntries; std::vector<MCReadAdvanceEntry> ReadAdvanceEntries;
for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) { for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) {
IdxVec WriteSeq; IdxVec WriteSeq;
@ -782,7 +785,14 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
// For each operand, create a latency entry. // For each operand, create a latency entry.
MCWriteLatencyEntry WLEntry; MCWriteLatencyEntry WLEntry;
WLEntry.Cycles = 0; WLEntry.Cycles = 0;
WLEntry.WriteResourceID = WriteSeq.back(); unsigned WriteID = WriteSeq.back();
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)) {
WriteID = 0;
}
WLEntry.WriteResourceID = WriteID;
for (IdxIter WSI = WriteSeq.begin(), WSE = WriteSeq.end(); for (IdxIter WSI = WriteSeq.begin(), WSE = WriteSeq.end();
WSI != WSE; ++WSI) { WSI != WSE; ++WSI) {
@ -881,12 +891,22 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
std::search(SchedTables.WriteLatencies.begin(), std::search(SchedTables.WriteLatencies.begin(),
SchedTables.WriteLatencies.end(), SchedTables.WriteLatencies.end(),
WriteLatencies.begin(), WriteLatencies.end()); WriteLatencies.begin(), WriteLatencies.end());
if (WLPos != SchedTables.WriteLatencies.end()) if (WLPos != SchedTables.WriteLatencies.end()) {
SCDesc.WriteLatencyIdx = WLPos - SchedTables.WriteLatencies.begin(); unsigned idx = WLPos - SchedTables.WriteLatencies.begin();
SCDesc.WriteLatencyIdx = idx;
for (unsigned i = 0, e = WriteLatencies.size(); i < e; ++i)
if (SchedTables.WriterNames[idx + i].find(WriterNames[i]) ==
std::string::npos) {
SchedTables.WriterNames[idx + i] += std::string("_") + WriterNames[i];
}
}
else { else {
SCDesc.WriteLatencyIdx = SchedTables.WriteLatencies.size(); SCDesc.WriteLatencyIdx = SchedTables.WriteLatencies.size();
SchedTables.WriteLatencies.insert(WLPos, WriteLatencies.begin(), SchedTables.WriteLatencies.insert(SchedTables.WriteLatencies.end(),
WriteLatencies.end()); WriteLatencies.begin(),
WriteLatencies.end());
SchedTables.WriterNames.insert(SchedTables.WriterNames.end(),
WriterNames.begin(), WriterNames.end());
} }
// ReadAdvanceEntries must remain in operand order. // ReadAdvanceEntries must remain in operand order.
SCDesc.NumReadAdvanceEntries = ReadAdvanceEntries.size(); SCDesc.NumReadAdvanceEntries = ReadAdvanceEntries.size();
@ -935,8 +955,7 @@ void SubtargetEmitter::EmitSchedClassTables(SchedClassTables &SchedTables,
<< format("%2d", WLEntry.WriteResourceID) << "}"; << format("%2d", WLEntry.WriteResourceID) << "}";
if (WLIdx + 1 < WLEnd) if (WLIdx + 1 < WLEnd)
OS << ','; OS << ',';
OS << " // #" << WLIdx << " " OS << " // #" << WLIdx << " " << SchedTables.WriterNames[WLIdx] << '\n';
<< SchedModels.getSchedWrite(WLEntry.WriteResourceID).Name << '\n';
} }
OS << "}; // " << Target << "WriteLatencyTable\n"; OS << "}; // " << Target << "WriteLatencyTable\n";