[llvm] r307159 - [globalisel][tablegen] Finish fixing compile-time regressions by merging the matcher and emitter state machines.

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 5 07:50:18 PDT 2017


Author: dsanders
Date: Wed Jul  5 07:50:18 2017
New Revision: 307159

URL: http://llvm.org/viewvc/llvm-project?rev=307159&view=rev
Log:
[globalisel][tablegen] Finish fixing compile-time regressions by merging the matcher and emitter state machines.

Summary:
Also, made a few minor tweaks to shave off a little more cumulative memory consumption:
* All rules share a single NewMIs instead of constructing their own. Only one
  will end up using it.
* Use MIs.resize(1) instead of MIs.clear();MIs.push_back(I) and prevent
  GIM_RecordInsn from changing MIs[0].

Depends on D33764

Reviewers: rovka, vitalybuka, ab, t.p.northover, qcolombet, aditya_nandakumar

Reviewed By: ab

Subscribers: kristof.beyls, igorb, llvm-commits

Differential Revision: https://reviews.llvm.org/D33766

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
    llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
    llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
    llvm/trunk/test/TableGen/GlobalISelEmitter.td
    llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=307159&r1=307158&r2=307159&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h Wed Jul  5 07:50:18 2017
@@ -112,11 +112,13 @@ enum {
   /// - OpIdx - Operand index
   GIM_CheckIsMBB,
 
-  /// A successful match
-  GIM_Accept,
-};
+  /// Check if the specified operand is safe to fold into the current
+  /// instruction.
+  /// - InsnID - Instruction ID
+  GIM_CheckIsSafeToFold,
+
+  //=== Renderers ===
 
