[llvm] [NFC][GlobalISel] Refactor ownership of InstructionMatchers (PR #200798)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 4 00:40:47 PDT 2026


https://github.com/graphite-app[bot] updated https://github.com/llvm/llvm-project/pull/200798

>From a4d1cb4ea19728c43b006c66e4e73db0e1307ade Mon Sep 17 00:00:00 2001
From: Pierre-vh <29600849+Pierre-vh at users.noreply.github.com>
Date: Thu, 4 Jun 2026 07:40:29 +0000
Subject: [PATCH] [NFC][GlobalISel] Refactor ownership of InstructionMatchers
 (#200798)

- Clarify that the array of InstructionMatchers in the RuleMatcher are for the roots only.
- Let RuleMatcher own all of the InstructionMatcher used for/by predicates.
They are all kept in an array in which the index of the InstructionMatcher is equal to its
InsnID, which eliminates some redundant tracking.
- Remove duplicate tracking of InsnID from RuleMatcher; InstructionMatcher does it on its own already.
---
 .../Common/GlobalISel/MatchTable/Matchers.cpp | 112 ++++++++----------
 .../Common/GlobalISel/MatchTable/Matchers.h   |  72 +++++------
 .../TableGen/GlobalISelCombinerEmitter.cpp    |   6 +-
 llvm/utils/TableGen/GlobalISelEmitter.cpp     |   4 +-
 4 files changed, 82 insertions(+), 112 deletions(-)

diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
index 92fa3c224a497..5111702d6e7e2 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
@@ -120,9 +120,9 @@ std::vector<Matcher *> llvm::gi::optimizeRuleset(
         const auto *L = cast<RuleMatcher>(A);
         const auto *R = cast<RuleMatcher>(B);
         return std::tuple(OpcodeOrder[L->getOpcode()],
-                          L->insnmatchers_front().getNumOperandMatchers()) <
+                          L->roots_front().getNumOperandMatchers()) <
                std::tuple(OpcodeOrder[R->getOpcode()],
-                          R->insnmatchers_front().getNumOperandMatchers());
+                          R->roots_front().getNumOperandMatchers());
       });
 
   for (Matcher *R : InputRules)
@@ -482,16 +482,14 @@ RuleMatcher::RuleMatcher(ArrayRef<SMLoc> SrcLoc)
 
 uint64_t RuleMatcher::NextRuleID = 0;
 
