[llvm] r339421 - [Tablegen][SubtargetEmitter] refactor method `emitSchedModelHelpersImpl()`. NFCI
Andrea Di Biagio via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 10 03:43:43 PDT 2018
Author: adibiagio
Date: Fri Aug 10 03:43:43 2018
New Revision: 339421
URL: http://llvm.org/viewvc/llvm-project?rev=339421&view=rev
Log:
[Tablegen][SubtargetEmitter] refactor method `emitSchedModelHelpersImpl()`. NFCI
Part of the logic has been moved to helper functions to (hopefully) improve
readability.
Added a few code comments to better describe how the algorithm works.
No functional change intended.
Modified:
llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=339421&r1=339420&r2=339421&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Fri Aug 10 03:43:43 2018
@@ -1509,85 +1509,119 @@ static void emitPredicates(const CodeGen
OS << Buffer;
}
-void SubtargetEmitter::emitSchedModelHelpersImpl(
- raw_ostream &OS, bool OnlyExpandMCInstPredicates) {
- // Collect Variant Classes.
- IdxVec VariantClasses;
+// Used by method `SubtargetEmitter::emitSchedModelHelpersImpl()` to generate
+// epilogue code for the auto-generated helper.
+void emitSchedModelHelperEpilogue(raw_ostream &OS, bool ShouldReturnZero) {
+ if (ShouldReturnZero) {
+ OS << " // Don't know how to resolve this scheduling class.\n"
+ << " return 0;\n";
+ return;
+ }
+
+ OS << " report_fatal_error(\"Expected a variant SchedClass\");\n";
+}
+
+bool hasMCSchedPredicates(const CodeGenSchedTransition &T) {
+ return all_of(T.PredTerm, [](const Record *Rec) {
+ return Rec->isSubClassOf("MCSchedPredicate");
+ });
+}
+
+void collectVariantClasses(const CodeGenSchedModels &SchedModels,
+ IdxVec &VariantClasses,
+ bool OnlyExpandMCInstPredicates) {
for (const CodeGenSchedClass &SC : SchedModels.schedClasses()) {
+ // Ignore non-variant scheduling classes.
if (SC.Transitions.empty())
continue;
+
+ if (OnlyExpandMCInstPredicates) {
+ // Ignore this variant scheduling class if transitions don't uses any
+ // MCSchedPredicate definitions.
+ if (!all_of(SC.Transitions, [](const CodeGenSchedTransition &T) {
+ return hasMCSchedPredicates(T);
+ }))
+ continue;
+ }
+
VariantClasses.push_back(SC.Index);
}
+}
- if (!VariantClasses.empty()) {
- bool FoundPredicates = false;
- for (unsigned VC : VariantClasses) {
- // Emit code for each variant scheduling class.
- const CodeGenSchedClass &SC = SchedModels.getSchedClass(VC);
- IdxVec ProcIndices;
- for (const CodeGenSchedTransition &T : SC.Transitions) {
- if (OnlyExpandMCInstPredicates &&
- !all_of(T.PredTerm, [](const Record *Rec) {
- return Rec->isSubClassOf("MCSchedPredicate");
- }))
- continue;
+void collectProcessorIndices(const CodeGenSchedClass &SC, IdxVec &ProcIndices) {
+ // A variant scheduling class may define transitions for multiple
+ // processors. This function identifies wich processors are associated with
+ // transition rules specified by variant class `SC`.
+ for (const CodeGenSchedTransition &T : SC.Transitions) {
+ IdxVec PI;
+ std::set_union(T.ProcIndices.begin(), T.ProcIndices.end(),
+ ProcIndices.begin(), ProcIndices.end(),
+ std::back_inserter(PI));
+ ProcIndices.swap(PI);
+ }
+}
- IdxVec PI;
- std::set_union(T.ProcIndices.begin(), T.ProcIndices.end(),
- ProcIndices.begin(), ProcIndices.end(),
- std::back_inserter(PI));
- ProcIndices.swap(PI);
- }
- if (ProcIndices.empty())
- continue;
+void SubtargetEmitter::emitSchedModelHelpersImpl(
+ raw_ostream &OS, bool OnlyExpandMCInstPredicates) {
+ IdxVec VariantClasses;
+ collectVariantClasses(SchedModels, VariantClasses,
+ OnlyExpandMCInstPredicates);
- // Emit a switch statement only if there are predicates to expand.
- if (!FoundPredicates) {
- OS << " switch (SchedClass) {\n";
- FoundPredicates = true;
- }
+ if (VariantClasses.empty()) {
+ emitSchedModelHelperEpilogue(OS, OnlyExpandMCInstPredicates);
+ return;
+ }
- OS << " case " << VC << ": // " << SC.Name << '\n';
- PredicateExpander PE;
- PE.setByRef(false);
- PE.setExpandForMC(OnlyExpandMCInstPredicates);
- for (unsigned PI : ProcIndices) {
- OS << " ";
- if (PI != 0) {
- OS << (OnlyExpandMCInstPredicates
- ? "if (CPUID == "
- : "if (SchedModel->getProcessorID() == ");
- OS << PI << ") ";
- }
+ // Construct a switch statement where the condition is a check on the
+ // scheduling class identifier. There is a `case` for every variant class
+ // defined by the processor models of this target.
+ // Each `case` implements a number of rules to resolve (i.e. to transition from)
+ // a variant scheduling class to another scheduling class. Rules are
+ // described by instances of CodeGenSchedTransition. Note that transitions may
+ // not be valid for all processors.
+ OS << " switch (SchedClass) {\n";
+ for (unsigned VC : VariantClasses) {
+ IdxVec ProcIndices;
+ const CodeGenSchedClass &SC = SchedModels.getSchedClass(VC);
+ collectProcessorIndices(SC, ProcIndices);
+
+ OS << " case " << VC << ": // " << SC.Name << '\n';
+
+ PredicateExpander PE;
+ PE.setByRef(false);
+ PE.setExpandForMC(OnlyExpandMCInstPredicates);
+ for (unsigned PI : ProcIndices) {
+ OS << " ";
+ // Emit a guard on the processor ID.
+ if (PI != 0) {
+ OS << (OnlyExpandMCInstPredicates
+ ? "if (CPUID == "
+ : "if (SchedModel->getProcessorID() == ");
+ OS << PI << ") ";
OS << "{ // " << (SchedModels.procModelBegin() + PI)->ModelName << '\n';
+ }
- for (const CodeGenSchedTransition &T : SC.Transitions) {
- if (PI != 0 && !count(T.ProcIndices, PI))
- continue;
- PE.setIndentLevel(4);
- emitPredicates(T, SchedModels.getSchedClass(T.ToClassIdx), PE, OS);
- }
-
- OS << " }\n";
- if (PI == 0)
- break;
+ // Now emit transitions associated with processor PI.
+ for (const CodeGenSchedTransition &T : SC.Transitions) {
+ if (PI != 0 && !count(T.ProcIndices, PI))
+ continue;
+ PE.setIndentLevel(4);
+ emitPredicates(T, SchedModels.getSchedClass(T.ToClassIdx), PE, OS);
}
- if (SC.isInferred())
- OS << " return " << SC.Index << ";\n";
- OS << " break;\n";
+
+ OS << " }\n";
+ if (PI == 0)
+ break;
}
- if (FoundPredicates)
- OS << " };\n";
+ if (SC.isInferred())
+ OS << " return " << SC.Index << ";\n";
+ OS << " break;\n";
}
- if (OnlyExpandMCInstPredicates) {
- OS << " // Don't know how to resolve this scheduling class.\n"
- << " return 0;\n";
- return;
- }
+ OS << " };\n";
- OS << " report_fatal_error(\"Expected a variant SchedClass\");\n";
+ emitSchedModelHelperEpilogue(OS, OnlyExpandMCInstPredicates);
}
void SubtargetEmitter::EmitSchedModelHelpers(const std::string &ClassName,
More information about the llvm-commits
mailing list