-enum {
   /// Mutate an instruction
   /// - NewInsnID - Instruction ID to define
   /// - OldInsnID - Instruction ID to mutate
@@ -225,15 +227,12 @@ protected:
   template <class TgtInstructionSelector, class PredicateBitset,
             class ComplexMatcherMemFn>
   bool executeMatchTable(
-      TgtInstructionSelector &ISel, MatcherState &State,
+      TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
       const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> &MatcherInfo,
-      const int64_t *MatchTable, MachineRegisterInfo &MRI,
-      const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
+      const int64_t *MatchTable, const TargetInstrInfo &TII,
+      MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+      const RegisterBankInfo &RBI,
       const PredicateBitset &AvailableFeatures) const;
-  void executeEmitTable(NewMIVector &OutMIs, MatcherState &State,
-                        const int64_t *EmitTable, const TargetInstrInfo &TII,
-                        const TargetRegisterInfo &TRI,
-                        const RegisterBankInfo &RBI) const;
 
   /// Constrain a register operand of an instruction \p I to a specified
   /// register class. This could involve inserting COPYs before (for uses) or

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h?rev=307159&r1=307158&r2=307159&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h Wed Jul  5 07:50:18 2017
@@ -20,10 +20,11 @@ namespace llvm {
 template <class TgtInstructionSelector, class PredicateBitset,
           class ComplexMatcherMemFn>
 bool InstructionSelector::executeMatchTable(
-    TgtInstructionSelector &ISel, MatcherState &State,
+    TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
     const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> &MatcherInfo,
-    const int64_t *MatchTable, MachineRegisterInfo &MRI,
-    const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
+    const int64_t *MatchTable, const TargetInstrInfo &TII,
+    MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+    const RegisterBankInfo &RBI,
     const PredicateBitset &AvailableFeatures) const {
   const int64_t *Command = MatchTable;
   while (true) {
@@ -33,6 +34,10 @@ bool InstructionSelector::executeMatchTa
       int64_t InsnID = *Command++;
       int64_t OpIdx = *Command++;
 
+      // As an optimisation we require that MIs[0] is always the root. Refuse
+      // any attempt to modify it.
+      assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
+
       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
       if (!MO.isReg()) {
         DEBUG(dbgs() << "Rejected (not a register)\n");
@@ -66,10 +71,12 @@ bool InstructionSelector::executeMatchTa
     case GIM_CheckOpcode: {
       int64_t InsnID = *Command++;
       int64_t Expected = *Command++;
-      DEBUG(dbgs() << "GIM_CheckOpcode(MIs[" << InsnID
-                   << "], ExpectedOpcode=" << Expected << ")\n");
+
+      unsigned Opcode = State.MIs[InsnID]->getOpcode();
+      DEBUG(dbgs() << "GIM_CheckOpcode(MIs[" << InsnID << "], ExpectedOpcode="
+                   << Expected << ") // Got=" << Opcode << "\n");
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
-      if (State.MIs[InsnID]->getOpcode() != Expected)
+      if (Opcode != Expected)
         return false;
       break;
     }
@@ -160,9 +167,151 @@ bool InstructionSelector::executeMatchTa
       break;
     }
 
-    case GIM_Accept:
-      DEBUG(dbgs() << "GIM_Accept\n");
+    case GIM_CheckIsSafeToFold: {
+      int64_t InsnID = *Command++;
+      DEBUG(dbgs() << "GIM_CheckIsSafeToFold(MIs[" << InsnID << "])\n");
+      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+      if (!isObviouslySafeToFold(*State.MIs[InsnID]))
+        return false;
+      break;
+    }
+
+    case GIR_MutateOpcode: {
+      int64_t OldInsnID = *Command++;
+      int64_t NewInsnID = *Command++;
+      int64_t NewOpcode = *Command++;
+      assert((size_t)NewInsnID == OutMIs.size() &&
+             "Expected to store MIs in order");
+      OutMIs.push_back(
+          MachineInstrBuilder(*State.MIs[OldInsnID]->getParent()->getParent(),
+                              State.MIs[OldInsnID]));
+      OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
+      DEBUG(dbgs() << "GIR_MutateOpcode(OutMIs[" << NewInsnID << "], MIs["
+                   << OldInsnID << "], " << NewOpcode << ")\n");
+      break;
+    }
+    case GIR_BuildMI: {
+      int64_t InsnID = *Command++;
+      int64_t Opcode = *Command++;
+      assert((size_t)InsnID == OutMIs.size() &&
+             "Expected to store MIs in order");
+      OutMIs.push_back(BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
+                               State.MIs[0]->getDebugLoc(), TII.get(Opcode)));
+      DEBUG(dbgs() << "GIR_BuildMI(OutMIs[" << InsnID << "], " << Opcode
+                   << ")\n");
+      break;
+    }
+
+    case GIR_Copy: {
+      int64_t NewInsnID = *Command++;
+      int64_t OldInsnID = *Command++;
+      int64_t OpIdx = *Command++;
+      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
+      OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
+      DEBUG(dbgs() << "GIR_Copy(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID
+                   << "], " << OpIdx << ")\n");
+      break;
+    }
+    case GIR_CopySubReg: {
+      int64_t NewInsnID = *Command++;
+      int64_t OldInsnID = *Command++;
+      int64_t OpIdx = *Command++;
+      int64_t SubRegIdx = *Command++;
+      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
+      OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
+                               0, SubRegIdx);
+      DEBUG(dbgs() << "GIR_CopySubReg(OutMIs[" << NewInsnID << "], MIs["
+                   << OldInsnID << "], " << OpIdx << ", " << SubRegIdx
+                   << ")\n");
+      break;
+    }
+    case GIR_AddImplicitDef: {
+      int64_t InsnID = *Command++;
+      int64_t RegNum = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
+      DEBUG(dbgs() << "GIR_AddImplicitDef(OutMIs[" << InsnID << "], " << RegNum
+                   << ")\n");
+      break;
+    }
+    case GIR_AddImplicitUse: {
+      int64_t InsnID = *Command++;
+      int64_t RegNum = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
+      DEBUG(dbgs() << "GIR_AddImplicitUse(OutMIs[" << InsnID << "], " << RegNum
+                   << ")\n");
+      break;
+    }
+    case GIR_AddRegister: {
+      int64_t InsnID = *Command++;
+      int64_t RegNum = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      OutMIs[InsnID].addReg(RegNum);
+      DEBUG(dbgs() << "GIR_AddRegister(OutMIs[" << InsnID << "], " << RegNum
+                   << ")\n");
+      break;
+    }
+    case GIR_AddImm: {
+      int64_t InsnID = *Command++;
+      int64_t Imm = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      OutMIs[InsnID].addImm(Imm);
+      DEBUG(dbgs() << "GIR_AddImm(OutMIs[" << InsnID << "], " << Imm << ")\n");
+      break;
+    }
+    case GIR_ComplexRenderer: {
+      int64_t InsnID = *Command++;
+      int64_t RendererID = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      State.Renderers[RendererID](OutMIs[InsnID]);
+      DEBUG(dbgs() << "GIR_ComplexRenderer(OutMIs[" << InsnID << "], "
+                   << RendererID << ")\n");
+      break;
+    }
+
+    case GIR_ConstrainOperandRC: {
+      int64_t InsnID = *Command++;
+      int64_t OpIdx = *Command++;
+      int64_t RCEnum = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
+                                    *TRI.getRegClass(RCEnum), TII, TRI, RBI);
+      DEBUG(dbgs() << "GIR_ConstrainOperandRC(OutMIs[" << InsnID << "], "
+                   << OpIdx << ", " << RCEnum << ")\n");
+      break;
+    }
+    case GIR_ConstrainSelectedInstOperands: {
+      int64_t InsnID = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
+                                       RBI);
+      DEBUG(dbgs() << "GIR_ConstrainSelectedInstOperands(OutMIs[" << InsnID
+                   << "])\n");
+      break;
+    }
+    case GIR_MergeMemOperands: {
+      int64_t InsnID = *Command++;
+      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
+      for (const auto *FromMI : State.MIs)
+        for (const auto &MMO : FromMI->memoperands())
+          OutMIs[InsnID].addMemOperand(MMO);
+      DEBUG(dbgs() << "GIR_MergeMemOperands(OutMIs[" << InsnID << "])\n");
+      break;
+    }
+    case GIR_EraseFromParent: {
+      int64_t InsnID = *Command++;
+      assert(State.MIs[InsnID] &&
+             "Attempted to erase an undefined instruction");
+      State.MIs[InsnID]->eraseFromParent();
+      DEBUG(dbgs() << "GIR_EraseFromParent(MIs[" << InsnID << "])\n");
+      break;
+    }
+
+    case GIR_Done:
+      DEBUG(dbgs() << "GIR_Done");
       return true;