-StringRef RuleMatcher::getOpcode() const {
-  return Matchers.front()->getOpcode();
-}
+StringRef RuleMatcher::getOpcode() const { return Roots.front()->getOpcode(); }
 
 bool RuleMatcher::recordsOperand() const {
-  return matchersRecordOperand(Matchers);
+  return matchersRecordOperand(Roots);
 }
 
 LLTCodeGen RuleMatcher::getFirstConditionAsRootType() const {
-  InstructionMatcher &InsnMatcher = *Matchers.front();
+  InstructionMatcher &InsnMatcher = *Roots.front();
   if (!InsnMatcher.predicates_empty()) {
     if (const auto *TM =
             dyn_cast<LLTOperandMatcher>(&**InsnMatcher.predicates_begin())) {
@@ -503,9 +501,8 @@ LLTCodeGen RuleMatcher::getFirstConditionAsRootType() const {
 }
 
 void RuleMatcher::optimize() {
-  for (auto &Item : InsnVariableIDs) {
-    InstructionMatcher &InsnMatcher = *Item.first;
-    for (auto &OM : InsnMatcher.operands()) {
+  for (const auto &InsnMatcher : InsnMatchers) {
+    for (auto &OM : InsnMatcher->operands()) {
       // Complex Patterns are usually expensive and they relatively rarely fail
       // on their own: more often we end up throwing away all the work done by a
       // matching part of a complex pattern because some other part of the
@@ -517,7 +514,7 @@ void RuleMatcher::optimize() {
           EpilogueMatchers.emplace_back(std::move(OP));
       OM->eraseNullPredicates();
     }
-    InsnMatcher.optimize();
+    InsnMatcher->optimize();
   }
   llvm::sort(EpilogueMatchers, [](const std::unique_ptr<PredicateMatcher> &L,
                                   const std::unique_ptr<PredicateMatcher> &R) {
@@ -550,9 +547,9 @@ void RuleMatcher::optimize() {
 }
 
 bool RuleMatcher::hasFirstCondition() const {
-  if (insnmatchers_empty())
+  if (roots_empty())
     return false;
-  InstructionMatcher &Matcher = insnmatchers_front();
+  InstructionMatcher &Matcher = roots_front();
   if (!Matcher.predicates_empty())
     return true;
   for (auto &OM : Matcher.operands())
@@ -563,10 +560,10 @@ bool RuleMatcher::hasFirstCondition() const {
 }
 
 const PredicateMatcher &RuleMatcher::getFirstCondition() const {
-  assert(!insnmatchers_empty() &&
+  assert(!roots_empty() &&
          "Trying to get a condition from an empty RuleMatcher");
 
-  InstructionMatcher &Matcher = insnmatchers_front();
+  InstructionMatcher &Matcher = roots_front();
   if (!Matcher.predicates_empty())
     return **Matcher.predicates_begin();
   // If there is no more predicate on the instruction itself, look at its
@@ -581,10 +578,10 @@ const PredicateMatcher &RuleMatcher::getFirstCondition() const {
 }
 
 std::unique_ptr<PredicateMatcher> RuleMatcher::popFirstCondition() {
-  assert(!insnmatchers_empty() &&
+  assert(!roots_empty() &&
          "Trying to pop a condition from an empty RuleMatcher");
 
-  InstructionMatcher &Matcher = insnmatchers_front();
+  InstructionMatcher &Matcher = roots_front();
   if (!Matcher.predicates_empty())
     return Matcher.predicates_pop_front();
   // If there is no more predicate on the instruction itself, look at its
@@ -653,9 +650,10 @@ Error RuleMatcher::defineComplexSubOperand(StringRef SymbolicName,
 }
 
 InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
-  Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
-  MutatableInsns.insert(Matchers.back().get());
-  return *Matchers.back();
+  auto &Res = allocateInstructionMatcher(SymbolicName);
+  Roots.push_back(&Res);
+  MutatableInsns.insert(&Res);
+  return Res;
 }
 
 void RuleMatcher::addRequiredSimplePredicate(StringRef PredName) {
@@ -666,19 +664,6 @@ const std::vector<std::string> &RuleMatcher::getRequiredSimplePredicates() {
   return RequiredSimplePredicates;
 }
 
-unsigned RuleMatcher::implicitlyDefineInsnVar(InstructionMatcher &Matcher) {
-  unsigned NewInsnVarID = NextInsnVarID++;
-  InsnVariableIDs[&Matcher] = NewInsnVarID;
-  return NewInsnVarID;
-}
-
-unsigned RuleMatcher::getInsnVarID(InstructionMatcher &InsnMatcher) const {
-  const auto &I = InsnVariableIDs.find(&InsnMatcher);
-  if (I != InsnVariableIDs.end())
-    return I->second;
-  llvm_unreachable("Matched Insn was not captured in a local variable");
-}
-
 void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
   if (DefinedOperands.try_emplace(SymbolicName, &OM).second)
     return;
@@ -697,9 +682,10 @@ void RuleMatcher::definePhysRegOperand(const Record *Reg, OperandMatcher &OM) {
 
 InstructionMatcher &
 RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
-  for (const auto &I : InsnVariableIDs)
-    if (I.first->getSymbolicName() == SymbolicName)
-      return *I.first;
+  for (const auto &InsnMatcher : InsnMatchers) {
+    if (InsnMatcher->getSymbolicName() == SymbolicName)
+      return *InsnMatcher;
+  }
   llvm_unreachable(
       ("Failed to lookup instruction " + SymbolicName).str().c_str());
 }
@@ -735,7 +721,7 @@ const OperandMatcher &RuleMatcher::getOperandMatcher(StringRef Name) const {
 }
 
 void RuleMatcher::emit(MatchTable &Table) {
-  if (Matchers.empty())
+  if (Roots.empty())
     llvm_unreachable("Unexpected empty matcher!");
 
   // The representation supports rules that require multiple roots such as:
@@ -747,7 +733,7 @@ void RuleMatcher::emit(MatchTable &Table) {
   //    %ptr(p0) = ...
   //    %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
   // on some targets but we don't need to make use of that yet.
-  assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
+  assert(Roots.size() == 1 && "Cannot handle multi-root matchers yet");
 
   unsigned LabelID = Table.allocateLabelID();
 
@@ -772,14 +758,14 @@ void RuleMatcher::emit(MatchTable &Table) {
     }
   }
 
-  Matchers.front()->emitPredicateOpcodes(Table, *this);
+  Roots.front()->emitPredicateOpcodes(Table, *this);
 
   // Check if it's safe to replace registers.
   for (const auto &MA : Actions)
     MA->emitAdditionalPredicates(Table, *this);
 
   // We must also check if it's safe to fold the matched instructions.
-  if (InsnVariableIDs.size() >= 2) {
+  if (InsnMatchers.size() >= 2) {
 
     // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
     //        account for unsafe cases.
@@ -818,7 +804,7 @@ void RuleMatcher::emit(MatchTable &Table) {
 
     Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
           << MatchTable::Comment("NumInsns")
-          << MatchTable::IntValue(1, InsnVariableIDs.size() - 1)
+          << MatchTable::IntValue(1, InsnMatchers.size() - 1)
           << MatchTable::LineBreak;
   }
 
@@ -871,12 +857,12 @@ void RuleMatcher::emit(MatchTable &Table) {
 
 bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
   // Rules involving more match roots have higher priority.
-  if (Matchers.size() > B.Matchers.size())
+  if (Roots.size() > B.Roots.size())
     return true;
-  if (Matchers.size() < B.Matchers.size())
+  if (Roots.size() < B.Roots.size())
     return false;
 
-  for (auto Matcher : zip(Matchers, B.Matchers)) {
+  for (auto Matcher : zip(Roots, B.Roots)) {
     if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
       return true;
     if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
@@ -887,14 +873,13 @@ bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
 }
 
 unsigned RuleMatcher::countRendererFns() const {
-  return std::accumulate(
-      Matchers.begin(), Matchers.end(), 0,
-      [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
-        return A + Matcher->countRendererFns();
-      });
+  return std::accumulate(Roots.begin(), Roots.end(), 0,
+                         [](unsigned A, InstructionMatcher *Matcher) {
+                           return A + Matcher->countRendererFns();
+                         });
 }
 
-void RuleMatcher::insnmatchers_pop_front() { Matchers.erase(Matchers.begin()); }
+void RuleMatcher::roots_pop_front() { Roots.erase(Roots.begin()); }
 
 //===- PredicateMatcher ---------------------------------------------------===//
 
@@ -936,8 +921,7 @@ bool OperandPredicateMatcher::isHigherPriorityThan(
 void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
                                               RuleMatcher &Rule) const {
   const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
-  unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
-  assert(OtherInsnVarID == OtherOM.getInstructionMatcher().getInsnVarID());
+  unsigned OtherInsnVarID = OtherOM.getInstructionMatcher().getInsnVarID();
   const bool IgnoreCopies = Flags & GISF_IgnoreCopies;
   Table << MatchTable::Opcode(IgnoreCopies
                                   ? "GIM_CheckIsSameOperandIgnoreCopies"
@@ -1676,7 +1660,7 @@ void InstructionMatcher::optimize() {
 
 void InstructionOperandMatcher::emitCaptureOpcodes(MatchTable &Table,
                                                    RuleMatcher &Rule) const {
-  const unsigned NewInsnVarID = InsnMatcher->getInsnVarID();
+  const unsigned NewInsnVarID = InsnMatcher.getInsnVarID();
   const bool IgnoreCopies = Flags & GISF_IgnoreCopies;
   Table << MatchTable::Opcode(IgnoreCopies ? "GIM_RecordInsnIgnoreCopies"
                                            : "GIM_RecordInsn")
@@ -1697,7 +1681,7 @@ bool InstructionOperandMatcher::isHigherPriorityThan(
 
   if (const InstructionOperandMatcher *BP =
           dyn_cast<InstructionOperandMatcher>(&B))
-    if (InsnMatcher->isHigherPriorityThan(*BP->InsnMatcher))
+    if (InsnMatcher.isHigherPriorityThan(BP->InsnMatcher))
       return true;
   return false;
 }
@@ -1729,7 +1713,7 @@ void CopyRenderer::emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule,
 void CopyRenderer::emitRenderOpcodes(MatchTable &Table,
                                      RuleMatcher &Rule) const {
   const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
-  unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
+  unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID();
 
   emitRenderOpcodes(Table, Rule, NewInsnID, OldInsnVarID, Operand.getOpIdx(),
                     SymbolicName, Operand.isVariadic());
@@ -1740,7 +1724,7 @@ void CopyRenderer::emitRenderOpcodes(MatchTable &Table,
 void CopyPhysRegRenderer::emitRenderOpcodes(MatchTable &Table,
                                             RuleMatcher &Rule) const {
   const OperandMatcher &Operand = Rule.getPhysRegOperandMatcher(PhysReg);
-  unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
+  unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID();
   CopyRenderer::emitRenderOpcodes(Table, Rule, NewInsnID, OldInsnVarID,
                                   Operand.getOpIdx(), PhysReg->getName());
 }
@@ -1750,7 +1734,7 @@ void CopyPhysRegRenderer::emitRenderOpcodes(MatchTable &Table,
 void CopyOrAddZeroRegRenderer::emitRenderOpcodes(MatchTable &Table,
                                                  RuleMatcher &Rule) const {
   const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
-  unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
+  unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID();
   Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg")
         << MatchTable::Comment("NewInsnID")
         << MatchTable::ULEB128Value(NewInsnID)
@@ -1772,7 +1756,7 @@ void CopyOrAddZeroRegRenderer::emitRenderOpcodes(MatchTable &Table,
 void CopyConstantAsImmRenderer::emitRenderOpcodes(MatchTable &Table,
                                                   RuleMatcher &Rule) const {
   InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
-  unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
+  unsigned OldInsnVarID = InsnMatcher.getInsnVarID();
   Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
                                      : "GIR_CopyConstantAsUImm")
         << MatchTable::Comment("NewInsnID")
@@ -1787,7 +1771,7 @@ void CopyConstantAsImmRenderer::emitRenderOpcodes(MatchTable &Table,
 void CopyFConstantAsFPImmRenderer::emitRenderOpcodes(MatchTable &Table,
                                                      RuleMatcher &Rule) const {
   InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
-  unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
+  unsigned OldInsnVarID = InsnMatcher.getInsnVarID();
   Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
         << MatchTable::Comment("NewInsnID")
         << MatchTable::ULEB128Value(NewInsnID)
@@ -1801,7 +1785,7 @@ void CopyFConstantAsFPImmRenderer::emitRenderOpcodes(MatchTable &Table,
 void CopySubRegRenderer::emitRenderOpcodes(MatchTable &Table,
                                            RuleMatcher &Rule) const {
   const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
-  unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
+  unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID();
   Table << MatchTable::Opcode("GIR_CopySubReg")
         << MatchTable::Comment("NewInsnID")
         << MatchTable::ULEB128Value(NewInsnID)
@@ -1955,7 +1939,7 @@ void IntrinsicIDRenderer::emitRenderOpcodes(MatchTable &Table,
 void CustomRenderer::emitRenderOpcodes(MatchTable &Table,
                                        RuleMatcher &Rule) const {
   InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
-  unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
+  unsigned OldInsnVarID = InsnMatcher.getInsnVarID();
   Table << MatchTable::Opcode("GIR_CustomRenderer")
         << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID)
         << MatchTable::Comment("OldInsnID")
@@ -2049,7 +2033,7 @@ void BuildMIAction::emitActionOpcodes(MatchTable &Table,
     assert(canMutate(Rule, Matched) &&
            "Arranged to mutate an insn that isn't mutatable");
 
-    unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
+    unsigned RecycleInsnID = Matched->getInsnVarID();
     Table << MatchTable::Opcode("GIR_MutateOpcode")
           << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID)
           << MatchTable::Comment("RecycleInsnID")
@@ -2132,8 +2116,8 @@ void BuildMIAction::emitActionOpcodes(MatchTable &Table,
     //       sign-extend since it has no effect there.
 
     std::vector<unsigned> MergeInsnIDs;
-    for (const auto &IDMatcherPair : Rule.defined_insn_vars())
-      MergeInsnIDs.push_back(IDMatcherPair.second);
+    for (const auto &Matcher : Rule.all_instmatchers())
+      MergeInsnIDs.push_back(Matcher->getInsnVarID());
     llvm::sort(MergeInsnIDs);
 
     Table << MatchTable::Opcode("GIR_MergeMemOperands")
diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
index d300a846cbb41..a93c7f560eaa2 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
+++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
@@ -289,12 +289,14 @@ class RuleMatcher : public Matcher {
   using action_iterator = ActionList::iterator;
 
 protected:
+  std::vector<std::unique_ptr<InstructionMatcher>> InsnMatchers;
+
   /// A list of matchers that all need to succeed for the current rule to match.
   /// FIXME: This currently supports a single match position but could be
   /// extended to support multiple positions to support div/rem fusion or
   /// load-multiple instructions.
-  using MatchersTy = std::vector<std::unique_ptr<InstructionMatcher>>;
-  MatchersTy Matchers;
+  using RootsTy = SmallVector<InstructionMatcher *, 1>;
+  RootsTy Roots;
 
   /// A list of actions that need to be taken when all predicates in this rule
   /// have succeeded.
@@ -304,11 +306,6 @@ class RuleMatcher : public Matcher {
   /// mutate instructions instead of relying on MatchActions. Empty if unused.
   std::string CustomCXXAction;
 
-  using DefinedInsnVariablesMap = std::map<InstructionMatcher *, unsigned>;
-
-  /// A map of instruction matchers to the local variables
-  DefinedInsnVariablesMap InsnVariableIDs;
-
   using MutatableInsnSet = SmallPtrSet<InstructionMatcher *, 4>;
 
   // The set of instruction matchers that have not yet been claimed for mutation
@@ -325,10 +322,6 @@ class RuleMatcher : public Matcher {
   /// may be referenced by the renderers.
   PhysRegOperandsTy PhysRegOperands;
 
-  /// ID for the next instruction variable defined with
-  /// implicitlyDefineInsnVar()
-  unsigned NextInsnVarID = 0;
-
   /// ID for the next output instruction allocated with allocateOutputInsnID()
   unsigned NextOutputInsnID = 0;
 
@@ -370,6 +363,14 @@ class RuleMatcher : public Matcher {
   GISelFlags updateGISelFlag(GISelFlags CurFlags, const Record *R,
                              StringRef FlagName, GISelFlags FlagBit);
 
+  friend class InstructionOperandMatcher;
+
+  InstructionMatcher &allocateInstructionMatcher(StringRef SymbolicName,
+                                                 bool AllowNumOpsCheck = true) {
+    return *InsnMatchers.emplace_back(std::make_unique<InstructionMatcher>(
+        *this, InsnMatchers.size(), SymbolicName, AllowNumOpsCheck));
+  }
+
 public:
   RuleMatcher(ArrayRef<SMLoc> SrcLoc);
   RuleMatcher(RuleMatcher &&Other) = default;
@@ -437,21 +438,6 @@ class RuleMatcher : public Matcher {
   SaveAndRestore<GISelFlags> setGISelFlags(const Record *R);
   GISelFlags getGISelFlags() const { return Flags; }
 
-  /// Define an instruction without emitting any code to do so.
-  unsigned implicitlyDefineInsnVar(InstructionMatcher &Matcher);
-
-  unsigned getInsnVarID(InstructionMatcher &InsnMatcher) const;
-  DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
-    return InsnVariableIDs.begin();
-  }
-  DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
-    return InsnVariableIDs.end();
-  }
-  iterator_range<DefinedInsnVariablesMap::const_iterator>
-  defined_insn_vars() const {
-    return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
-  }
-
   MutatableInsnSet::const_iterator mutatable_insns_begin() const {
     return MutatableInsns.begin();
   }
@@ -467,6 +453,10 @@ class RuleMatcher : public Matcher {
     (void)R;
   }
 
+  auto all_instmatchers() const {
+    return make_range(InsnMatchers.begin(), InsnMatchers.end());
+  }
+
   action_iterator actions_begin() { return Actions.begin(); }
   action_iterator actions_end() { return Actions.end(); }
   iterator_range<action_iterator> actions() {
@@ -520,7 +510,7 @@ class RuleMatcher : public Matcher {
   StringRef getOpcode() const;
 
   // FIXME: Remove this as soon as possible
-  InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); }
+  InstructionMatcher &roots_front() const { return *Roots.front(); }
 
   unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
   unsigned allocateTempRegID() { return NextTempRegID++; }
@@ -529,9 +519,9 @@ class RuleMatcher : public Matcher {
     return make_range(PhysRegOperands.begin(), PhysRegOperands.end());
   }
 
-  iterator_range<MatchersTy::iterator> insnmatchers() { return Matchers; }
-  bool insnmatchers_empty() const { return Matchers.empty(); }
-  void insnmatchers_pop_front();
+  iterator_range<RootsTy::iterator> roots() { return Roots; }
+  bool roots_empty() const { return Roots.empty(); }
+  void roots_pop_front();
 };
 
 template <class PredicateTy> class PredicateListMatcher {
@@ -1676,14 +1666,10 @@ class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> {
   }
 
 public:
-  InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName,
-                     bool AllowNumOpsCheck = true)
-      : Rule(Rule), SymbolicName(SymbolicName),
-        AllowNumOpsCheck(AllowNumOpsCheck) {
-    // We create a new instruction matcher.
-    // Get a new ID for that instruction.
-    InsnVarID = Rule.implicitlyDefineInsnVar(*this);
-  }
+  InstructionMatcher(RuleMatcher &Rule, unsigned InsnVarID,
+                     StringRef SymbolicName, bool AllowNumOpsCheck = true)
+      : Rule(Rule), SymbolicName(SymbolicName), InsnVarID(InsnVarID),
+        AllowNumOpsCheck(AllowNumOpsCheck) {}
 
   /// Construct a new instruction predicate and add it to the matcher.
   template <class Kind, class... Args>
@@ -1768,7 +1754,7 @@ class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> {
 /// subpattern.
 class InstructionOperandMatcher : public OperandPredicateMatcher {
 protected:
-  std::unique_ptr<InstructionMatcher> InsnMatcher;
+  InstructionMatcher &InsnMatcher;
 
   GISelFlags Flags;
 
@@ -1778,20 +1764,20 @@ class InstructionOperandMatcher : public OperandPredicateMatcher {
                             bool AllowNumOpsCheck = true)
       : OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
         InsnMatcher(
-            new InstructionMatcher(Rule, SymbolicName, AllowNumOpsCheck)),
+            Rule.allocateInstructionMatcher(SymbolicName, AllowNumOpsCheck)),
         Flags(Rule.getGISelFlags()) {}
 
   static bool classof(const PredicateMatcher *P) {
     return P->getKind() == OPM_Instruction;
   }
 
-  InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
+  InstructionMatcher &getInsnMatcher() const { return InsnMatcher; }
 
   void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const;
   void emitPredicateOpcodes(MatchTable &Table,
                             RuleMatcher &Rule) const override {
     emitCaptureOpcodes(Table, Rule);
-    InsnMatcher->emitPredicateOpcodes(Table, Rule);
+    InsnMatcher.emitPredicateOpcodes(Table, Rule);
   }
 
   bool isHigherPriorityThan(const OperandPredicateMatcher &B) const override;
@@ -1799,7 +1785,7 @@ class InstructionOperandMatcher : public OperandPredicateMatcher {
   /// Report the maximum number of temporary operands needed by the predicate
   /// matcher.
   unsigned countRendererFns() const override {
-    return InsnMatcher->countRendererFns();
+    return InsnMatcher.countRendererFns();
   }
 };
 
diff --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
index 129034f81d082..4dfd94ac5c54c 100644
--- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
@@ -1074,7 +1074,7 @@ void CombineRuleBuilder::addCXXPredicate(RuleMatcher &M,
                                          const PatternAlternatives &Alts) {
   // FIXME: Hack so C++ code is executed last. May not work for more complex
   // patterns.
-  auto &IM = *std::prev(M.insnmatchers().end());
+  auto &IM = *std::prev(M.roots().end());
   auto Loc = RuleDef.getLoc();
   const auto AddComment = [&](raw_ostream &OS) {
     OS << "// Pattern Alternatives: ";
@@ -1901,7 +1901,7 @@ bool CombineRuleBuilder::emitApplyPatterns(CodeExpansions &CE, RuleMatcher &M) {
 
   // Erase the root.
   unsigned RootInsnID =
-      M.getInsnVarID(M.getInstructionMatcher(MatchRoot->getName()));
+      M.getInstructionMatcher(MatchRoot->getName()).getInsnVarID();
   M.addAction<EraseInstAction>(RootInsnID);
 
   return true;
@@ -2566,7 +2566,7 @@ void GICombinerEmitter::emitRuleConfigImpl(raw_ostream &OS) {
 void GICombinerEmitter::collectMatchOpcodes(ArrayRef<RuleMatcher> Rules) {
   for (const RuleMatcher &Rule : Rules) {
     for (const CodeGenInstruction *I :
-         Rule.insnmatchers_front().getOpcodeMatcher().getAlternativeOpcodes())
+         Rule.roots_front().getOpcodeMatcher().getAlternativeOpcodes())
       MatchOpcodes.insert(I);
   }
 }
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index c707241dea6a0..e09bcc4905c1e 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -2222,7 +2222,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
       M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
 
       // Erase the root.
-      unsigned RootInsnID = M.getInsnVarID(InsnMatcher);
+      unsigned RootInsnID = InsnMatcher.getInsnVarID();
       M.addAction<EraseInstAction>(RootInsnID);
 
       // We're done with this pattern!  It's eligible for GISel emission; return
@@ -2305,7 +2305,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
     return std::move(Error);
 
   // Erase the root.
-  unsigned RootInsnID = M.getInsnVarID(InsnMatcher);
+  unsigned RootInsnID = InsnMatcher.getInsnVarID();
   M.addAction<EraseInstAction>(RootInsnID);
 
   // We're done with this pattern!  It's eligible for GISel emission; return it.



More information about the llvm-commits mailing list