https://github.com/graphite-app[bot] updated https://github.com/llvm/llvm-project/pull/200799
>From 84551833aa31928a4d1e37bf3682462ad5384f9b Mon Sep 17 00:00:00 2001 From: Pierre-vh <[email protected]> Date: Thu, 4 Jun 2026 07:40:33 +0000 Subject: [PATCH] [GlobalISel] Do not depend on the RuleMatcher at MatchTable emission (#200799) Some PredicateMatchers/MatchAction/OperandRenderers relied on accessing RuleMatcher at emission as a crutch. Instead, make these classes collect all necessary information in the constructor so the `emit` methods don't depend on RuleMatcher anymore. The primary motivation for this is that I've been looking at ways to optimize the MatchTable better, and the fact that Predicates/Actions/Renderers are not "pure" objects, in the sense that they keep accessing a bunch of data all over the place even as late as emission, was a consistent pain. This is NFCI. There are no changes to any of the match table for AMDGPU/AArch64 in this patch. This patch has a bunch of noise due to function signature changes so I'll highlight the following interesting changes: - `SameOperandMatcher` needed a bit of an update in its `canHoistOutsideOf` function. I had to rewrite it but I think the end result is the same. - `EraseInstAction` has been updated as well, and its users in both Combiner/ISel backends have been updated to. Instead of ignoring this action if the Inst was already erased, it's now the responsibility of the builder to never insert it in the first place. `BuildMIAction` had a small update because of that too. Assisted-By: Claude Sonnet 4.6 Context-of-Use: I used Claude to mass-remove the `RuleMatcher&` arguments from the `emitPredicateOpcode` methods. It did not write any logic. --- .../Common/GlobalISel/MatchTable/Matchers.cpp | 303 +++++++----------- .../Common/GlobalISel/MatchTable/Matchers.h | 295 +++++++++-------- .../TableGen/GlobalISelCombinerEmitter.cpp | 12 +- llvm/utils/TableGen/GlobalISelEmitter.cpp | 40 +-- 4 files changed, 298 insertions(+), 352 deletions(-) diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp index 5111702d6e7e2..5f57537a49458 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp @@ -249,8 +249,7 @@ void GroupMatcher::emit(MatchTable &Table) { << MatchTable::JumpTarget(LabelID) << MatchTable::LineBreak; } for (auto &Condition : Conditions) - Condition->emitPredicateOpcodes( - Table, *static_cast<RuleMatcher *>(*Matchers.begin())); + Condition->emitPredicateOpcodes(Table); for (const auto &M : Matchers) M->emit(Table); @@ -671,9 +670,9 @@ void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) { // If the operand is already defined, then we must ensure both references in // the matcher have the exact same node. RuleMatcher &RM = OM.getInstructionMatcher().getRuleMatcher(); - OM.addPredicate<SameOperandMatcher>( - OM.getSymbolicName(), getOperandMatcher(OM.getSymbolicName()).getOpIdx(), - RM.getGISelFlags()); + auto &OtherOM = getOperandMatcher(OM.getSymbolicName()); + OM.addPredicate<SameOperandMatcher>(OtherOM.getInsnVarID(), + OtherOM.getOpIdx(), RM.getGISelFlags()); } void RuleMatcher::definePhysRegOperand(const Record *Reg, OperandMatcher &OM) { @@ -758,11 +757,11 @@ void RuleMatcher::emit(MatchTable &Table) { } } - Roots.front()->emitPredicateOpcodes(Table, *this); + Roots.front()->emitPredicateOpcodes(Table); // Check if it's safe to replace registers. for (const auto &MA : Actions) - MA->emitAdditionalPredicates(Table, *this); + MA->emitAdditionalPredicates(Table); // We must also check if it's safe to fold the matched instructions. if (InsnMatchers.size() >= 2) { @@ -809,7 +808,7 @@ void RuleMatcher::emit(MatchTable &Table) { } for (const auto &PM : EpilogueMatchers) - PM->emitPredicateOpcodes(Table, *this); + PM->emitPredicateOpcodes(Table); if (!CustomCXXAction.empty()) { /// Handle combiners relying on custom C++ code instead of actions. @@ -819,7 +818,7 @@ void RuleMatcher::emit(MatchTable &Table) { return A->getKind() != MatchAction::AK_DebugComment; })); for (const auto &MA : Actions) - MA->emitActionOpcodes(Table, *this); + MA->emitActionOpcodes(Table); Table << MatchTable::Opcode("GIR_DoneWithCustomAction", -1) << MatchTable::Comment("Fn") << MatchTable::NamedValue(2, CustomCXXAction) @@ -832,21 +831,25 @@ void RuleMatcher::emit(MatchTable &Table) { // double as a GIR_Done and terminate execution of the rule. if (!Actions.empty()) { for (const auto &MA : drop_end(Actions)) - MA->emitActionOpcodes(Table, *this); + MA->emitActionOpcodes(Table); } - assert((Table.isWithCoverage() ? !Table.isCombiner() : true) && - "Combiner tables don't support coverage!"); - if (Table.isWithCoverage()) - Table << MatchTable::Opcode("GIR_Coverage") - << MatchTable::IntValue(4, RuleID) << MatchTable::LineBreak; - else if (!Table.isCombiner()) - Table << MatchTable::Comment( - ("GIR_Coverage, " + Twine(RuleID) + ",").str()) - << MatchTable::LineBreak; + // Emit coverage right before the Done opcode> + auto EmitCoverage = [&] { + assert((Table.isWithCoverage() ? !Table.isCombiner() : true) && + "Combiner tables don't support coverage!"); + if (Table.isWithCoverage()) + Table << MatchTable::Opcode("GIR_Coverage") + << MatchTable::IntValue(4, RuleID) << MatchTable::LineBreak; + else if (!Table.isCombiner()) + Table << MatchTable::Comment( + ("GIR_Coverage, " + Twine(RuleID) + ",").str()) + << MatchTable::LineBreak; + }; if (Actions.empty() || - !Actions.back()->emitActionOpcodesAndDone(Table, *this)) { + !Actions.back()->emitActionOpcodesAndDone(Table, EmitCoverage)) { + EmitCoverage(); Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak; } } @@ -918,10 +921,7 @@ bool OperandPredicateMatcher::isHigherPriorityThan( //===- SameOperandMatcher -------------------------------------------------===// -void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName); - unsigned OtherInsnVarID = OtherOM.getInstructionMatcher().getInsnVarID(); +void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { const bool IgnoreCopies = Flags & GISF_IgnoreCopies; Table << MatchTable::Opcode(IgnoreCopies ? "GIM_CheckIsSameOperandIgnoreCopies" @@ -929,15 +929,9 @@ void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table, << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("OpIdx") << MatchTable::ULEB128Value(OpIdx) << MatchTable::Comment("OtherMI") - << MatchTable::ULEB128Value(OtherInsnVarID) + << MatchTable::ULEB128Value(OtherInsnID) << MatchTable::Comment("OtherOpIdx") - << MatchTable::ULEB128Value(OtherOM.getOpIdx()) - << MatchTable::LineBreak; -} - -bool SameOperandMatcher::canHoistOutsideOf(const Matcher &M) const { - const auto *RM = dyn_cast<RuleMatcher>(&M); - return !RM || !RM->hasOperand(MatchingName); + << MatchTable::ULEB128Value(OtherOpIdx) << MatchTable::LineBreak; } //===- LLTOperandMatcher --------------------------------------------------===// @@ -957,8 +951,7 @@ bool LLTOperandMatcher::hasValue() const { return TypeIDValues.count(Ty); } -void LLTOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void LLTOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { if (InsnVarID == 0) { Table << MatchTable::Opcode("GIM_RootCheckType"); } else { @@ -972,8 +965,7 @@ void LLTOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- PointerToAnyOperandMatcher -----------------------------------------===// -void PointerToAnyOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void PointerToAnyOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckPointerToAny") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) @@ -983,8 +975,7 @@ void PointerToAnyOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- RecordNamedOperandMatcher ------------------------------------------===// -void RecordNamedOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void RecordNamedOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_RecordNamedOperand") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) @@ -994,8 +985,7 @@ void RecordNamedOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- RecordRegisterType ------------------------------------------===// -void RecordRegisterType::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void RecordRegisterType::emitPredicateOpcodes(MatchTable &Table) const { assert(Idx < 0 && "Temp types always have negative indexes!"); Table << MatchTable::Opcode("GIM_RecordRegType") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") @@ -1006,7 +996,7 @@ void RecordRegisterType::emitPredicateOpcodes(MatchTable &Table, //===- ComplexPatternOperandMatcher ---------------------------------------===// void ComplexPatternOperandMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { unsigned ID = getAllocatedTemporariesBaseID(); Table << MatchTable::Opcode("GIM_CheckComplexPattern") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) @@ -1027,8 +1017,7 @@ bool RegisterBankOperandMatcher::isIdentical(const PredicateMatcher &B) const { RC.getDef() == cast<RegisterBankOperandMatcher>(&B)->RC.getDef(); } -void RegisterBankOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void RegisterBankOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { if (InsnVarID == 0) { Table << MatchTable::Opcode("GIM_RootCheckRegBankForClass"); } else { @@ -1044,8 +1033,7 @@ void RegisterBankOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- MBBOperandMatcher --------------------------------------------------===// -void MBBOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void MBBOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) << MatchTable::LineBreak; @@ -1053,8 +1041,7 @@ void MBBOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- ImmOperandMatcher --------------------------------------------------===// -void ImmOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void ImmOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckIsImm") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) << MatchTable::LineBreak; @@ -1062,8 +1049,7 @@ void ImmOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- ConstantIntOperandMatcher ------------------------------------------===// -void ConstantIntOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void ConstantIntOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { const bool IsInt8 = isInt<8>(Value); Table << MatchTable::Opcode(IsInt8 ? "GIM_CheckConstantInt8" : "GIM_CheckConstantInt") @@ -1074,8 +1060,7 @@ void ConstantIntOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- LiteralIntOperandMatcher -------------------------------------------===// -void LiteralIntOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void LiteralIntOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckLiteralInt") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) @@ -1084,8 +1069,7 @@ void LiteralIntOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- CmpPredicateOperandMatcher -----------------------------------------===// -void CmpPredicateOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void CmpPredicateOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckCmpPredicate") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) @@ -1096,8 +1080,7 @@ void CmpPredicateOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- IntrinsicIDOperandMatcher ------------------------------------------===// -void IntrinsicIDOperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void IntrinsicIDOperandMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckIntrinsicID") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) @@ -1107,8 +1090,7 @@ void IntrinsicIDOperandMatcher::emitPredicateOpcodes(MatchTable &Table, //===- OperandImmPredicateMatcher -----------------------------------------===// -void OperandImmPredicateMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void OperandImmPredicateMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckImmOperandPredicate") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("MO") << MatchTable::ULEB128Value(OpIdx) @@ -1120,7 +1102,7 @@ void OperandImmPredicateMatcher::emitPredicateOpcodes(MatchTable &Table, //===- OperandLeafPredicateMatcher ----------------------------------------===// void OperandLeafPredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckLeafOperandPredicate") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("MO") << MatchTable::ULEB128Value(OpIdx) @@ -1155,8 +1137,7 @@ bool OperandMatcher::recordsOperand() const { return matchersRecordOperand(Predicates); } -void OperandMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) { +void OperandMatcher::emitPredicateOpcodes(MatchTable &Table) { if (!Optimized) { std::string Comment; raw_string_ostream CommentOS(Comment); @@ -1168,7 +1149,7 @@ void OperandMatcher::emitPredicateOpcodes(MatchTable &Table, Table << MatchTable::Comment(Comment) << MatchTable::LineBreak; } - emitPredicateListOpcodes(Table, Rule); + emitPredicateListOpcodes(Table); } bool OperandMatcher::isHigherPriorityThan(OperandMatcher &B) { @@ -1261,8 +1242,7 @@ RecordAndValue InstructionOpcodeMatcher::getValue() const { return MatchTable::NamedValue(2, I->Namespace, I->getName()); } -void InstructionOpcodeMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void InstructionOpcodeMatcher::emitPredicateOpcodes(MatchTable &Table) const { StringRef CheckType = Insts.size() == 1 ? "GIM_CheckOpcode" : "GIM_CheckOpcodeIsEither"; Table << MatchTable::Opcode(CheckType) << MatchTable::Comment("MI") @@ -1311,7 +1291,7 @@ StringRef InstructionOpcodeMatcher::getOperandType(unsigned OpIdx) const { //===- InstructionNumOperandsMatcher --------------------------------------===// void InstructionNumOperandsMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { StringRef Opc; switch (CK) { case CheckKind::Eq: @@ -1341,7 +1321,7 @@ bool InstructionImmPredicateMatcher::isIdentical( } void InstructionImmPredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { Table << MatchTable::Opcode(getMatchOpcodeForImmPredicate(Predicate)) << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Predicate") @@ -1360,7 +1340,7 @@ bool AtomicOrderingMMOPredicateMatcher::isIdentical( } void AtomicOrderingMMOPredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { StringRef Opcode = "GIM_CheckAtomicOrdering"; if (Comparator == AO_OrStronger) @@ -1377,8 +1357,7 @@ void AtomicOrderingMMOPredicateMatcher::emitPredicateOpcodes( //===- MemorySizePredicateMatcher -----------------------------------------===// -void MemorySizePredicateMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void MemorySizePredicateMatcher::emitPredicateOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckMemorySizeEqualTo") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("MMO") << MatchTable::ULEB128Value(MMOIdx) @@ -1397,7 +1376,7 @@ bool MemoryAddressSpacePredicateMatcher::isIdentical( } void MemoryAddressSpacePredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { assert(AddrSpaces.size() < 256); Table << MatchTable::Opcode("GIM_CheckMemoryAddressSpace") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) @@ -1423,7 +1402,7 @@ bool MemoryAlignmentPredicateMatcher::isIdentical( } void MemoryAlignmentPredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { // TODO: we could support more, just need to emit the right opcode or switch // to log alignment. assert(MinAlign < 256); @@ -1445,7 +1424,7 @@ bool MemoryVsLLTSizePredicateMatcher::isIdentical( } void MemoryVsLLTSizePredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { Table << MatchTable::Opcode( Relation == EqualTo ? "GIM_CheckMemorySizeEqualToLLT" : Relation == GreaterThan ? "GIM_CheckMemorySizeGreaterThanLLT" @@ -1459,7 +1438,7 @@ void MemoryVsLLTSizePredicateMatcher::emitPredicateOpcodes( //===- VectorSplatImmPredicateMatcher -------------------------------------===// void VectorSplatImmPredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { if (Kind == AllOnes) Table << MatchTable::Opcode("GIM_CheckIsBuildVectorAllOnes"); else @@ -1483,7 +1462,7 @@ bool GenericInstructionPredicateMatcher::isIdentical( static_cast<const GenericInstructionPredicateMatcher &>(B).EnumVal; } void GenericInstructionPredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { Table << MatchTable::Opcode("GIM_CheckCxxInsnPredicate") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("FnId") << MatchTable::NamedValue(2, EnumVal) @@ -1502,7 +1481,7 @@ bool MIFlagsInstructionPredicateMatcher::isIdentical( } void MIFlagsInstructionPredicateMatcher::emitPredicateOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { Table << MatchTable::Opcode(CheckNot ? "GIM_MIFlagsNot" : "GIM_MIFlags") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::NamedValue(4, join(Flags, " | ")) @@ -1548,28 +1527,27 @@ bool InstructionMatcher::recordsOperand() const { return matchersRecordOperand(Predicates) || matchersRecordOperand(operands()); } -void InstructionMatcher::emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) { +void InstructionMatcher::emitPredicateOpcodes(MatchTable &Table) { if (canAddNumOperandsCheck()) { InstructionNumOperandsMatcher(InsnVarID, getNumOperandMatchers()) - .emitPredicateOpcodes(Table, Rule); + .emitPredicateOpcodes(Table); } // First emit all instruction level predicates need to be verified before we // can verify operands. emitFilteredPredicateListOpcodes( [](const PredicateMatcher &P) { return !P.dependsOnRecordedOperands(); }, - Table, Rule); + Table); // Emit all operand constraints. for (const auto &Operand : Operands) - Operand->emitPredicateOpcodes(Table, Rule); + Operand->emitPredicateOpcodes(Table); // All of the tablegen defined predicates should now be matched. Now emit // any custom predicates that rely on all generated checks. emitFilteredPredicateListOpcodes( [](const PredicateMatcher &P) { return P.dependsOnRecordedOperands(); }, - Table, Rule); + Table); } bool InstructionMatcher::isHigherPriorityThan(InstructionMatcher &B) { @@ -1658,8 +1636,7 @@ void InstructionMatcher::optimize() { //===- InstructionOperandMatcher ------------------------------------------===// -void InstructionOperandMatcher::emitCaptureOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void InstructionOperandMatcher::emitCaptureOpcodes(MatchTable &Table) const { const unsigned NewInsnVarID = InsnMatcher.getInsnVarID(); const bool IgnoreCopies = Flags & GISF_IgnoreCopies; Table << MatchTable::Opcode(IgnoreCopies ? "GIM_RecordInsnIgnoreCopies" @@ -1692,10 +1669,9 @@ OperandRenderer::~OperandRenderer() = default; //===- CopyRenderer -------------------------------------------------------===// -void CopyRenderer::emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned NewInsnID, unsigned OldInsnID, - unsigned OpIdx, StringRef Name, - bool ForVariadic) { +void CopyRenderer::emitRenderOpcodes(MatchTable &Table, unsigned NewInsnID, + unsigned OldInsnID, unsigned OldOpIdx, + StringRef Name, bool ForVariadic) { if (!ForVariadic && NewInsnID == 0 && OldInsnID == 0) { Table << MatchTable::Opcode("GIR_RootToRootCopy"); } else { @@ -1706,42 +1682,31 @@ void CopyRenderer::emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule, << MatchTable::ULEB128Value(OldInsnID); } - Table << MatchTable::Comment("OpIdx") << MatchTable::ULEB128Value(OpIdx) + Table << MatchTable::Comment("OpIdx") << MatchTable::ULEB128Value(OldOpIdx) << MatchTable::Comment(Name) << MatchTable::LineBreak; } -void CopyRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName); - unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID(); - - emitRenderOpcodes(Table, Rule, NewInsnID, OldInsnVarID, Operand.getOpIdx(), - SymbolicName, Operand.isVariadic()); +void CopyRenderer::emitRenderOpcodes(MatchTable &Table) const { + emitRenderOpcodes(Table, NewInsnID, OldInsnID, OldOpIdx, SymbolicName, + OldOpIsVariadic); } //===- CopyPhysRegRenderer ------------------------------------------------===// -void CopyPhysRegRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - const OperandMatcher &Operand = Rule.getPhysRegOperandMatcher(PhysReg); - unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID(); - CopyRenderer::emitRenderOpcodes(Table, Rule, NewInsnID, OldInsnVarID, - Operand.getOpIdx(), PhysReg->getName()); +void CopyPhysRegRenderer::emitRenderOpcodes(MatchTable &Table) const { + CopyRenderer::emitRenderOpcodes(Table, NewInsnID, OldInsnID, OldOpIdx, + PhysReg->getName()); } //===- CopyOrAddZeroRegRenderer -------------------------------------------===// -void CopyOrAddZeroRegRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName); - unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID(); +void CopyOrAddZeroRegRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg") << MatchTable::Comment("NewInsnID") << MatchTable::ULEB128Value(NewInsnID) << MatchTable::Comment("OldInsnID") - << MatchTable::ULEB128Value(OldInsnVarID) - << MatchTable::Comment("OpIdx") - << MatchTable::ULEB128Value(Operand.getOpIdx()) + << MatchTable::ULEB128Value(OldInsnID) << MatchTable::Comment("OpIdx") + << MatchTable::ULEB128Value(OldOpIdx) << MatchTable::NamedValue( 2, (ZeroRegisterDef->getValue("Namespace") @@ -1753,46 +1718,36 @@ void CopyOrAddZeroRegRenderer::emitRenderOpcodes(MatchTable &Table, //===- CopyConstantAsImmRenderer ------------------------------------------===// -void CopyConstantAsImmRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName); - unsigned OldInsnVarID = InsnMatcher.getInsnVarID(); +void CopyConstantAsImmRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm" : "GIR_CopyConstantAsUImm") << MatchTable::Comment("NewInsnID") << MatchTable::ULEB128Value(NewInsnID) << MatchTable::Comment("OldInsnID") - << MatchTable::ULEB128Value(OldInsnVarID) + << MatchTable::ULEB128Value(OldInsnID) << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak; } //===- CopyFConstantAsFPImmRenderer ---------------------------------------===// -void CopyFConstantAsFPImmRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName); - unsigned OldInsnVarID = InsnMatcher.getInsnVarID(); +void CopyFConstantAsFPImmRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm") << MatchTable::Comment("NewInsnID") << MatchTable::ULEB128Value(NewInsnID) << MatchTable::Comment("OldInsnID") - << MatchTable::ULEB128Value(OldInsnVarID) + << MatchTable::ULEB128Value(OldInsnID) << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak; } //===- CopySubRegRenderer -------------------------------------------------===// -void CopySubRegRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName); - unsigned OldInsnVarID = Operand.getInstructionMatcher().getInsnVarID(); +void CopySubRegRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_CopySubReg") << MatchTable::Comment("NewInsnID") << MatchTable::ULEB128Value(NewInsnID) << MatchTable::Comment("OldInsnID") - << MatchTable::ULEB128Value(OldInsnVarID) - << MatchTable::Comment("OpIdx") - << MatchTable::ULEB128Value(Operand.getOpIdx()) + << MatchTable::ULEB128Value(OldInsnID) << MatchTable::Comment("OpIdx") + << MatchTable::ULEB128Value(OldOpIdx) << MatchTable::Comment("SubRegIdx") << MatchTable::IntValue(2, SubReg->EnumValue) << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak; @@ -1800,8 +1755,7 @@ void CopySubRegRenderer::emitRenderOpcodes(MatchTable &Table, //===- AddRegisterRenderer ------------------------------------------------===// -void AddRegisterRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void AddRegisterRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_AddRegister") << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID); if (RegisterDef->getName() != "zero_reg") { @@ -1832,8 +1786,7 @@ void AddRegisterRenderer::emitRenderOpcodes(MatchTable &Table, //===- TempRegRenderer ----------------------------------------------------===// -void TempRegRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void TempRegRenderer::emitRenderOpcodes(MatchTable &Table) const { const bool NeedsFlags = (SubRegIdx || IsDef); if (SubRegIdx) { assert(!IsDef); @@ -1871,8 +1824,8 @@ void TempRegRenderer::emitRenderOpcodes(MatchTable &Table, //===- ImmRenderer --------------------------------------------------------===// -void ImmRenderer::emitAddImm(MatchTable &Table, RuleMatcher &RM, - unsigned InsnID, int64_t Imm, StringRef ImmName) { +void ImmRenderer::emitAddImm(MatchTable &Table, unsigned InsnID, int64_t Imm, + StringRef ImmName) { const bool IsInt8 = isInt<8>(Imm); Table << MatchTable::Opcode(IsInt8 ? "GIR_AddImm8" : "GIR_AddImm") @@ -1881,8 +1834,7 @@ void ImmRenderer::emitAddImm(MatchTable &Table, RuleMatcher &RM, << MatchTable::IntValue(IsInt8 ? 1 : 8, Imm) << MatchTable::LineBreak; } -void ImmRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void ImmRenderer::emitRenderOpcodes(MatchTable &Table) const { if (CImmLLT) { assert(Table.isCombiner() && "ConstantInt immediate are only for combiners!"); @@ -1892,22 +1844,19 @@ void ImmRenderer::emitRenderOpcodes(MatchTable &Table, Table << MatchTable::Comment("Imm") << MatchTable::IntValue(8, Imm) << MatchTable::LineBreak; } else { - emitAddImm(Table, Rule, InsnID, Imm); + emitAddImm(Table, InsnID, Imm); } } //===- SubRegIndexRenderer ------------------------------------------------===// -void SubRegIndexRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - ImmRenderer::emitAddImm(Table, Rule, InsnID, SubRegIdx->EnumValue, - "SubRegIndex"); +void SubRegIndexRenderer::emitRenderOpcodes(MatchTable &Table) const { + ImmRenderer::emitAddImm(Table, InsnID, SubRegIdx->EnumValue, "SubRegIndex"); } //===- RenderComplexPatternOperand ----------------------------------------===// -void RenderComplexPatternOperand::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void RenderComplexPatternOperand::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode( SubOperand ? (SubReg ? "GIR_ComplexSubOperandSubRegRenderer" : "GIR_ComplexSubOperandRenderer") @@ -1926,8 +1875,7 @@ void RenderComplexPatternOperand::emitRenderOpcodes(MatchTable &Table, //===- IntrinsicIDRenderer ------------------------------------------------===// -void IntrinsicIDRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void IntrinsicIDRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_AddIntrinsicID") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnID) << MatchTable::NamedValue(2, "Intrinsic::" + II->EnumName.str()) @@ -1936,14 +1884,11 @@ void IntrinsicIDRenderer::emitRenderOpcodes(MatchTable &Table, //===- CustomRenderer -----------------------------------------------------===// -void CustomRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName); - unsigned OldInsnVarID = InsnMatcher.getInsnVarID(); +void CustomRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_CustomRenderer") << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID) << MatchTable::Comment("OldInsnID") - << MatchTable::ULEB128Value(OldInsnVarID) + << MatchTable::ULEB128Value(OldInsnID) << MatchTable::Comment("Renderer") << MatchTable::NamedValue( 2, "GICR_" + Renderer.getValueAsString("RendererFn").str()) @@ -1952,15 +1897,12 @@ void CustomRenderer::emitRenderOpcodes(MatchTable &Table, //===- CustomOperandRenderer ----------------------------------------------===// -void CustomOperandRenderer::emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - const OperandMatcher &OpdMatcher = Rule.getOperandMatcher(SymbolicName); +void CustomOperandRenderer::emitRenderOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_CustomOperandRenderer") << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID) << MatchTable::Comment("OldInsnID") - << MatchTable::ULEB128Value(OpdMatcher.getInsnVarID()) - << MatchTable::Comment("OpIdx") - << MatchTable::ULEB128Value(OpdMatcher.getOpIdx()) + << MatchTable::ULEB128Value(OldInsnID) << MatchTable::Comment("OpIdx") + << MatchTable::ULEB128Value(OldOpIdx) << MatchTable::Comment("OperandRenderer") << MatchTable::NamedValue( 2, "GICR_" + Renderer.getValueAsString("RendererFn").str()) @@ -1998,13 +1940,13 @@ void BuildMIAction::chooseInsnToMutate(RuleMatcher &Rule) { // Take the first one we're offered that we're able to mutate. Rule.reserveInsnMatcherForMutation(MutateCandidate); Matched = MutateCandidate; + Rule.tryEraseInsnID(MutateCandidate->getInsnVarID()); return; } } } -void BuildMIAction::emitActionOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void BuildMIAction::emitActionOpcodes(MatchTable &Table) const { const auto AddMIFlags = [&]() { for (const InstructionMatcher *IM : CopiedFlags) { Table << MatchTable::Opcode("GIR_CopyMIFlags") @@ -2030,9 +1972,6 @@ void BuildMIAction::emitActionOpcodes(MatchTable &Table, }; if (Matched) { - assert(canMutate(Rule, Matched) && - "Arranged to mutate an insn that isn't mutatable"); - unsigned RecycleInsnID = Matched->getInsnVarID(); Table << MatchTable::Opcode("GIR_MutateOpcode") << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID) @@ -2072,7 +2011,6 @@ void BuildMIAction::emitActionOpcodes(MatchTable &Table, AddMIFlags(); // Mark the mutated instruction as erased. - Rule.tryEraseInsnID(RecycleInsnID); return; } @@ -2091,7 +2029,7 @@ void BuildMIAction::emitActionOpcodes(MatchTable &Table, << MatchTable::LineBreak; for (const auto &Renderer : OperandRenderers) - Renderer->emitRenderOpcodes(Table, Rule); + Renderer->emitRenderOpcodes(Table); for (auto [OpIdx, Def] : enumerate(I->ImplicitDefs)) { auto Namespace = @@ -2106,20 +2044,8 @@ void BuildMIAction::emitActionOpcodes(MatchTable &Table, } } - if (I->mayLoad || I->mayStore) { - // Emit the ID's for all the instructions that are matched by this rule. - // TODO: Limit this to matched instructions that mayLoad/mayStore or have - // some other means of having a memoperand. Also limit this to - // emitted instructions that expect to have a memoperand too. For - // example, (G_SEXT (G_LOAD x)) that results in separate load and - // sign-extend instructions shouldn't put the memoperand on the - // sign-extend since it has no effect there. - - std::vector<unsigned> MergeInsnIDs; - for (const auto &Matcher : Rule.all_instmatchers()) - MergeInsnIDs.push_back(Matcher->getInsnVarID()); - llvm::sort(MergeInsnIDs); - + if (!MergeInsnIDs.empty()) { + assert(I->mayLoad || I->mayStore); Table << MatchTable::Opcode("GIR_MergeMemOperands") << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID) << MatchTable::Comment("NumInsns") @@ -2135,8 +2061,7 @@ void BuildMIAction::emitActionOpcodes(MatchTable &Table, //===- BuildConstantAction ------------------------------------------------===// -void BuildConstantAction::emitActionOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void BuildConstantAction::emitActionOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_BuildConstant") << MatchTable::Comment("TempRegID") << MatchTable::ULEB128Value(TempRegID) << MatchTable::Comment("Val") @@ -2145,27 +2070,20 @@ void BuildConstantAction::emitActionOpcodes(MatchTable &Table, //===- EraseInstAction ----------------------------------------------------===// -void EraseInstAction::emitActionOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { - // Avoid erasing the same inst twice. - if (!Rule.tryEraseInsnID(InsnID)) - return; - +void EraseInstAction::emitActionOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_EraseFromParent") << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID) << MatchTable::LineBreak; } -bool EraseInstAction::emitActionOpcodesAndDone(MatchTable &Table, - RuleMatcher &Rule) const { +bool EraseInstAction::emitActionOpcodesAndDone( + MatchTable &Table, function_ref<void()> OnDone) const { if (InsnID != 0) { - emitActionOpcodes(Table, Rule); + emitActionOpcodes(Table); return false; } - if (!Rule.tryEraseInsnID(0)) - return false; - + OnDone(); Table << MatchTable::Opcode("GIR_EraseRootFromParent_Done", -1) << MatchTable::LineBreak; return true; @@ -2173,8 +2091,7 @@ bool EraseInstAction::emitActionOpcodesAndDone(MatchTable &Table, //===- ReplaceRegAction ---------------------------------------------------===// -void ReplaceRegAction::emitAdditionalPredicates(MatchTable &Table, - RuleMatcher &Rule) const { +void ReplaceRegAction::emitAdditionalPredicates(MatchTable &Table) const { if (TempRegID != (unsigned)-1) return; @@ -2188,8 +2105,7 @@ void ReplaceRegAction::emitAdditionalPredicates(MatchTable &Table, << MatchTable::LineBreak; } -void ReplaceRegAction::emitActionOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void ReplaceRegAction::emitActionOpcodes(MatchTable &Table) const { if (TempRegID != (unsigned)-1) { Table << MatchTable::Opcode("GIR_ReplaceRegWithTempReg") << MatchTable::Comment("OldInsnID") @@ -2214,7 +2130,7 @@ void ReplaceRegAction::emitActionOpcodes(MatchTable &Table, //===- ConstrainOperandToRegClassAction -----------------------------------===// void ConstrainOperandToRegClassAction::emitActionOpcodes( - MatchTable &Table, RuleMatcher &Rule) const { + MatchTable &Table) const { Table << MatchTable::Opcode("GIR_ConstrainOperandRC") << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) @@ -2224,8 +2140,7 @@ void ConstrainOperandToRegClassAction::emitActionOpcodes( //===- MakeTempRegisterAction ---------------------------------------------===// -void MakeTempRegisterAction::emitActionOpcodes(MatchTable &Table, - RuleMatcher &Rule) const { +void MakeTempRegisterAction::emitActionOpcodes(MatchTable &Table) const { Table << MatchTable::Opcode("GIR_MakeTempReg") << MatchTable::Comment("TempRegID") << MatchTable::ULEB128Value(TempRegID) << MatchTable::Comment("TypeID"); diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h index a93c7f560eaa2..76f242466f2ce 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h +++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h @@ -672,8 +672,7 @@ class PredicateMatcher { unsigned getOpIdx() const { return OpIdx; } /// Emit MatchTable opcodes that check the predicate for the given operand. - virtual void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const = 0; + virtual void emitPredicateOpcodes(MatchTable &Table) const = 0; PredicateKind getKind() const { return Kind; } @@ -738,31 +737,34 @@ PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const { /// Generates code to check that a register operand is defined by the same exact /// one as another. class SameOperandMatcher : public OperandPredicateMatcher { - std::string MatchingName; - unsigned OrigOpIdx; + unsigned OtherInsnID; + unsigned OtherOpIdx; GISelFlags Flags; public: - SameOperandMatcher(unsigned InsnVarID, unsigned OpIdx, StringRef MatchingName, - unsigned OrigOpIdx, GISelFlags Flags) + SameOperandMatcher(unsigned InsnVarID, unsigned OpIdx, unsigned OtherInsnID, + unsigned OtherOpIdx, GISelFlags Flags) : OperandPredicateMatcher(OPM_SameOperand, InsnVarID, OpIdx), - MatchingName(MatchingName), OrigOpIdx(OrigOpIdx), Flags(Flags) {} + OtherInsnID(OtherInsnID), OtherOpIdx(OtherOpIdx), Flags(Flags) {} static bool classof(const PredicateMatcher *P) { return P->getKind() == OPM_SameOperand; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; bool isIdentical(const PredicateMatcher &B) const override { return OperandPredicateMatcher::isIdentical(B) && - OrigOpIdx == cast<SameOperandMatcher>(&B)->OrigOpIdx && - MatchingName == cast<SameOperandMatcher>(&B)->MatchingName; + OtherInsnID == cast<SameOperandMatcher>(&B)->OtherInsnID && + OtherOpIdx == cast<SameOperandMatcher>(&B)->OtherOpIdx; } - virtual bool canHoistOutsideOf(const Matcher &M) const override; + virtual bool canHoistOutsideOf(const Matcher &M) const override { + // We can only hoist these if they only refer to the root instruction. + // We do not support hoisting predicates on non-root instructions. + return OtherInsnID == 0 && InsnVarID == 0; + } }; /// Generates code to check that an operand is a particular LLT. @@ -804,8 +806,7 @@ class LLTOperandMatcher : public OperandPredicateMatcher { LLTCodeGen getTy() const { return Ty; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that the element count & element sizes are the same. @@ -867,8 +868,7 @@ class PointerToAnyOperandMatcher : public OperandPredicateMatcher { SizeInBits == cast<PointerToAnyOperandMatcher>(&B)->SizeInBits; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to record named operand in RecordedOperands list at StoreIdx. @@ -895,8 +895,7 @@ class RecordNamedOperandMatcher : public OperandPredicateMatcher { Name == cast<RecordNamedOperandMatcher>(&B)->Name; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to store a register operand's type into the set of temporary @@ -919,8 +918,7 @@ class RecordRegisterType : public OperandPredicateMatcher { Idx == cast<RecordRegisterType>(&B)->Idx; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that an operand is a particular target constant. @@ -944,8 +942,7 @@ class ComplexPatternOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_ComplexPattern; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; unsigned countRendererFns() const override { return 1; } }; @@ -965,8 +962,7 @@ class RegisterBankOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_RegBank; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that an operand is a basic block. @@ -979,8 +975,7 @@ class MBBOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_MBB; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; class ImmOperandMatcher : public OperandPredicateMatcher { @@ -992,8 +987,7 @@ class ImmOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_Imm; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that an operand is a G_CONSTANT with a particular @@ -1015,8 +1009,7 @@ class ConstantIntOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_Int; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that an operand is a raw int (where MO.isImm() or @@ -1039,8 +1032,7 @@ class LiteralIntOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_LiteralInt; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that an operand is an CmpInst predicate @@ -1062,8 +1054,7 @@ class CmpPredicateOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_CmpPredicate; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that an operand is an intrinsic ID. @@ -1085,8 +1076,7 @@ class IntrinsicIDOperandMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_IntrinsicID; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that this operand is an immediate whose value meets @@ -1112,8 +1102,7 @@ class OperandImmPredicateMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_ImmPredicate; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that this operand is a register whose value meets @@ -1132,8 +1121,7 @@ class OperandLeafPredicateMatcher : public OperandPredicateMatcher { return P->getKind() == OPM_LeafPredicate; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that a set of predicates match for a particular @@ -1201,7 +1189,7 @@ class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> { /// Emit MatchTable opcodes that test whether the instruction named in /// InsnVarID matches all the predicates and all the operands. - void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule); + void emitPredicateOpcodes(MatchTable &Table); /// Compare the priority of this object and B. /// @@ -1290,8 +1278,7 @@ class InstructionOpcodeMatcher : public InstructionPredicateMatcher { // return a list of the opcodes to match. RecordAndValue getValue() const override; - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; /// Compare the priority of this object and B. /// @@ -1333,8 +1320,7 @@ class InstructionNumOperandsMatcher final : public InstructionPredicateMatcher { return NumOperands == Other.NumOperands && CK == Other.CK; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that this instruction is a constant whose value @@ -1380,8 +1366,7 @@ class InstructionImmPredicateMatcher : public InstructionPredicateMatcher { return P->getKind() == IPM_ImmPredicate; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that a memory instruction has a atomic ordering @@ -1410,8 +1395,7 @@ class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher { bool isIdentical(const PredicateMatcher &B) const override; - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that the size of an MMO is exactly N bytes. @@ -1434,8 +1418,7 @@ class MemorySizePredicateMatcher : public InstructionPredicateMatcher { Size == cast<MemorySizePredicateMatcher>(&B)->Size; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; class MemoryAddressSpacePredicateMatcher : public InstructionPredicateMatcher { @@ -1455,8 +1438,7 @@ class MemoryAddressSpacePredicateMatcher : public InstructionPredicateMatcher { bool isIdentical(const PredicateMatcher &B) const override; - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; class MemoryAlignmentPredicateMatcher : public InstructionPredicateMatcher { @@ -1478,8 +1460,7 @@ class MemoryAlignmentPredicateMatcher : public InstructionPredicateMatcher { bool isIdentical(const PredicateMatcher &B) const override; - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check that the size of an MMO is less-than, equal-to, or @@ -1508,8 +1489,7 @@ class MemoryVsLLTSizePredicateMatcher : public InstructionPredicateMatcher { } bool isIdentical(const PredicateMatcher &B) const override; - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; // Matcher for immAllOnesV/immAllZerosV @@ -1533,8 +1513,7 @@ class VectorSplatImmPredicateMatcher : public InstructionPredicateMatcher { Kind == static_cast<const VectorSplatImmPredicateMatcher &>(B).Kind; } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check an arbitrary C++ instruction predicate. @@ -1555,8 +1534,7 @@ class GenericInstructionPredicateMatcher : public InstructionPredicateMatcher { return P->getKind() == IPM_GenericPredicate; } bool isIdentical(const PredicateMatcher &B) const override; - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; bool canHoistOutsideOf(const Matcher &M) const override { // We can only hoist C++ code if the parent Matcher does not define any @@ -1585,8 +1563,7 @@ class MIFlagsInstructionPredicateMatcher : public InstructionPredicateMatcher { } bool isIdentical(const PredicateMatcher &B) const override; - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override; + void emitPredicateOpcodes(MatchTable &Table) const override; }; /// Generates code to check for the absence of use of the result. @@ -1604,8 +1581,7 @@ class NoUsePredicateMatcher : public InstructionPredicateMatcher { return InstructionPredicateMatcher::isIdentical(B); } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override { + void emitPredicateOpcodes(MatchTable &Table) const override { Table << MatchTable::Opcode("GIM_CheckHasNoUse") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::LineBreak; @@ -1626,8 +1602,7 @@ class OneUsePredicateMatcher : public InstructionPredicateMatcher { return InstructionPredicateMatcher::isIdentical(B); } - void emitPredicateOpcodes(MatchTable &Table, - RuleMatcher &Rule) const override { + void emitPredicateOpcodes(MatchTable &Table) const override { Table << MatchTable::Opcode("GIM_CheckHasOneUse") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::LineBreak; @@ -1718,7 +1693,7 @@ class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> { /// Emit MatchTable opcodes that test whether the instruction named in /// InsnVarName matches all the predicates and all the operands. - void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule); + void emitPredicateOpcodes(MatchTable &Table); /// Compare the priority of this object and B. /// @@ -1773,11 +1748,10 @@ class InstructionOperandMatcher : public OperandPredicateMatcher { 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); + void emitCaptureOpcodes(MatchTable &Table) const; + void emitPredicateOpcodes(MatchTable &Table) const override { + emitCaptureOpcodes(Table); + InsnMatcher.emitPredicateOpcodes(Table); } bool isHigherPriorityThan(const OperandPredicateMatcher &B) const override; @@ -1818,8 +1792,7 @@ class OperandRenderer { RendererKind getKind() const { return Kind; } - virtual void emitRenderOpcodes(MatchTable &Table, - RuleMatcher &Rule) const = 0; + virtual void emitRenderOpcodes(MatchTable &Table) const = 0; }; /// A CopyRenderer emits code to copy a single operand from an existing @@ -1827,14 +1800,20 @@ class OperandRenderer { class CopyRenderer : public OperandRenderer { protected: unsigned NewInsnID; - /// The name of the operand. - const StringRef SymbolicName; + StringRef SymbolicName; + unsigned OldInsnID; + unsigned OldOpIdx; + bool OldOpIsVariadic = false; public: - CopyRenderer(unsigned NewInsnID, StringRef SymbolicName) + CopyRenderer(unsigned NewInsnID, RuleMatcher &RM, StringRef SymbolicName) : OperandRenderer(OR_Copy), NewInsnID(NewInsnID), SymbolicName(SymbolicName) { assert(!SymbolicName.empty() && "Cannot copy from an unspecified source"); + const OperandMatcher &Operand = RM.getOperandMatcher(SymbolicName); + OldInsnID = Operand.getInstructionMatcher().getInsnVarID(); + OldOpIdx = Operand.getOpIdx(); + OldOpIsVariadic = Operand.isVariadic(); } static bool classof(const OperandRenderer *R) { @@ -1843,12 +1822,11 @@ class CopyRenderer : public OperandRenderer { StringRef getSymbolicName() const { return SymbolicName; } - static void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned NewInsnID, unsigned OldInsnID, - unsigned OpIdx, StringRef Name, - bool ForVariadic = false); + static void emitRenderOpcodes(MatchTable &Table, unsigned NewInsnID, + unsigned OldInsnID, unsigned OpIdx, + StringRef Name, bool ForVariadic = false); - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// A CopyRenderer emits code to copy a virtual register to a specific physical @@ -1857,11 +1835,16 @@ class CopyPhysRegRenderer : public OperandRenderer { protected: unsigned NewInsnID; const Record *PhysReg; + unsigned OldInsnID; + unsigned OldOpIdx; public: - CopyPhysRegRenderer(unsigned NewInsnID, const Record *Reg) + CopyPhysRegRenderer(unsigned NewInsnID, RuleMatcher &RM, const Record *Reg) : OperandRenderer(OR_CopyPhysReg), NewInsnID(NewInsnID), PhysReg(Reg) { assert(PhysReg); + const OperandMatcher &Operand = RM.getPhysRegOperandMatcher(PhysReg); + OldInsnID = Operand.getInstructionMatcher().getInsnVarID(); + OldOpIdx = Operand.getOpIdx(); } static bool classof(const OperandRenderer *R) { @@ -1870,7 +1853,7 @@ class CopyPhysRegRenderer : public OperandRenderer { const Record *getPhysReg() const { return PhysReg; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an @@ -1882,13 +1865,19 @@ class CopyOrAddZeroRegRenderer : public OperandRenderer { /// The name of the operand. const StringRef SymbolicName; const Record *ZeroRegisterDef; + unsigned OldInsnID; + unsigned OldOpIdx; public: - CopyOrAddZeroRegRenderer(unsigned NewInsnID, StringRef SymbolicName, + CopyOrAddZeroRegRenderer(unsigned NewInsnID, RuleMatcher &RM, + StringRef SymbolicName, const Record *ZeroRegisterDef) : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID), SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) { assert(!SymbolicName.empty() && "Cannot copy from an unspecified source"); + const OperandMatcher &Operand = RM.getOperandMatcher(SymbolicName); + OldInsnID = Operand.getInstructionMatcher().getInsnVarID(); + OldOpIdx = Operand.getOpIdx(); } static bool classof(const OperandRenderer *R) { @@ -1897,7 +1886,7 @@ class CopyOrAddZeroRegRenderer : public OperandRenderer { StringRef getSymbolicName() const { return SymbolicName; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to @@ -1908,11 +1897,16 @@ class CopyConstantAsImmRenderer : public OperandRenderer { /// The name of the operand. const std::string SymbolicName; bool Signed = true; + unsigned OldInsnID; public: - CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName) + CopyConstantAsImmRenderer(unsigned NewInsnID, RuleMatcher &RM, + StringRef SymbolicName) : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID), - SymbolicName(SymbolicName) {} + SymbolicName(SymbolicName) { + InstructionMatcher &InsnMatcher = RM.getInstructionMatcher(SymbolicName); + OldInsnID = InsnMatcher.getInsnVarID(); + } static bool classof(const OperandRenderer *R) { return R->getKind() == OR_CopyConstantAsImm; @@ -1920,7 +1914,7 @@ class CopyConstantAsImmRenderer : public OperandRenderer { StringRef getSymbolicName() const { return SymbolicName; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT @@ -1930,11 +1924,16 @@ class CopyFConstantAsFPImmRenderer : public OperandRenderer { unsigned NewInsnID; /// The name of the operand. const std::string SymbolicName; + unsigned OldInsnID; public: - CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName) + CopyFConstantAsFPImmRenderer(unsigned NewInsnID, RuleMatcher &RM, + StringRef SymbolicName) : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID), - SymbolicName(SymbolicName) {} + SymbolicName(SymbolicName) { + InstructionMatcher &InsnMatcher = RM.getInstructionMatcher(SymbolicName); + OldInsnID = InsnMatcher.getInsnVarID(); + } static bool classof(const OperandRenderer *R) { return R->getKind() == OR_CopyFConstantAsFPImm; @@ -1942,7 +1941,7 @@ class CopyFConstantAsFPImmRenderer : public OperandRenderer { StringRef getSymbolicName() const { return SymbolicName; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// A CopySubRegRenderer emits code to copy a single register operand from an @@ -1955,12 +1954,18 @@ class CopySubRegRenderer : public OperandRenderer { const StringRef SymbolicName; /// The subregister to extract. const CodeGenSubRegIndex *SubReg; + unsigned OldInsnID; + unsigned OldOpIdx; public: - CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName, - const CodeGenSubRegIndex *SubReg) + CopySubRegRenderer(unsigned NewInsnID, RuleMatcher &RM, + StringRef SymbolicName, const CodeGenSubRegIndex *SubReg) : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID), - SymbolicName(SymbolicName), SubReg(SubReg) {} + SymbolicName(SymbolicName), SubReg(SubReg) { + const OperandMatcher &Operand = RM.getOperandMatcher(SymbolicName); + OldInsnID = Operand.getInstructionMatcher().getInsnVarID(); + OldOpIdx = Operand.getOpIdx(); + } static bool classof(const OperandRenderer *R) { return R->getKind() == OR_CopySubReg; @@ -1968,7 +1973,7 @@ class CopySubRegRenderer : public OperandRenderer { StringRef getSymbolicName() const { return SymbolicName; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// Adds a specific physical register to the instruction being built. @@ -1992,7 +1997,7 @@ class AddRegisterRenderer : public OperandRenderer { return R->getKind() == OR_Register; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// Adds a specific temporary virtual register to the instruction being built. @@ -2017,7 +2022,7 @@ class TempRegRenderer : public OperandRenderer { return R->getKind() == OR_TempRegister; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// Adds a specific immediate to the instruction being built. @@ -2042,10 +2047,10 @@ class ImmRenderer : public OperandRenderer { return R->getKind() == OR_Imm; } - static void emitAddImm(MatchTable &Table, RuleMatcher &RM, unsigned InsnID, - int64_t Imm, StringRef ImmName = "Imm"); + static void emitAddImm(MatchTable &Table, unsigned InsnID, int64_t Imm, + StringRef ImmName = "Imm"); - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// Adds an enum value for a subreg index to the instruction being built. @@ -2062,7 +2067,7 @@ class SubRegIndexRenderer : public OperandRenderer { return R->getKind() == OR_SubRegIndex; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// Adds operands by calling a renderer function supplied by the ComplexPattern @@ -2099,7 +2104,7 @@ class RenderComplexPatternOperand : public OperandRenderer { return R->getKind() == OR_ComplexPattern; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// Adds an intrinsic ID operand to the instruction being built. @@ -2116,7 +2121,7 @@ class IntrinsicIDRenderer : public OperandRenderer { return R->getKind() == OR_Intrinsic; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; class CustomRenderer : public OperandRenderer { @@ -2125,18 +2130,22 @@ class CustomRenderer : public OperandRenderer { const Record &Renderer; /// The name of the operand. const std::string SymbolicName; + unsigned OldInsnID; public: - CustomRenderer(unsigned InsnID, const Record &Renderer, + CustomRenderer(unsigned InsnID, RuleMatcher &RM, const Record &Renderer, StringRef SymbolicName) : OperandRenderer(OR_Custom), InsnID(InsnID), Renderer(Renderer), - SymbolicName(SymbolicName) {} + SymbolicName(SymbolicName) { + InstructionMatcher &InsnMatcher = RM.getInstructionMatcher(SymbolicName); + OldInsnID = InsnMatcher.getInsnVarID(); + } static bool classof(const OperandRenderer *R) { return R->getKind() == OR_Custom; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; class CustomOperandRenderer : public OperandRenderer { @@ -2145,18 +2154,24 @@ class CustomOperandRenderer : public OperandRenderer { const Record &Renderer; /// The name of the operand. const std::string SymbolicName; + unsigned OldInsnID; + unsigned OldOpIdx; public: - CustomOperandRenderer(unsigned InsnID, const Record &Renderer, - StringRef SymbolicName) + CustomOperandRenderer(unsigned InsnID, RuleMatcher &RM, + const Record &Renderer, StringRef SymbolicName) : OperandRenderer(OR_CustomOperand), InsnID(InsnID), Renderer(Renderer), - SymbolicName(SymbolicName) {} + SymbolicName(SymbolicName) { + const OperandMatcher &OM = RM.getOperandMatcher(SymbolicName); + OldInsnID = OM.getInsnVarID(); + OldOpIdx = OM.getOpIdx(); + } static bool classof(const OperandRenderer *R) { return R->getKind() == OR_CustomOperand; } - void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitRenderOpcodes(MatchTable &Table) const override; }; /// An action taken when all Matcher predicates succeeded for a parent rule. @@ -2184,19 +2199,17 @@ class MatchAction { virtual ~MatchAction() = default; // Some actions may need to add extra predicates to ensure they can run. - virtual void emitAdditionalPredicates(MatchTable &Table, - RuleMatcher &Rule) const {} + virtual void emitAdditionalPredicates(MatchTable &Table) const {} /// Emit the MatchTable opcodes to implement the action. - virtual void emitActionOpcodes(MatchTable &Table, - RuleMatcher &Rule) const = 0; + virtual void emitActionOpcodes(MatchTable &Table) const = 0; - /// If this opcode has an overload that can call GIR_Done directly, emit that - /// instead of the usual opcode and return "true". Return "false" if GIR_Done - /// still needs to be emitted. + /// If this opcode has an overload that can call GIR_Done directly, call \p + /// OnDone, emit the opcode, and return true. Otherwise, emit the normal + /// action opcode and return false. virtual bool emitActionOpcodesAndDone(MatchTable &Table, - RuleMatcher &Rule) const { - emitActionOpcodes(Table, Rule); + function_ref<void()> OnDone) const { + emitActionOpcodes(Table); return false; } @@ -2216,7 +2229,7 @@ class DebugCommentAction : public MatchAction { return A->getKind() == AK_DebugComment; } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override { + void emitActionOpcodes(MatchTable &Table) const override { Table << MatchTable::Comment(S) << MatchTable::LineBreak; } }; @@ -2234,13 +2247,28 @@ class BuildMIAction : public MatchAction { std::vector<const InstructionMatcher *> CopiedFlags; std::vector<StringRef> SetFlags; std::vector<StringRef> UnsetFlags; + std::vector<unsigned> MergeInsnIDs; /// True if the instruction can be built solely by mutating the opcode. bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const; public: - BuildMIAction(unsigned InsnID, const CodeGenInstruction *I) - : MatchAction(AK_BuildMI), InsnID(InsnID), I(I) {} + BuildMIAction(unsigned InsnID, RuleMatcher &RM, const CodeGenInstruction *I) + : MatchAction(AK_BuildMI), InsnID(InsnID), I(I) { + + // Emit the ID's for all the instructions that are matched by this rule. + // TODO: Limit this to matched instructions that mayLoad/mayStore or have + // some other means of having a memoperand. Also limit this to + // emitted instructions that expect to have a memoperand too. For + // example, (G_SEXT (G_LOAD x)) that results in separate load and + // sign-extend instructions shouldn't put the memoperand on the + // sign-extend since it has no effect there. + if (I->mayLoad || I->mayStore) { + for (const auto &Matcher : RM.all_instmatchers()) + MergeInsnIDs.push_back(Matcher->getInsnVarID()); + llvm::sort(MergeInsnIDs); + } + } static bool classof(const MatchAction *A) { return A->getKind() == AK_BuildMI; @@ -2265,7 +2293,7 @@ class BuildMIAction : public MatchAction { return *static_cast<Kind *>(OperandRenderers.back().get()); } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitActionOpcodes(MatchTable &Table) const override; }; /// Generates code to create a constant that defines a TempReg. @@ -2283,7 +2311,7 @@ class BuildConstantAction : public MatchAction { return A->getKind() == AK_BuildConstantMI; } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitActionOpcodes(MatchTable &Table) const override; }; class EraseInstAction : public MatchAction { @@ -2299,9 +2327,9 @@ class EraseInstAction : public MatchAction { return A->getKind() == AK_EraseInst; } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitActionOpcodes(MatchTable &Table) const override; bool emitActionOpcodesAndDone(MatchTable &Table, - RuleMatcher &Rule) const override; + function_ref<void()> OnDone) const override; }; class ReplaceRegAction : public MatchAction { @@ -2323,9 +2351,8 @@ class ReplaceRegAction : public MatchAction { return A->getKind() == AK_ReplaceReg; } - void emitAdditionalPredicates(MatchTable &Table, - RuleMatcher &Rule) const override; - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitAdditionalPredicates(MatchTable &Table) const override; + void emitActionOpcodes(MatchTable &Table) const override; }; /// Generates code to constrain the operands of an output instruction to the @@ -2341,7 +2368,7 @@ class ConstrainOperandsToDefinitionAction : public MatchAction { return A->getKind() == AK_ConstraintOpsToDef; } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override { + void emitActionOpcodes(MatchTable &Table) const override { if (InsnID == 0) { Table << MatchTable::Opcode("GIR_RootConstrainSelectedInstOperands") << MatchTable::LineBreak; @@ -2370,7 +2397,7 @@ class ConstrainOperandToRegClassAction : public MatchAction { return A->getKind() == AK_ConstraintOpsToRC; } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitActionOpcodes(MatchTable &Table) const override; }; /// Generates code to create a temporary register which can be used to chain @@ -2391,7 +2418,7 @@ class MakeTempRegisterAction : public MatchAction { return A->getKind() == AK_MakeTempReg; } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override; + void emitActionOpcodes(MatchTable &Table) const override; }; } // namespace gi diff --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp index 4dfd94ac5c54c..daed2868fb351 100644 --- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp @@ -1902,7 +1902,8 @@ bool CombineRuleBuilder::emitApplyPatterns(CodeExpansions &CE, RuleMatcher &M) { // Erase the root. unsigned RootInsnID = M.getInstructionMatcher(MatchRoot->getName()).getInsnVarID(); - M.addAction<EraseInstAction>(RootInsnID); + if (M.tryEraseInsnID(RootInsnID)) + M.addAction<EraseInstAction>(RootInsnID); return true; } @@ -1985,7 +1986,7 @@ bool CombineRuleBuilder::emitInstructionApplyPattern( // Now render this inst. auto &DstMI = - M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &CGIP.getInst()); + M.addAction<BuildMIAction>(M.allocateOutputInsnID(), M, &CGIP.getInst()); bool HasEmittedIntrinsicID = false; const auto EmitIntrinsicID = [&]() { @@ -2028,7 +2029,7 @@ bool CombineRuleBuilder::emitInstructionApplyPattern( // the previous condition should have passed. assert(MatchOpTable.lookup(OpName).Found && !ApplyOpTable.getDef(OpName) && "Temp reg not emitted yet!"); - DstMI.addRenderer<CopyRenderer>(OpName); + DstMI.addRenderer<CopyRenderer>(M, OpName); } continue; } @@ -2056,7 +2057,7 @@ bool CombineRuleBuilder::emitInstructionApplyPattern( return false; } // redef of a match - DstMI.addRenderer<CopyRenderer>(OpName); + DstMI.addRenderer<CopyRenderer>(M, OpName); continue; } @@ -2169,7 +2170,8 @@ bool CombineRuleBuilder::emitBuiltinApplyPattern( switch (P.getBuiltinKind()) { case BI_EraseRoot: { // Root is always inst 0. - M.addAction<EraseInstAction>(/*InsnID*/ 0); + if (M.tryEraseInsnID(0)) + M.addAction<EraseInstAction>(/*InsnID*/ 0); return true; } case BI_ReplaceReg: { diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index e09bcc4905c1e..39eab594c2c4f 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -1296,12 +1296,12 @@ Error GlobalISelEmitter::importNamedNodeRenderer( StringRef OperatorName = N.getOperator()->getName(); if (OperatorName == "imm") { - MIBuilder.addRenderer<CopyConstantAsImmRenderer>(NodeName); + MIBuilder.addRenderer<CopyConstantAsImmRenderer>(M, NodeName); return Error::success(); } if (OperatorName == "fpimm") { - MIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(NodeName); + MIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(M, NodeName); return Error::success(); } @@ -1309,7 +1309,7 @@ Error GlobalISelEmitter::importNamedNodeRenderer( // Remove this check and add CopyRenderer unconditionally for other nodes. if (OperatorName == "bb" || OperatorName == "timm" || OperatorName == "tframeindex") { - MIBuilder.addRenderer<CopyRenderer>(NodeName); + MIBuilder.addRenderer<CopyRenderer>(M, NodeName); return Error::success(); } @@ -1337,7 +1337,7 @@ Error GlobalISelEmitter::importNamedNodeRenderer( if (R->isSubClassOf("RegisterOperand") && !R->isValueUnset("GIZeroRegister")) { MIBuilder.addRenderer<CopyOrAddZeroRegRenderer>( - NodeName, R->getValueAsDef("GIZeroRegister")); + M, NodeName, R->getValueAsDef("GIZeroRegister")); return Error::success(); } @@ -1345,7 +1345,7 @@ Error GlobalISelEmitter::importNamedNodeRenderer( // CopyRenderer unconditionally. if (R->isSubClassOf("RegisterClassLike") || R->isSubClassOf("RegisterOperand") || R->isSubClassOf("ValueType")) { - MIBuilder.addRenderer<CopyRenderer>(NodeName); + MIBuilder.addRenderer<CopyRenderer>(M, NodeName); return Error::success(); } } @@ -1358,7 +1358,7 @@ Error GlobalISelEmitter::importNamedNodeRenderer( // TODO: Remove this check and add CopyRenderer unconditionally. // TODO: Handle nodes with multiple results (provided they can reach here). if (isa<UnsetInit>(N.getLeafValue())) { - MIBuilder.addRenderer<CopyRenderer>(NodeName); + MIBuilder.addRenderer<CopyRenderer>(M, NodeName); return Error::success(); } @@ -1391,7 +1391,7 @@ Error GlobalISelEmitter::importLeafNodeRenderer( M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone, TempRegID); auto I = M.insertAction<BuildMIAction>( - InsertPt, M.allocateOutputInsnID(), + InsertPt, M.allocateOutputInsnID(), M, &Target.getInstruction(RK.getDef("IMPLICIT_DEF"))); auto &ImpDefBuilder = static_cast<BuildMIAction &>(**I); ImpDefBuilder.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true); @@ -1440,9 +1440,9 @@ Error GlobalISelEmitter::importXFormNodeRenderer( // If this is a TargetConstant, there won't be a corresponding // instruction to transform. Instead, this will refer directly to an // operand in an instruction's operand list. - MIBuilder.addRenderer<CustomOperandRenderer>(*XFormEquivRec, NodeName); + MIBuilder.addRenderer<CustomOperandRenderer>(M, *XFormEquivRec, NodeName); } else { - MIBuilder.addRenderer<CustomRenderer>(*XFormEquivRec, NodeName); + MIBuilder.addRenderer<CustomRenderer>(M, *XFormEquivRec, NodeName); } return Error::success(); @@ -1509,13 +1509,13 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( for (auto PhysOp : M.physoperands()) { InsertPt = M.insertAction<BuildMIAction>( - InsertPt, M.allocateOutputInsnID(), + InsertPt, M.allocateOutputInsnID(), M, &Target.getInstruction(RK.getDef("COPY"))); BuildMIAction &CopyToPhysRegMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get()); CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(Target, PhysOp.first, true); - CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysOp.first); + CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(M, PhysOp.first); } if (auto Error = importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Dst, @@ -1584,7 +1584,7 @@ GlobalISelEmitter::createInstructionRenderer(action_iterator InsertPt, if (Name == "COPY_TO_REGCLASS" || Name == "EXTRACT_SUBREG") DstI = &Target.getInstruction(RK.getDef("COPY")); - return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(), + return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(), M, DstI); } @@ -1603,7 +1603,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitDefRenderers( // CopyRenderer saves a StringRef, so cannot pass OpName itself - // let's use a string with an appropriate lifetime. StringRef PermanentRef = M.getOperandMatcher(OpName).getSymbolicName(); - DstMIBuilder.addRenderer<CopyRenderer>(PermanentRef); + DstMIBuilder.addRenderer<CopyRenderer>(M, PermanentRef); continue; } @@ -1723,7 +1723,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers( return InsertPt; } - DstMIBuilder.addRenderer<CopySubRegRenderer>(RegOperandName, SubIdx); + DstMIBuilder.addRenderer<CopySubRegRenderer>(M, RegOperandName, SubIdx); return InsertPt; } @@ -2216,14 +2216,15 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { OM0.addPredicate<RegisterBankOperandMatcher>(RC); auto &DstMIBuilder = - M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI); - DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name); - DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName()); + M.addAction<BuildMIAction>(M.allocateOutputInsnID(), M, &DstI); + DstMIBuilder.addRenderer<CopyRenderer>(M, DstIOperand.Name); + DstMIBuilder.addRenderer<CopyRenderer>(M, Dst.getName()); M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC); // Erase the root. unsigned RootInsnID = InsnMatcher.getInsnVarID(); - M.addAction<EraseInstAction>(RootInsnID); + if (M.tryEraseInsnID(RootInsnID)) + M.addAction<EraseInstAction>(RootInsnID); // We're done with this pattern! It's eligible for GISel emission; return // it. @@ -2306,7 +2307,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { // Erase the root. unsigned RootInsnID = InsnMatcher.getInsnVarID(); - M.addAction<EraseInstAction>(RootInsnID); + if (M.tryEraseInsnID(RootInsnID)) + M.addAction<EraseInstAction>(RootInsnID); // We're done with this pattern! It's eligible for GISel emission; return it. ++NumPatternImported; _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