+
     default:
       llvm_unreachable("Unexpected command");
     }

Modified: llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp?rev=307159&r1=307158&r2=307159&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp Wed Jul  5 07:50:18 2017
@@ -35,155 +35,6 @@ InstructionSelector::MatcherState::Match
 
 InstructionSelector::InstructionSelector() = default;
 
-void InstructionSelector::executeEmitTable(NewMIVector &OutMIs,
-                                           MatcherState &State,
-                                           const int64_t *EmitTable,
-                                           const TargetInstrInfo &TII,
-                                           const TargetRegisterInfo &TRI,
-                                           const RegisterBankInfo &RBI) const {
-  const int64_t *Command = EmitTable;
-  while (true) {
-    switch (*Command++) {
-    case GIR_MutateOpcode: {
-      int64_t OldInsnID = *Command++;
-      int64_t NewInsnID = *Command++;
-      int64_t NewOpcode = *Command++;
-      assert((size_t)NewInsnID == OutMIs.size() &&
-             "Expected to store MIs in order");
-      OutMIs.push_back(
-          MachineInstrBuilder(*State.MIs[OldInsnID]->getParent()->getParent(),
-                              State.MIs[OldInsnID]));
-      OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
-      DEBUG(dbgs() << "GIR_MutateOpcode(OutMIs[" << NewInsnID << "], MIs["
-                   << OldInsnID << "], " << NewOpcode << ")\n");
-      break;
-    }
-    case GIR_BuildMI: {
-      int64_t InsnID LLVM_ATTRIBUTE_UNUSED = *Command++;
-      int64_t Opcode = *Command++;
-      assert((size_t)InsnID == OutMIs.size() &&
-             "Expected to store MIs in order");
-      OutMIs.push_back(BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
-                               State.MIs[0]->getDebugLoc(), TII.get(Opcode)));
-      DEBUG(dbgs() << "GIR_BuildMI(OutMIs[" << InsnID << "], " << Opcode
-                   << ")\n");
-      break;
-    }
-
-    case GIR_Copy: {
-      int64_t NewInsnID = *Command++;
-      int64_t OldInsnID = *Command++;
-      int64_t OpIdx = *Command++;
-      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
-      OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
-      DEBUG(dbgs() << "GIR_Copy(OutMIs[" << NewInsnID << "], MIs[" << OldInsnID
-                   << "], " << OpIdx << ")\n");
-      break;
-    }
-    case GIR_CopySubReg: {
-      int64_t NewInsnID = *Command++;
-      int64_t OldInsnID = *Command++;
-      int64_t OpIdx = *Command++;
-      int64_t SubRegIdx = *Command++;
-      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
-      OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
-                               0, SubRegIdx);
-      DEBUG(dbgs() << "GIR_CopySubReg(OutMIs[" << NewInsnID << "], MIs["
-                   << OldInsnID << "], " << OpIdx << ", " << SubRegIdx
-                   << ")\n");
-      break;
-    }
-    case GIR_AddImplicitDef: {
-      int64_t InsnID = *Command++;
-      int64_t RegNum = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
-      DEBUG(dbgs() << "GIR_AddImplicitDef(OutMIs[" << InsnID << "], " << RegNum
-                   << ")\n");
-      break;
-    }
-    case GIR_AddImplicitUse: {
-      int64_t InsnID = *Command++;
-      int64_t RegNum = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
-      DEBUG(dbgs() << "GIR_AddImplicitUse(OutMIs[" << InsnID << "], " << RegNum
-                   << ")\n");
-      break;
-    }
-    case GIR_AddRegister: {
-      int64_t InsnID = *Command++;
-      int64_t RegNum = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      OutMIs[InsnID].addReg(RegNum);
-      DEBUG(dbgs() << "GIR_AddRegister(OutMIs[" << InsnID << "], " << RegNum
-                   << ")\n");
-      break;
-    }
-    case GIR_AddImm: {
-      int64_t InsnID = *Command++;
-      int64_t Imm = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      OutMIs[InsnID].addImm(Imm);
-      DEBUG(dbgs() << "GIR_AddImm(OutMIs[" << InsnID << "], " << Imm << ")\n");
-      break;
-    }
-    case GIR_ComplexRenderer: {
-      int64_t InsnID = *Command++;
-      int64_t RendererID = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      State.Renderers[RendererID](OutMIs[InsnID]);
-      DEBUG(dbgs() << "GIR_ComplexRenderer(OutMIs[" << InsnID << "], "
-                   << RendererID << ")\n");
-      break;
-    }
-
-    case GIR_ConstrainOperandRC: {
-      int64_t InsnID = *Command++;
-      int64_t OpIdx = *Command++;
-      int64_t RCEnum = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
-                                    *TRI.getRegClass(RCEnum), TII, TRI, RBI);
-      DEBUG(dbgs() << "GIR_ConstrainOperandRC(OutMIs[" << InsnID << "], "
-                   << OpIdx << ", " << RCEnum << ")\n");
-      break;
-    }
-    case GIR_ConstrainSelectedInstOperands: {
-      int64_t InsnID = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
-                                       RBI);
-      DEBUG(dbgs() << "GIR_ConstrainSelectedInstOperands(OutMIs[" << InsnID
-                   << "])\n");
-      break;
-    }
-    case GIR_MergeMemOperands: {
-      int64_t InsnID = *Command++;
-      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
-      for (const auto *FromMI : State.MIs)
-        for (const auto &MMO : FromMI->memoperands())
-          OutMIs[InsnID].addMemOperand(MMO);
-      DEBUG(dbgs() << "GIR_MergeMemOperands(OutMIs[" << InsnID << "])\n");
-      break;
-    }
-    case GIR_EraseFromParent: {
-      int64_t InsnID = *Command++;
-      assert(State.MIs[InsnID] && "Attempted to erase an undefined instruction");
-      State.MIs[InsnID]->eraseFromParent();
-      DEBUG(dbgs() << "GIR_EraseFromParent(MIs[" << InsnID << "])\n");
-      break;
-    }
-
-    case GIR_Done:
-      DEBUG(dbgs() << "GIR_Done");
-      return;
-    default:
-      llvm_unreachable("Unexpected command");
-    }
-  }
-}
-
 bool InstructionSelector::constrainOperandRegToRegClass(
     MachineInstr &I, unsigned OpIdx, const TargetRegisterClass &RC,
     const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,

Modified: llvm/trunk/test/TableGen/GlobalISelEmitter.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=307159&r1=307158&r2=307159&view=diff
==============================================================================
--- llvm/trunk/test/TableGen/GlobalISelEmitter.td (original)
+++ llvm/trunk/test/TableGen/GlobalISelEmitter.td Wed Jul  5 07:50:18 2017
@@ -80,10 +80,13 @@ def HasC : Predicate<"Subtarget->hasC()"
 // CHECK-NEXT:  }
 
 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
-// CHECK: MachineFunction &MF = *I.getParent()->getParent();
-// CHECK: MachineRegisterInfo &MRI = MF.getRegInfo();
-// CHECK: AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);
-// CHECK: const PredicateBitset AvailableFeatures = getAvailableFeatures();
+// CHECK-NEXT: MachineFunction &MF = *I.getParent()->getParent();
+// CHECK-NEXT: MachineRegisterInfo &MRI = MF.getRegInfo();
+// CHECK:      AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);
+// CHECK-NEXT: const PredicateBitset AvailableFeatures = getAvailableFeatures();
+// CHECK-NEXT: NewMIVector OutMIs;
+// CHECK-NEXT: State.MIs.clear();
+// CHECK-NEXT: State.MIs.push_back(&I);
 
 //===- Test a pattern with multiple ComplexPattern operands. --------------===//
 //
@@ -103,27 +106,20 @@ def HasC : Predicate<"Subtarget->hasC()"
 // CHECK-NEXT:    // MIs[0] src3
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (select:i32 GPR32:i32:$src1, complex:i32:$src2, complex:i32:$src3) => (INSN2:i32 GPR32:i32:$src1, complex:i32:$src3, complex:i32:$src2)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
+// CHECK-NEXT:    GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable0\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable0, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable0[] = {
-// CHECK-NEXT:      // (select:i32 GPR32:i32:$src1, complex:i32:$src2, complex:i32:$src3) => (INSN2:i32 GPR32:i32:$src1, complex:i32:$src3, complex:i32:$src2)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
-// CHECK-NEXT:      GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable0\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable0, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable0, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -146,21 +142,14 @@ def : Pat<(select GPR32:$src1, complex:$
 // CHECK-NEXT:    // MIs[0] src2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (add:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (ADD:i32 GPR32:i32:$src1, GPR32:i32:$src2)
+// CHECK-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/ 0, /*Opcode*/MyTarget::ADD,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable1\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable1, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable1[] = {
-// CHECK-NEXT:      // (add:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (ADD:i32 GPR32:i32:$src1, GPR32:i32:$src2)
-// CHECK-NEXT:      GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/ 0, /*Opcode*/MyTarget::ADD,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable1\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable1, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable1, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -192,29 +181,21 @@ def ADD : I<(outs GPR32:$dst), (ins GPR3
 // CHECK-NEXT:    // MIs[0] src3
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/1,
+// CHECK-NEXT:    // (mul:i32 (add:i32 GPR32:i32:$src1, GPR32:i32:$src2), GPR32:i32:$src3)  =>  (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable2\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable2, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    if (!isObviouslySafeToFold(*State.MIs[1]))
-// CHECK-NEXT:      return false;
-// CHECK-NEXT:    const static int64_t EmitTable2[] = {
-// CHECK-NEXT:      // (mul:i32 (add:i32 GPR32:i32:$src1, GPR32:i32:$src2), GPR32:i32:$src3)  =>  (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable2\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable2, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable2, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -242,29 +223,21 @@ def ADD : I<(outs GPR32:$dst), (ins GPR3
 // CHECK-NEXT:    // MIs[1] src2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/1,
+// CHECK-NEXT:    // (mul:i32 GPR32:i32:$src3, (add:i32 GPR32:i32:$src1, GPR32:i32:$src2))  =>  (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable3\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable3, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    if (!isObviouslySafeToFold(*State.MIs[1]))
-// CHECK-NEXT:      return false;
-// CHECK-NEXT:    const static int64_t EmitTable3[] = {
-// CHECK-NEXT:      // (mul:i32 GPR32:i32:$src3, (add:i32 GPR32:i32:$src1, GPR32:i32:$src2))  =>  (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable3\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable3, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable3, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -288,26 +261,19 @@ def MULADD : I<(outs GPR32:$dst), (ins G
 // CHECK-NEXT:    // MIs[0] src2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (mul:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (MUL:i32 GPR32:i32:$src2, GPR32:i32:$src1)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable4\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable4, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable4[] = {
-// CHECK-NEXT:      // (mul:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (MUL:i32 GPR32:i32:$src2, GPR32:i32:$src1)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable4\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable4, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable4, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -350,32 +316,23 @@ def MUL : I<(outs GPR32:$dst), (ins GPR3
 // CHECK-NEXT:    // MIs[2] src4
 // CHECK-NEXT:    GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/1,
+// CHECK-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/2,
+// CHECK-NEXT:    // (sub:i32 (sub:i32 GPR32:i32:$src1, GPR32:i32:$src2), (sub:i32 GPR32:i32:$src3, GPR32:i32:$src4)) => (INSNBOB:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3, GPR32:i32:$src4)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSNBOB,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/1, // src3
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // src4
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable5\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable5, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    if (!isObviouslySafeToFold(*State.MIs[1]))
-// CHECK-NEXT:      return false;
-// CHECK-NEXT:    if (!isObviouslySafeToFold(*State.MIs[2]))
-// CHECK-NEXT:      return false;
-// CHECK-NEXT:    const static int64_t EmitTable5[] = {
-// CHECK-NEXT:      // (sub:i32 (sub:i32 GPR32:i32:$src1, GPR32:i32:$src2), (sub:i32 GPR32:i32:$src3, GPR32:i32:$src4)) => (INSNBOB:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3, GPR32:i32:$src4)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSNBOB,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/1, // src3
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // src4
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable5\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable5, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable5, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -399,26 +356,19 @@ def INSNBOB : I<(outs GPR32:$dst), (ins
 // CHECK-NEXT:    // MIs[0] src2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (sub:i32 GPR32:i32:$src1, complex:i32:$src2) => (INSN1:i32 GPR32:i32:$src1, complex:i32:$src2)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable6\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable6, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable6[] = {
-// CHECK-NEXT:      // (sub:i32 GPR32:i32:$src1, complex:i32:$src2) => (INSN1:i32 GPR32:i32:$src1, complex:i32:$src2)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable6\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable6, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable6, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -440,26 +390,19 @@ def : Pat<(sub GPR32:$src1, complex:$src
 // CHECK-NEXT:    // MIs[0] Operand 2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -2
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (xor:i32 GPR32:i32:$src1, -2:i32) => (XORI:i32 GPR32:i32:$src1)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORI,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable7\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable7, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable7[] = {
-// CHECK-NEXT:      // (xor:i32 GPR32:i32:$src1, -2:i32) => (XORI:i32 GPR32:i32:$src1)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORI,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable7\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable7, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable7, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -482,26 +425,19 @@ def XORI : I<(outs GPR32:$dst), (ins m1:
 // CHECK-NEXT:    // MIs[0] Operand 2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -3
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (xor:i32 GPR32:i32:$src1, -3:i32) => (XOR:i32 GPR32:i32:$src1)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XOR,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable8\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable8, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable8[] = {
-// CHECK-NEXT:      // (xor:i32 GPR32:i32:$src1, -3:i32) => (XOR:i32 GPR32:i32:$src1)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XOR,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable8\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable8, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable8, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -524,27 +460,20 @@ def XOR : I<(outs GPR32:$dst), (ins Z:$s
 // CHECK-NEXT:    // MIs[0] Operand 2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -4
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (xor:i32 GPR32:i32:$src1, -4:i32) => (XORlike:i32 GPR32:i32:$src1)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORlike,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
+// CHECK-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable9\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable9, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable9[] = {
-// CHECK-NEXT:      // (xor:i32 GPR32:i32:$src1, -4:i32) => (XORlike:i32 GPR32:i32:$src1)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORlike,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
-// CHECK-NEXT:      GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable9\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable9, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable9, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -567,28 +496,21 @@ def XORlike : I<(outs GPR32:$dst), (ins
 // CHECK-NEXT:    // MIs[0] Operand 2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -5,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (xor:i32 GPR32:i32:$src1, -5:i32) => (XORManyDefaults:i32 GPR32:i32:$src1)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORManyDefaults,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
+// CHECK-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
+// CHECK-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable10\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable10, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable10[] = {
-// CHECK-NEXT:      // (xor:i32 GPR32:i32:$src1, -5:i32) => (XORManyDefaults:i32 GPR32:i32:$src1)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORManyDefaults,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
-// CHECK-NEXT:      GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
-// CHECK-NEXT:      GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable10\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable10, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable10, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -613,26 +535,19 @@ def XORManyDefaults : I<(outs GPR32:$dst
 // CHECK-NEXT:    // MIs[0] Operand 2
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -1,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (xor:i32 GPR32:i32:$Wm, -1:i32) => (ORN:i32 R0:i32, GPR32:i32:$Wm)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::ORN,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // Wm
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable11\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable11, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable11[] = {
-// CHECK-NEXT:      // (xor:i32 GPR32:i32:$Wm, -1:i32) => (ORN:i32 R0:i32, GPR32:i32:$Wm)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::ORN,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // Wm
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable11\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable11, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable11, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -651,21 +566,14 @@ def : Pat<(not GPR32:$Wm), (ORN R0, GPR3
 // CHECK-NEXT:    // MIs[0] src1
 // CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
 // CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (bitconvert:i32 FPR32:f32:$src1) => (COPY_TO_REGCLASS:i32 FPR32:f32:$src1, GPR32:i32)
+// CHECK-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/ 0, /*Opcode*/TargetOpcode::COPY,
+// CHECK-NEXT:    GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, /*RC GPR32*/ 1,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable12\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable12, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable12[] = {
-// CHECK-NEXT:      // (bitconvert:i32 FPR32:f32:$src1) => (COPY_TO_REGCLASS:i32 FPR32:f32:$src1, GPR32:i32)
-// CHECK-NEXT:      GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/ 0, /*Opcode*/TargetOpcode::COPY,
-// CHECK-NEXT:      GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, /*RC GPR32*/ 1,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable12\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable12, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable12, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -682,24 +590,17 @@ def : Pat<(i32 (bitconvert FPR32:$src1))
 // CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
 // CHECK-NEXT:    // MIs[0] Operand 1
 // CHECK-NEXT:    GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // 1:i32  =>  (MOV1:i32)
+// CHECK-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1,
+// CHECK-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
+// CHECK-NEXT:    GIR_MergeMemOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable13\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable13, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable13[] = {
-// CHECK-NEXT:      // 1:i32  =>  (MOV1:i32)
-// CHECK-NEXT:      GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1,
-// CHECK-NEXT:      GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
-// CHECK-NEXT:      GIR_MergeMemOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_EraseFromParent, /*InsnID*/0,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable13\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable13, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable13, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 
@@ -712,21 +613,14 @@ def MOV1 : I<(outs GPR32:$dst), (ins), [
 // CHECK-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR,
 // CHECK-NEXT:    // MIs[0] target
 // CHECK-NEXT:    GIM_CheckIsMBB, /*MI*/0, /*Op*/0,
-// CHECK-NEXT:    GIM_Accept,
+// CHECK-NEXT:    // (br (bb:Other):$target) => (BR (bb:Other):$target)
+// CHECK-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/ 0, /*Opcode*/MyTarget::BR,
+// CHECK-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
+// CHECK-NEXT:    GIR_Done,
 // CHECK-NEXT:  };
-// CHECK-NEXT:  MIs.clear();
-// CHECK-NEXT:  MIs.push_back(&I);
+// CHECK-NEXT:  MIs.resize(1);
 // CHECK-NEXT:  DEBUG(dbgs() << "Processing MatchTable14\n");
-// CHECK-NEXT:  if (executeMatchTable(*this, State, MatcherInfo, MatchTable14, MRI, TRI, RBI, AvailableFeatures)) {
-// CHECK-NEXT:    const static int64_t EmitTable14[] = {
-// CHECK-NEXT:      // (br (bb:Other):$target) => (BR (bb:Other):$target)
-// CHECK-NEXT:      GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/ 0, /*Opcode*/MyTarget::BR,
-// CHECK-NEXT:      GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
-// CHECK-NEXT:      GIR_Done,
-// CHECK-NEXT:    };
-// CHECK-NEXT:    NewMIVector OutMIs;
-// CHECK-NEXT:    DEBUG(dbgs() << "Processing EmitTable14\n");
-// CHECK-NEXT:    executeEmitTable(OutMIs, State, EmitTable14, TII, TRI, RBI);
+// CHECK-NEXT:  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable14, TII, MRI, TRI, RBI, AvailableFeatures)) {
 // CHECK-NEXT:    return true;
 // CHECK-NEXT:  }
 

Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=307159&r1=307158&r2=307159&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Wed Jul  5 07:50:18 2017
@@ -928,7 +928,7 @@ public:
   void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
     const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
     unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
-    OS << "      GIR_Copy, /*NewInsnID*/" << NewInsnID << ", /*OldInsnID*/"
+    OS << "    GIR_Copy, /*NewInsnID*/" << NewInsnID << ", /*OldInsnID*/"
        << OldInsnVarID << ", /*OpIdx*/" << Operand.getOperandIndex() << ", // "
        << SymbolicName << "\n";
   }
@@ -964,7 +964,7 @@ public:
   void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
     const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
     unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
-    OS << "      GIR_CopySubReg, /*NewInsnID*/" << NewInsnID
+    OS << "    GIR_CopySubReg, /*NewInsnID*/" << NewInsnID
        << ", /*OldInsnID*/" << OldInsnVarID << ", /*OpIdx*/"
        << Operand.getOperandIndex() << ", /*SubRegIdx*/" << SubReg->EnumValue
        << ", // " << SymbolicName << "\n";
@@ -1043,8 +1043,8 @@ public:
   }
 
   void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
-    OS << "      GIR_ComplexRenderer, /*InsnID*/" << InsnID
-       << ", /*RendererID*/" << RendererID << ",\n";
+    OS << "    GIR_ComplexRenderer, /*InsnID*/" << InsnID << ", /*RendererID*/"
+       << RendererID << ",\n";
   }
 };
 
@@ -1076,7 +1076,7 @@ public:
 
   void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
                           unsigned RecycleInsnID) const override {
-    OS << "      // " << *P.getSrcPattern() << "  =>  " << *P.getDstPattern()
+    OS << "    // " << *P.getSrcPattern() << "  =>  " << *P.getDstPattern()
        << "\n";
   }
 };
@@ -1123,7 +1123,7 @@ public:
   void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
                           unsigned RecycleInsnID) const override {
     if (canMutate()) {
-      OS << "      GIR_MutateOpcode, /*InsnID*/" << InsnID
+      OS << "    GIR_MutateOpcode, /*InsnID*/" << InsnID
          << ", /*RecycleInsnID*/ " << RecycleInsnID << ", /*Opcode*/"
          << I->Namespace << "::" << I->TheDef->getName() << ",\n";
 
@@ -1132,14 +1132,14 @@ public:
           auto Namespace = Def->getValue("Namespace")
                                ? Def->getValueAsString("Namespace")
                                : "";
-          OS << "      GIR_AddImplicitDef, " << InsnID << ", " << Namespace
+          OS << "    GIR_AddImplicitDef, " << InsnID << ", " << Namespace
              << "::" << Def->getName() << ",\n";
         }
         for (auto Use : I->ImplicitUses) {
           auto Namespace = Use->getValue("Namespace")
                                ? Use->getValueAsString("Namespace")
                                : "";
-          OS << "      GIR_AddImplicitUse, " << InsnID << ", " << Namespace
+          OS << "    GIR_AddImplicitUse, " << InsnID << ", " << Namespace
              << "::" << Use->getName() << ",\n";
         }
       }
