diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td --- a/llvm/include/llvm/Target/GlobalISel/Combine.td +++ b/llvm/include/llvm/Target/GlobalISel/Combine.td @@ -15,16 +15,19 @@ // See GICombineGroup. We only declare it here to make the tablegen pass // simpler. list Rules = ?; + list Excluded = ?; } // A group of combine rules that can be added to a GICombiner or another group. -class GICombineGroup rules> : GICombine { +class GICombineGroup rules, list excluded_rules = []> : GICombine { // The rules contained in this group. The rules in a group are flattened into // a single list and sorted into whatever order is most efficient. However, // they will never be re-ordered such that behaviour differs from the // specified order. It is therefore possible to use the order of rules in this // list to describe priorities. let Rules = rules; + // The excluded rules are deleted from the Rules list. + let Excluded = excluded_rules; } class GICombinerHelperArg { @@ -33,8 +36,8 @@ } // Declares a combiner helper class -class GICombinerHelper rules> - : GICombineGroup { +class GICombinerHelper rules, list excluded = []> + : GICombineGroup { // The class name to use in the generated output. string Classname = classname; // The name of a run-time compiler option that will be generated to disable diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td --- a/llvm/lib/Target/AArch64/AArch64Combine.td +++ b/llvm/lib/Target/AArch64/AArch64Combine.td @@ -19,7 +19,8 @@ def AArch64PreLegalizerCombinerHelper: GICombinerHelper< "AArch64GenPreLegalizerCombinerHelper", [all_combines, - fconstant_to_constant]> { + fconstant_to_constant], + []> { let DisableRuleOption = "aarch64prelegalizercombiner-disable-rule"; let StateClass = "AArch64PreLegalizerCombinerHelperState"; let AdditionalArguments = []; diff --git a/llvm/utils/TableGen/GICombinerEmitter.cpp b/llvm/utils/TableGen/GICombinerEmitter.cpp --- a/llvm/utils/TableGen/GICombinerEmitter.cpp +++ b/llvm/utils/TableGen/GICombinerEmitter.cpp @@ -26,6 +26,7 @@ #include "GlobalISel/GIMatchDag.h" #include "GlobalISel/GIMatchTree.h" #include +#include using namespace llvm; @@ -596,12 +597,16 @@ StringRef Name; const CodeGenTarget &Target; Record *Combiner; - std::vector> Rules; + using RuleList = std::vector>; + RuleList Rules; GIMatchDagContext MatchDagCtx; std::unique_ptr makeCombineRule(const Record &R); - void gatherRules(std::vector> &ActiveRules, + void gatherExcludedRules(std::unordered_set &ExcludedNames, + const std::vector &RulesAndGroups); + void gatherRules(RuleList &ActiveRules, + std::unordered_set &ExcludedNames, const std::vector &&RulesAndGroups); public: @@ -704,8 +709,27 @@ } /// Recurse into GICombineGroup's and flatten the ruleset into a simple list. -void GICombinerEmitter::gatherRules( - std::vector> &ActiveRules, +void GICombinerEmitter::gatherExcludedRules( + std::unordered_set &ExcludedRules, + const std::vector &RulesAndGroups) { + for (Record *R : RulesAndGroups) { + + if (R->isValueUnset("Excluded")) { + ExcludedRules.insert(std::string(R->getName())); + } else { + // Delete rules form the list in the excluded list. + auto Excluded = R->getValueAsListOfDefs("Excluded"); + gatherExcludedRules(ExcludedRules, Excluded); + } + } + for (std::string s : ExcludedRules) { + LLVM_DEBUG(dbgs() << "Excluding rule: " << s << "\n"); + } +} + +/// Recurse into GICombineGroup's and flatten the ruleset into a simple list. +void GICombinerEmitter::gatherRules(RuleList &ActiveRules, + std::unordered_set &ExcludedNames, const std::vector &&RulesAndGroups) { for (Record *R : RulesAndGroups) { if (R->isValueUnset("Rules")) { @@ -714,10 +738,13 @@ PrintError(R->getLoc(), "Failed to parse rule"); continue; } + if (ExcludedNames.count(std::string(R->getName()))) + continue; ActiveRules.emplace_back(std::move(Rule)); ++NumPatternTotal; - } else - gatherRules(ActiveRules, R->getValueAsListOfDefs("Rules")); + } else { + gatherRules(ActiveRules, ExcludedNames, R->getValueAsListOfDefs("Rules")); + } } } @@ -849,8 +876,12 @@ << Arg->getValueAsString("Name"); } -void GICombinerEmitter::run(raw_ostream &OS) { - gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules")); +void GICombinerEmitter::run(raw_ostream & OS) { + std::unordered_set ExcludedRules; + gatherExcludedRules(ExcludedRules, + Combiner->getValueAsListOfDefs("Excluded")); + gatherRules(Rules, ExcludedRules, Combiner->getValueAsListOfDefs("Rules")); + if (StopAfterParse) { MatchDagCtx.print(errs()); PrintNote(Combiner->getLoc(),