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 @@ -40,6 +40,9 @@ // The name of a run-time compiler option that will be generated to disable // specific rules within this combiner. string DisableRuleOption = ?; + // The state class to inherit from (if any). The generated helper will inherit + // from this class and will forward arguments to its constructors. + string StateClass = ""; // Any additional arguments that should be appended to the tryCombine*(). list AdditionalArguments = [GICombinerHelperArg<"CombinerHelper &", "Helper">]; 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 @@ -22,6 +22,8 @@ elide_br_by_inverting_cond, fconstant_to_constant]> { let DisableRuleOption = "aarch64prelegalizercombiner-disable-rule"; + let StateClass = "AArch64PreLegalizerCombinerHelperState"; + let AdditionalArguments = []; } // Matchdata for combines which replace a G_SHUFFLE_VECTOR with a diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp @@ -295,7 +295,7 @@ MachineDominatorTree *MDT; public: - AArch64GenPostLegalizerCombinerHelper Generated; + AArch64GenPostLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; AArch64PostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, GISelKnownBits *KB, @@ -303,7 +303,7 @@ : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize), KB(KB), MDT(MDT) { - if (!Generated.parseCommandLineOption()) + if (!GeneratedRuleCfg.parseCommandLineOption()) report_fatal_error("Invalid rule identifier"); } @@ -317,6 +317,7 @@ const auto *LI = MI.getParent()->getParent()->getSubtarget().getLegalizerInfo(); CombinerHelper Helper(Observer, B, KB, MDT, LI); + AArch64GenPostLegalizerCombinerHelper Generated(GeneratedRuleCfg); return Generated.tryCombineAll(Observer, MI, B, Helper); } diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp @@ -53,6 +53,15 @@ MI.eraseFromParent(); } +class AArch64PreLegalizerCombinerHelperState { +protected: + CombinerHelper &Helper; + +public: + AArch64PreLegalizerCombinerHelperState(CombinerHelper &Helper) + : Helper(Helper) {} +}; + #define AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS #include "AArch64GenPreLegalizeGICombiner.inc" #undef AARCH64PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS @@ -65,16 +74,15 @@ class AArch64PreLegalizerCombinerInfo : public CombinerInfo { GISelKnownBits *KB; MachineDominatorTree *MDT; + AArch64GenPreLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; public: - AArch64GenPreLegalizerCombinerHelper Generated; - AArch64PreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, GISelKnownBits *KB, MachineDominatorTree *MDT) : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize), KB(KB), MDT(MDT) { - if (!Generated.parseCommandLineOption()) + if (!GeneratedRuleCfg.parseCommandLineOption()) report_fatal_error("Invalid rule identifier"); } @@ -86,6 +94,7 @@ MachineInstr &MI, MachineIRBuilder &B) const { CombinerHelper Helper(Observer, B, KB, MDT); + AArch64GenPreLegalizerCombinerHelper Generated(GeneratedRuleCfg, Helper); switch (MI.getOpcode()) { case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS: @@ -105,7 +114,7 @@ } } - if (Generated.tryCombineAll(Observer, MI, B, Helper)) + if (Generated.tryCombineAll(Observer, MI, B)) return true; switch (MI.getOpcode()) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPostLegalizerCombiner.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPostLegalizerCombiner.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUPostLegalizerCombiner.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPostLegalizerCombiner.cpp @@ -233,7 +233,7 @@ MachineDominatorTree *MDT; public: - AMDGPUGenPostLegalizerCombinerHelper Generated; + AMDGPUGenPostLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; AMDGPUPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, const AMDGPULegalizerInfo *LI, @@ -241,7 +241,7 @@ : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), KB(KB), MDT(MDT) { - if (!Generated.parseCommandLineOption()) + if (!GeneratedRuleCfg.parseCommandLineOption()) report_fatal_error("Invalid rule identifier"); } @@ -253,6 +253,7 @@ MachineInstr &MI, MachineIRBuilder &B) const { CombinerHelper Helper(Observer, B, KB, MDT); + AMDGPUGenPostLegalizerCombinerHelper Generated(GeneratedRuleCfg); if (Generated.tryCombineAll(Observer, MI, B, Helper)) return true; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPreLegalizerCombiner.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPreLegalizerCombiner.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUPreLegalizerCombiner.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPreLegalizerCombiner.cpp @@ -42,14 +42,14 @@ MachineDominatorTree *MDT; public: - AMDGPUGenPreLegalizerCombinerHelper Generated; + AMDGPUGenPreLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; AMDGPUPreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, GISelKnownBits *KB, MachineDominatorTree *MDT) : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize), KB(KB), MDT(MDT) { - if (!Generated.parseCommandLineOption()) + if (!GeneratedRuleCfg.parseCommandLineOption()) report_fatal_error("Invalid rule identifier"); } @@ -61,6 +61,7 @@ MachineInstr &MI, MachineIRBuilder &B) const { CombinerHelper Helper(Observer, B, KB, MDT); + AMDGPUGenPreLegalizerCombinerHelper Generated(GeneratedRuleCfg); if (Generated.tryCombineAll(Observer, MI, B, Helper)) return true; diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp @@ -44,7 +44,7 @@ MachineDominatorTree *MDT; public: - AMDGPUGenRegBankCombinerHelper Generated; + AMDGPUGenRegBankCombinerHelperRuleConfig GeneratedRuleCfg; AMDGPURegBankCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, const AMDGPULegalizerInfo *LI, @@ -52,7 +52,7 @@ : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), KB(KB), MDT(MDT) { - if (!Generated.parseCommandLineOption()) + if (!GeneratedRuleCfg.parseCommandLineOption()) report_fatal_error("Invalid rule identifier"); } @@ -64,6 +64,7 @@ MachineInstr &MI, MachineIRBuilder &B) const { CombinerHelper Helper(Observer, B, KB, MDT); + AMDGPUGenRegBankCombinerHelper Generated(GeneratedRuleCfg); if (Generated.tryCombineAll(Observer, MI, B, Helper)) return true; 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 @@ -743,7 +743,8 @@ const Record &RuleDef = Rule->getDef(); OS << Indent << "// Rule: " << RuleDef.getName() << "\n" - << Indent << "if (!isRuleDisabled(" << Rule->getID() << ")) {\n"; + << Indent << "if (!RuleConfig->isRuleDisabled(" << Rule->getID() + << ")) {\n"; CodeExpansions Expansions; for (const auto &VarBinding : Leaf.var_bindings()) { @@ -897,13 +898,29 @@ << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n\n"; OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n" - << "class " << getClassName() << " {\n" + << "class " << getClassName() << "RuleConfig {\n" << " SparseBitVector<> DisabledRules;\n" << "\n" << "public:\n" << " bool parseCommandLineOption();\n" << " bool isRuleDisabled(unsigned ID) const;\n" << " bool setRuleDisabled(StringRef RuleIdentifier);\n" + << "\n" + << "};\n" + << "\n" + << "class " << getClassName(); + StringRef StateClass = Combiner->getValueAsString("StateClass"); + if (!StateClass.empty()) + OS << " : public " << StateClass; + OS << " {\n" + << " const " << getClassName() << "RuleConfig *RuleConfig;\n" + << "\n" + << "public:\n" + << " template" << getClassName() << "(const " + << getClassName() << "RuleConfig &RuleConfig, Args &&... args) : "; + if (!StateClass.empty()) + OS << StateClass << "(std::forward(args)...), "; + OS << "RuleConfig(&RuleConfig) {}\n" << "\n" << " bool tryCombineAll(\n" << " GISelChangeObserver &Observer,\n" @@ -916,7 +933,7 @@ emitNameMatcher(OS); OS << "bool " << getClassName() - << "::setRuleDisabled(StringRef RuleIdentifier) {\n" + << "RuleConfig::setRuleDisabled(StringRef RuleIdentifier) {\n" << " std::pair RangePair = " "RuleIdentifier.split('-');\n" << " if (!RangePair.second.empty()) {\n" @@ -941,7 +958,7 @@ << "}\n"; OS << "bool " << getClassName() - << "::isRuleDisabled(unsigned RuleID) const {\n" + << "RuleConfig::isRuleDisabled(unsigned RuleID) const {\n" << " return DisabledRules.test(RuleID);\n" << "}\n"; OS << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n\n"; @@ -956,7 +973,7 @@ << " cl::Hidden,\n" << " cl::cat(GICombinerOptionCategory));\n" << "\n" - << "bool " << getClassName() << "::parseCommandLineOption() {\n" + << "bool " << getClassName() << "RuleConfig::parseCommandLineOption() {\n" << " for (const auto &Identifier : " << Name << "Option)\n" << " if (!setRuleDisabled(Identifier))\n" << " return false;\n"