@@ -1149,13 +1149,13 @@ public:
     // TODO: Simple permutation looks like it could be almost as common as
     //       mutation due to commutative operations.
 
-    OS << "      GIR_BuildMI, /*InsnID*/" << InsnID << ", /*Opcode*/"
+    OS << "    GIR_BuildMI, /*InsnID*/" << InsnID << ", /*Opcode*/"
        << I->Namespace << "::" << I->TheDef->getName() << ",\n";
     for (const auto &Renderer : OperandRenderers)
       Renderer->emitCxxRenderStmts(OS, Rule);
 
-    OS << "      GIR_MergeMemOperands, /*InsnID*/" << InsnID << ",\n"
-       << "      GIR_EraseFromParent, /*InsnID*/" << RecycleInsnID << ",\n";
+    OS << "    GIR_MergeMemOperands, /*InsnID*/" << InsnID << ",\n"
+       << "    GIR_EraseFromParent, /*InsnID*/" << RecycleInsnID << ",\n";
   }
 };
 
@@ -1169,7 +1169,7 @@ public:
 
   void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
                           unsigned RecycleInsnID) const override {
-    OS << "      GIR_ConstrainSelectedInstOperands, /*InsnID*/" << InsnID << ",\n";
+    OS << "    GIR_ConstrainSelectedInstOperands, /*InsnID*/" << InsnID << ",\n";
   }
 };
 
