[llvm] 1a0ddbd - [GlobalISel] Filter combiner worklists (#197693)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 15 02:13:57 PDT 2026


Author: Cullen Rhodes
Date: 2026-07-15T10:13:53+01:00
New Revision: 1a0ddbdff9eef0257445778f36dd19b74f018487

URL: https://github.com/llvm/llvm-project/commit/1a0ddbdff9eef0257445778f36dd19b74f018487
DIFF: https://github.com/llvm/llvm-project/commit/1a0ddbdff9eef0257445778f36dd19b74f018487.diff

LOG: [GlobalISel] Filter combiner worklists (#197693)

This follows on from #196017 which added an opcode predicate for GICombiner
matchers and used it to return from tryCombineAll before executing the match
table.

The better approach is to not add opcodes with no combines to the worklist in
the first place. This is a further -0.35% CTMark geomean improvement on
aarch64-O0-g, sqlite is -0.67%.

https://llvm-compile-time-tracker.com/compare.php?from=35f5d7ea802eae78b26a5fb2a46f072acd15f49d&to=c356bec46b68b59f37b26347f93676c9102d810c&stat=instructions%3Au

I also measured O3 locally and it's positive:

```
stage1-aarch64-O3 -fglobal-isel
                 instructions:u                 diff
                            old           new
7zip               203863583445  203865335443  0.00%
Bullet             103920943623  103917036315 -0.00%
ClamAV              53008970261   52971646424 -0.07%
SPASS               41843361245   41815471487 -0.07%
consumer-typeset    31848080935   31816255572 -0.10%
kimwitu++           39779892082   39733563964 -0.12%
lencod              67158153709   67134337444 -0.04%
mafft               36689364945   36675438948 -0.04%
sqlite3             33436727535   33410098701 -0.08%
tramp3d-v4          76553056559   76569825676  0.02%
geomean             57208304686   57180409869 -0.05%
```

I am a bit worried about the incurred overhead of this for other opt levels as
we add more combines, but right now at least the data is positive.

Assisted-by: codex

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
    llvm/lib/CodeGen/GlobalISel/Combiner.cpp
    llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
    llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
index 3b8cb91ac1efa..bd9a526eae606 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
@@ -65,6 +65,8 @@ class LLVM_ABI Combiner : public GIMatchTableExecutor {
   bool combineMachineInstrs();
 
 protected:
+  virtual bool canMatchOpcode(unsigned Opc) const { return true; }
+
   const CombinerInfo &CInfo;
   GISelChangeObserver &Observer;
   MachineIRBuilder &B;

diff  --git a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
index a4121fbb7b6c8..3b051aacba8ab 100644
--- a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
@@ -297,7 +297,8 @@ bool Combiner::combineMachineInstrs() {
         // Erase dead insts before even adding to the list.
         if (EnableDCE && tryDCE(CurMI, MRI))
           continue;
-        WorkList.deferred_insert(&CurMI);
+        if (canMatchOpcode(CurMI.getOpcode()))
+          WorkList.deferred_insert(&CurMI);
       }
     }
     WorkList.finalize();

diff  --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
index 595b4339170a9..58c25ab925b85 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
@@ -84,7 +84,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
 
 // Verify we gate on opcodes with generated combines and reset MatchData on each
 // tryCombineAll.
-// CHECK:      static bool GenMyCombiner_canMatchOpcode(unsigned Opc) {
+// CHECK:      bool GenMyCombiner::canMatchOpcode(unsigned Opc) const {
 // CHECK-NEXT:   switch (Opc) {
 // CHECK-DAG:    case TargetOpcode::COPY:
 // CHECK-DAG:    case TargetOpcode::G_AND:
@@ -99,8 +99,6 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
 // CHECK-NEXT: }
 // CHECK-EMPTY:
 // CHECK:      bool GenMyCombiner::tryCombineAll(MachineInstr &I) const {
-// CHECK-NEXT:   if (!GenMyCombiner_canMatchOpcode(I.getOpcode()))
-// CHECK-NEXT:     return false;
 // CHECK-NEXT:   const PredicateBitset AvailableFeatures = getAvailableFeatures();
 // CHECK-NEXT:   State.MIs.clear();
 // CHECK-NEXT:   State.MIs.push_back(&I);

diff  --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
index 6a338489b4a6d..bb93d0248e55f 100644
--- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
@@ -2583,7 +2583,7 @@ void GICombinerEmitter::collectMatchOpcodes(ArrayRef<RuleMatcher> Rules) {
 
 void GICombinerEmitter::emitCanMatchOpcodeFn(raw_ostream &OS,
                                              StringRef FnName) const {
-  OS << "static bool " << FnName << "(unsigned Opc) {\n";
+  OS << "bool " << FnName << "(unsigned Opc) const {\n";
   if (MatchOpcodes.empty()) {
     OS << "  (void)Opc;\n"
        << "  return false;\n"
@@ -2602,12 +2602,11 @@ void GICombinerEmitter::emitCanMatchOpcodeFn(raw_ostream &OS,
 }
 
 void GICombinerEmitter::emitAdditionalImpl(raw_ostream &OS) {
-  std::string CanMatchOpcodeFnName = (getClassName() + "_canMatchOpcode").str();
+  std::string CanMatchOpcodeFnName =
+      (getClassName() + "::canMatchOpcode").str();
   emitCanMatchOpcodeFn(OS, CanMatchOpcodeFnName);
   OS << "bool " << getClassName() << "::" << getCombineAllMethodName()
      << "(MachineInstr &I) const {\n"
-     << "  if (!" << CanMatchOpcodeFnName << "(I.getOpcode()))\n"
-     << "    return false;\n"
      << "  const PredicateBitset AvailableFeatures = "
         "getAvailableFeatures();\n"
      << "  State.MIs.clear();\n"
@@ -2824,6 +2823,10 @@ void GICombinerEmitter::run(raw_ostream &OS) {
   emitPredicateBitset(OS, "GET_GICOMBINER_TYPES");
 
   // GET_GICOMBINER_CLASS_MEMBERS, which need to be included inside the class.
+  {
+    IfDefGuardEmitter If(OS, "GET_GICOMBINER_CLASS_MEMBERS");
+    OS << "  bool canMatchOpcode(unsigned Opc) const override;\n";
+  }
   emitPredicatesDecl(OS, "GET_GICOMBINER_CLASS_MEMBERS");
   emitTemporariesDecl(OS, "GET_GICOMBINER_CLASS_MEMBERS");
 


        


More information about the llvm-commits mailing list