[llvm] [GlobalISel] Delay match table builder initialization (PR #196506)

Cullen Rhodes via llvm-commits llvm-commits at lists.llvm.org
Fri May 8 03:14:56 PDT 2026


https://github.com/c-rhodes created https://github.com/llvm/llvm-project/pull/196506

MachineIRBuilder::setInstrAndDebugLoc is expensive, delay until needed.

CTMark -0.10% geomean improvement on aarch64-O0-g.

https://llvm-compile-time-tracker.com/compare.php?from=71fef6d5a306d1adf8bf7d30d2fe9e286380fecf&to=8a87845dfde9de9d141b42d2fce92fcf3be02276&stat=instructions%3Au

Assisted-by: codex

>From 8a87845dfde9de9d141b42d2fce92fcf3be02276 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Fri, 8 May 2026 09:36:40 +0000
Subject: [PATCH] [GlobalISel] Delay match table builder initialization

MachineIRBuilder::setInstrAndDebugLoc is expensive, delay until needed.

Assisted-by: codex
---
 .../CodeGen/GlobalISel/GIMatchTableExecutorImpl.h   | 13 +++++++++++++
 .../GlobalISelCombinerEmitter/match-table.td        |  1 -
 llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp   |  1 -
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 4576dff67db0c..f68cec34e69e1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -59,6 +59,15 @@ bool GIMatchTableExecutor::executeMatchTable(
   bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
 
   const uint32_t Flags = State.MIs[0]->getFlags();
+  bool BuilderInitialized = false;
+  const auto initializeBuilder = [&]() {
+    if (BuilderInitialized)
+      return;
+    // Delay setting the insertion point and debug location until a successful
+    // action needs the builder.
+    Builder.setInstrAndDebugLoc(*State.MIs[0]);
+    BuilderInitialized = true;
+  };
 
   enum RejectAction { RejectAndGiveUp, RejectAndResume };
   auto handleReject = [&]() -> RejectAction {
@@ -1089,6 +1098,7 @@ bool GIMatchTableExecutor::executeMatchTable(
       if (NewInsnID >= OutMIs.size())
         OutMIs.resize(NewInsnID + 1);
 
+      initializeBuilder();
       OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
@@ -1099,6 +1109,7 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_BuildConstant: {
       uint64_t TempRegID = readULEB();
       uint64_t Imm = readU64();
+      initializeBuilder();
       Builder.buildConstant(State.TempRegisters[TempRegID], Imm);
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs() << CurrentIdx << ": GIR_BuildConstant(TempReg["
@@ -1495,6 +1506,7 @@ bool GIMatchTableExecutor::executeMatchTable(
       uint64_t InsnID = readULEB();
       MachineInstr *MI = State.MIs[InsnID];
       assert(MI && "Attempted to erase an undefined instruction");
+      initializeBuilder();
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
                              << InsnID << "])\n");
@@ -1502,6 +1514,7 @@ bool GIMatchTableExecutor::executeMatchTable(
       break;
     }
     case GIR_EraseRootFromParent_Done: {
+      initializeBuilder();
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs()
                           << CurrentIdx << ": GIR_EraseRootFromParent_Done\n");
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
index 8907cfe811abd..4278b6b614138 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
@@ -86,7 +86,6 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
 // CHECK:      bool GenMyCombiner::tryCombineAll(MachineInstr &I) const {
 // CHECK-NEXT:   const TargetSubtargetInfo &ST = MF.getSubtarget();
 // CHECK-NEXT:   const PredicateBitset AvailableFeatures = getAvailableFeatures();
-// CHECK-NEXT:   B.setInstrAndDebugLoc(I);
 // CHECK-NEXT:   State.MIs.clear();
 // CHECK-NEXT:   State.MIs.push_back(&I);
 // CHECK-NEXT:   if (executeMatchTable(*this, State, ExecInfo, B, getMatchTable(), *ST.getInstrInfo(), MRI, *MRI.getTargetRegisterInfo(), *ST.getRegBankInfo(), AvailableFeatures, /*CoverageInfo*/ nullptr))
diff --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
index 56b39fcd1cc9e..61c4c9eb29b71 100644
--- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
@@ -2563,7 +2563,6 @@ void GICombinerEmitter::emitAdditionalImpl(raw_ostream &OS) {
      << "  const TargetSubtargetInfo &ST = MF.getSubtarget();\n"
      << "  const PredicateBitset AvailableFeatures = "
         "getAvailableFeatures();\n"
-     << "  B.setInstrAndDebugLoc(I);\n"
      << "  State.MIs.clear();\n"
      << "  State.MIs.push_back(&I);\n"
      << "  if (executeMatchTable(*this, State, ExecInfo, B"



More information about the llvm-commits mailing list