@@ -1187,7 +1187,7 @@ public:
 
   void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
                           unsigned RecycleInsnID) const override {
-    OS << "      GIR_ConstrainOperandRC, /*InsnID*/" << InsnID << ", /*Op*/"
+    OS << "    GIR_ConstrainOperandRC, /*InsnID*/" << InsnID << ", /*Op*/"
        << OpIdx << ", /*RC " << RC.getName() << "*/ " << RC.EnumValue << ",\n";
   }
 };
@@ -1264,21 +1264,11 @@ void RuleMatcher::emit(raw_ostream &OS)
        << ",\n";
   }
 
-
   emitCxxCaptureStmts(OS);
 
   Matchers.front()->emitCxxPredicateExpr(OS, *this,
                                          getInsnVarID(*Matchers.front()));
 
-  OS << "    GIM_Accept,\n"
-     << "  };\n"
-     << "  State.MIs.clear();\n"
-     << "  State.MIs.push_back(&I);\n"
-     << "  DEBUG(dbgs() << \"Processing MatchTable" << CurrentMatchTableID
-     << "\\n\");\n"
-     << "  if (executeMatchTable(*this, State, MatcherInfo, MatchTable"
-     << CurrentMatchTableID << ", MRI, TRI, RBI, AvailableFeatures)) {\n";
-
   // We must also check if it's safe to fold the matched instructions.
   if (InsnVariableIDs.size() >= 2) {
     // Invert the map to create stable ordering (by var names)
@@ -1295,8 +1285,7 @@ void RuleMatcher::emit(raw_ostream &OS)
 
     for (const auto &InsnID : InsnIDs) {
       // Reject the difficult cases until we have a more accurate check.
-      OS << "    if (!isObviouslySafeToFold(*State.MIs[" << InsnID << "]))\n"
-         << "      return false;\n";
+      OS << "    GIM_CheckIsSafeToFold, /*InsnID*/" << InsnID << ",\n";
 
       // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
       //        account for unsafe cases.
@@ -1335,19 +1324,17 @@ void RuleMatcher::emit(raw_ostream &OS)
     }
   }
 
