summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/utils/TableGen/CodeGenSchedule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/utils/TableGen/CodeGenSchedule.cpp')
-rw-r--r--gnu/llvm/utils/TableGen/CodeGenSchedule.cpp101
1 files changed, 93 insertions, 8 deletions
diff --git a/gnu/llvm/utils/TableGen/CodeGenSchedule.cpp b/gnu/llvm/utils/TableGen/CodeGenSchedule.cpp
index c98f6234534..d1b141e3160 100644
--- a/gnu/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/gnu/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -68,7 +68,7 @@ struct InstRegexOp : public SetTheory::Operator {
}
RegexList.push_back(Regex(pat));
}
- for (const CodeGenInstruction *Inst : Target.instructions()) {
+ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
for (auto &R : RegexList) {
if (R.match(Inst->TheDef->getName()))
Elts.insert(Inst->TheDef);
@@ -120,12 +120,18 @@ CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
// (For per-operand resources mapped to itinerary classes).
collectProcItinRW();
+ // Find UnsupportedFeatures records for each processor.
+ // (For per-operand resources mapped to itinerary classes).
+ collectProcUnsupportedFeatures();
+
// Infer new SchedClasses from SchedVariant.
inferSchedClasses();
// Populate each CodeGenProcModel's WriteResDefs, ReadAdvanceDefs, and
// ProcResourceDefs.
collectProcResources();
+
+ checkCompleteness();
}
/// Gather all processor models.
@@ -204,7 +210,7 @@ void CodeGenSchedModels::collectSchedRW() {
// Find all SchedReadWrites referenced by instruction defs.
RecVec SWDefs, SRDefs;
- for (const CodeGenInstruction *Inst : Target.instructions()) {
+ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
Record *SchedDef = Inst->TheDef;
if (SchedDef->isValueUnset("SchedRW"))
continue;
@@ -498,7 +504,7 @@ void CodeGenSchedModels::collectSchedClasses() {
// Create a SchedClass for each unique combination of itinerary class and
// SchedRW list.
- for (const CodeGenInstruction *Inst : Target.instructions()) {
+ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
Record *ItinDef = Inst->TheDef->getValueAsDef("Itinerary");
IdxVec Writes, Reads;
if (!Inst->TheDef->isValueUnset("SchedRW"))
@@ -523,11 +529,12 @@ void CodeGenSchedModels::collectSchedClasses() {
if (!EnableDump)
return;
- for (const CodeGenInstruction *Inst : Target.instructions()) {
+ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
std::string InstName = Inst->TheDef->getName();
unsigned SCIdx = InstrClassMap.lookup(Inst->TheDef);
if (!SCIdx) {
- dbgs() << "No machine model for " << Inst->TheDef->getName() << '\n';
+ if (!Inst->hasNoSchedulingInfo)
+ dbgs() << "No machine model for " << Inst->TheDef->getName() << '\n';
continue;
}
CodeGenSchedClass &SC = getSchedClass(SCIdx);
@@ -826,6 +833,15 @@ void CodeGenSchedModels::collectProcItinRW() {
}
}
+// Gather the unsupported features for processor models.
+void CodeGenSchedModels::collectProcUnsupportedFeatures() {
+ for (CodeGenProcModel &ProcModel : ProcModels) {
+ for (Record *Pred : ProcModel.ModelDef->getValueAsListOfDefs("UnsupportedFeatures")) {
+ ProcModel.UnsupportedFeaturesDefs.push_back(Pred);
+ }
+ }
+}
+
/// Infer new classes from existing classes. In the process, this may create new
/// SchedWrites from sequences of existing SchedWrites.
void CodeGenSchedModels::inferSchedClasses() {
@@ -1426,6 +1442,9 @@ void CodeGenSchedModels::verifyProcResourceGroups(CodeGenProcModel &PM) {
// Collect and sort WriteRes, ReadAdvance, and ProcResources.
void CodeGenSchedModels::collectProcResources() {
+ ProcResourceDefs = Records.getAllDerivedDefinitions("ProcResourceUnits");
+ ProcResGroups = Records.getAllDerivedDefinitions("ProcResGroup");
+
// Add any subtarget-specific SchedReadWrites that are directly associated
// with processor resources. Refer to the parent SchedClass's ProcIndices to
// determine which processors they apply to.
@@ -1520,6 +1539,63 @@ void CodeGenSchedModels::collectProcResources() {
dbgs() << '\n');
verifyProcResourceGroups(PM);
}
+
+ ProcResourceDefs.clear();
+ ProcResGroups.clear();
+}
+
+void CodeGenSchedModels::checkCompleteness() {
+ bool Complete = true;
+ bool HadCompleteModel = false;
+ for (const CodeGenProcModel &ProcModel : procModels()) {
+ if (!ProcModel.ModelDef->getValueAsBit("CompleteModel"))
+ continue;
+ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
+ if (Inst->hasNoSchedulingInfo)
+ continue;
+ if (ProcModel.isUnsupported(*Inst))
+ continue;
+ unsigned SCIdx = getSchedClassIdx(*Inst);
+ if (!SCIdx) {
+ if (Inst->TheDef->isValueUnset("SchedRW") && !HadCompleteModel) {
+ PrintError("No schedule information for instruction '"
+ + Inst->TheDef->getName() + "'");
+ Complete = false;
+ }
+ continue;
+ }
+
+ const CodeGenSchedClass &SC = getSchedClass(SCIdx);
+ if (!SC.Writes.empty())
+ continue;
+ if (SC.ItinClassDef != nullptr)
+ continue;
+
+ const RecVec &InstRWs = SC.InstRWs;
+ auto I = std::find_if(InstRWs.begin(), InstRWs.end(),
+ [&ProcModel] (const Record *R) {
+ return R->getValueAsDef("SchedModel") ==
+ ProcModel.ModelDef;
+ });
+ if (I == InstRWs.end()) {
+ PrintError("'" + ProcModel.ModelName + "' lacks information for '" +
+ Inst->TheDef->getName() + "'");
+ Complete = false;
+ }
+ }
+ HadCompleteModel = true;
+ }
+ if (!Complete) {
+ errs() << "\n\nIncomplete schedule models found.\n"
+ << "- Consider setting 'CompleteModel = 0' while developing new models.\n"
+ << "- Pseudo instructions can be marked with 'hasNoSchedulingInfo = 1'.\n"
+ << "- Instructions should usually have Sched<[...]> as a superclass, "
+ "you may temporarily use an empty list.\n"
+ << "- Instructions related to unsupported features can be excluded with "
+ "list<Predicate> UnsupportedFeatures = [HasA,..,HasY]; in the "
+ "processor model.\n\n";
+ PrintFatalError("Incomplete schedule model");
+ }
}
// Collect itinerary class resources for each processor.
@@ -1600,8 +1676,8 @@ Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
return ProcResKind;
Record *ProcUnitDef = nullptr;
- RecVec ProcResourceDefs =
- Records.getAllDerivedDefinitions("ProcResourceUnits");
+ assert(!ProcResourceDefs.empty());
+ assert(!ProcResGroups.empty());
for (RecIter RI = ProcResourceDefs.begin(), RE = ProcResourceDefs.end();
RI != RE; ++RI) {
@@ -1616,7 +1692,6 @@ Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
ProcUnitDef = *RI;
}
}
- RecVec ProcResGroups = Records.getAllDerivedDefinitions("ProcResGroup");
for (RecIter RI = ProcResGroups.begin(), RE = ProcResGroups.end();
RI != RE; ++RI) {
@@ -1699,6 +1774,16 @@ unsigned CodeGenProcModel::getProcResourceIdx(Record *PRDef) const {
return 1 + (PRPos - ProcResourceDefs.begin());
}
+bool CodeGenProcModel::isUnsupported(const CodeGenInstruction &Inst) const {
+ for (const Record *TheDef : UnsupportedFeaturesDefs) {
+ for (const Record *PredDef : Inst.TheDef->getValueAsListOfDefs("Predicates")) {
+ if (TheDef->getName() == PredDef->getName())
+ return true;
+ }
+ }
+ return false;
+}
+
#ifndef NDEBUG
void CodeGenProcModel::dump() const {
dbgs() << Index << ": " << ModelName << " "