diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-copy-prop-disabled.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-copy-prop-disabled.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-copy-prop-disabled.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-copy-prop-disabled.mir @@ -3,6 +3,14 @@ # RUN: | FileCheck --check-prefix=ENABLED %s # RUN: llc -run-pass=aarch64-prelegalizer-combiner -global-isel -verify-machineinstrs %s -o - \ # RUN: --aarch64prelegalizercombinerhelper-disable-rule=copy_prop | FileCheck --check-prefix=DISABLED %s +# RUN: llc -run-pass=aarch64-prelegalizer-combiner -global-isel -verify-machineinstrs %s -o - \ +# RUN: --aarch64prelegalizercombinerhelper-disable-rule="*" | FileCheck --check-prefix=DISABLED %s +# RUN: llc -run-pass=aarch64-prelegalizer-combiner -global-isel -verify-machineinstrs %s -o - \ +# RUN: --aarch64prelegalizercombinerhelper-disable-rule="*,!copy_prop" \ +# RUN: | FileCheck --check-prefix=ENABLED %s +# RUN: llc -run-pass=aarch64-prelegalizer-combiner -global-isel -verify-machineinstrs %s -o - \ +# RUN: --aarch64prelegalizercombinerhelper-only-enable-rule="copy_prop" \ +# RUN: | FileCheck --check-prefix=ENABLED %s # REQUIRES: asserts 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 @@ -904,6 +904,7 @@ << "public:\n" << " bool parseCommandLineOption();\n" << " bool isRuleDisabled(unsigned ID) const;\n" + << " bool setRuleEnabled(StringRef RuleIdentifier);\n" << " bool setRuleDisabled(StringRef RuleIdentifier);\n" << "\n" << "};\n" @@ -932,30 +933,43 @@ emitNameMatcher(OS); - OS << "bool " << getClassName() - << "RuleConfig::setRuleDisabled(StringRef RuleIdentifier) {\n" + OS << "static Optional> " + "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n" << " std::pair RangePair = " "RuleIdentifier.split('-');\n" << " if (!RangePair.second.empty()) {\n" - << " const auto First = getRuleIdxForIdentifier(RangePair.first);\n" - << " const auto Last = getRuleIdxForIdentifier(RangePair.second);\n" + << " const auto First = " + "getRuleIdxForIdentifier(RangePair.first);\n" + << " const auto Last = " + "getRuleIdxForIdentifier(RangePair.second);\n" << " if (!First.hasValue() || !Last.hasValue())\n" - << " return false;\n" + << " return None;\n" << " if (First >= Last)\n" - << " report_fatal_error(\"Beginning of range should be before end of " - "range\");\n" - << " for (auto I = First.getValue(); I < Last.getValue(); ++I)\n" - << " DisabledRules.set(I);\n" - << " return true;\n" + << " report_fatal_error(\"Beginning of range should be before " + "end of range\");\n" + << " return {{ *First, *Last + 1 }};\n" + << " } else if (RangePair.first == \"*\") {\n" + << " return {{ 0, " << Rules.size() << " }};\n" << " } else {\n" << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n" << " if (!I.hasValue())\n" - << " return false;\n" - << " DisabledRules.set(I.getValue());\n" - << " return true;\n" + << " return None;\n" + << " return {{*I, *I + 1}};\n" << " }\n" - << " return false;\n" - << "}\n"; + << " return None;\n" + << "}\n\n"; + + for (bool Enabled : {true, false}) { + OS << "bool " << getClassName() << "RuleConfig::setRule" + << (Enabled ? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n" + << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n" + << " if(!MaybeRange.hasValue())\n" + << " return false;\n" + << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n" + << " DisabledRules." << (Enabled ? "reset" : "set") << "(I);\n" + << " return true;\n" + << "}\n\n"; + } OS << "bool " << getClassName() << "RuleConfig::isRuleDisabled(unsigned RuleID) const {\n" @@ -965,18 +979,41 @@ OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n" << "\n" - << "cl::list " << Name << "Option(\n" + << "std::vector " << Name << "Option;\n" + << "cl::list " << Name << "DisableOption(\n" << " \"" << Name.lower() << "-disable-rule\",\n" << " cl::desc(\"Disable one or more combiner rules temporarily in " << "the " << Name << " pass\"),\n" << " cl::CommaSeparated,\n" << " cl::Hidden,\n" - << " cl::cat(GICombinerOptionCategory));\n" + << " cl::cat(GICombinerOptionCategory),\n" + << " cl::callback([](const std::string &Str) {\n" + << " " << Name << "Option.push_back(Str);\n" + << " }));\n" + << "cl::list " << Name << "OnlyEnableOption(\n" + << " \"" << Name.lower() << "-only-enable-rule\",\n" + << " cl::desc(\"Disable all rules in the " << Name + << " pass then re-enable the specified ones\"),\n" + << " cl::Hidden,\n" + << " cl::cat(GICombinerOptionCategory),\n" + << " cl::callback([](const std::string &CommaSeparatedArg) {\n" + << " StringRef Str = CommaSeparatedArg;\n" + << " " << Name << "Option.push_back(\"*\");\n" + << " do {\n" + << " auto X = Str.split(\",\");\n" + << " " << Name << "Option.push_back((\"!\" + X.first).str());\n" + << " Str = X.second;\n" + << " } while (!Str.empty());\n" + << " }));\n" << "\n" << "bool " << getClassName() << "RuleConfig::parseCommandLineOption() {\n" - << " for (const auto &Identifier : " << Name << "Option)\n" - << " if (!setRuleDisabled(Identifier))\n" + << " for (StringRef Identifier : " << Name << "Option) {\n" + << " bool Enabled = Identifier.consume_front(\"!\");\n" + << " if (Enabled && !setRuleEnabled(Identifier))\n" << " return false;\n" + << " if (!Enabled && !setRuleDisabled(Identifier))\n" + << " return false;\n" + << " }\n" << " return true;\n" << "}\n\n";