-  OS << "    const static int64_t EmitTable" << CurrentMatchTableID << "[] = {\n";
   for (const auto &MA : Actions)
     MA->emitCxxActionStmts(OS, *this, 0);
-  OS << "      GIR_Done,\n"
-     << "    };\n"
-     << "    NewMIVector OutMIs;\n"
-     << "    DEBUG(dbgs() << \"Processing EmitTable" << CurrentMatchTableID
+  OS << "    GIR_Done,\n"
+     << "  };\n"
+     << "  State.MIs.resize(1);\n"
+     << "  DEBUG(dbgs() << \"Processing MatchTable" << CurrentMatchTableID
      << "\\n\");\n"
-     << "    executeEmitTable(OutMIs, State, EmitTable" << CurrentMatchTableID
-     << ", TII, TRI, RBI);\n";
-
-  OS << "    return true;\n";
-  OS << "  }\n\n";
+     << "  if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable"
+     << CurrentMatchTableID << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n"
+     << "    return true;\n"
+     << "  }\n\n";
 }
 
 bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
@@ -2169,7 +2156,10 @@ void GlobalISelEmitter::run(raw_ostream
         "than per-insn.\n"
      << "  AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
         "&MF);\n"
-     << "  const PredicateBitset AvailableFeatures = getAvailableFeatures();\n";
+     << "  const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
+     << "  NewMIVector OutMIs;\n"
+     << "  State.MIs.clear();\n"
+     << "  State.MIs.push_back(&I);\n\n";
 
   for (auto &Rule : Rules) {
     Rule.emit(OS);




More information about the llvm-commits mailing list