diff options
| author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-08-10 10:43:43 +0000 |
|---|---|---|
| committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-08-10 10:43:43 +0000 |
| commit | 8bdfd52ba76887db0ddb57d474700940b14ae36d (patch) | |
| tree | 95cbf5ffe42243ed169c393ca7851020e87a7e50 /llvm/utils/TableGen/SubtargetEmitter.cpp | |
| parent | a912e3e6be26e1c37219be994710e7f5a2b348b3 (diff) | |
| download | bcm5719-llvm-8bdfd52ba76887db0ddb57d474700940b14ae36d.tar.gz bcm5719-llvm-8bdfd52ba76887db0ddb57d474700940b14ae36d.zip | |
[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.
llvm-svn: 339421
Diffstat (limited to 'llvm/utils/TableGen/SubtargetEmitter.cpp')
| -rw-r--r-- | llvm/utils/TableGen/SubtargetEmitter.cpp | 158 |
1 files changed, 96 insertions, 62 deletions
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index c5da8d8142f..8a32e712d6c 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -1509,85 +1509,119 @@ static void emitPredicates(const CodeGenSchedTransition &T, 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, |

