[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