Index: include/llvm/CodeGen/GlobalISel/InstructionSelector.h =================================================================== --- include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -112,11 +112,13 @@ /// - 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 @@ template bool executeMatchTable( - TgtInstructionSelector &ISel, MatcherState &State, + TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, const MatcherInfoTy &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 Index: include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h =================================================================== --- include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -20,10 +20,11 @@ template bool InstructionSelector::executeMatchTable( - TgtInstructionSelector &ISel, MatcherState &State, + TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, const MatcherInfoTy &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 @@ 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 @@ 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 @@ 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"); } Index: lib/CodeGen/GlobalISel/InstructionSelector.cpp =================================================================== --- lib/CodeGen/GlobalISel/InstructionSelector.cpp +++ lib/CodeGen/GlobalISel/InstructionSelector.cpp @@ -35,155 +35,6 @@ 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 = *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, Index: test/TableGen/GlobalISelEmitter.td =================================================================== --- test/TableGen/GlobalISelEmitter.td +++ test/TableGen/GlobalISelEmitter.td @@ -80,10 +80,13 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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: } Index: utils/TableGen/GlobalISelEmitter.cpp =================================================================== --- utils/TableGen/GlobalISelEmitter.cpp +++ utils/TableGen/GlobalISelEmitter.cpp @@ -926,7 +926,7 @@ 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"; } @@ -962,7 +962,7 @@ 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"; @@ -1041,8 +1041,8 @@ } 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"; } }; @@ -1074,7 +1074,7 @@ void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule, unsigned RecycleInsnID) const override { - OS << " // " << *P.getSrcPattern() << " => " << *P.getDstPattern() + OS << " // " << *P.getSrcPattern() << " => " << *P.getDstPattern() << "\n"; } }; @@ -1121,7 +1121,7 @@ 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"; @@ -1130,14 +1130,14 @@ 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"; } } @@ -1147,13 +1147,13 @@ // 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"; } }; @@ -1167,7 +1167,7 @@ void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule, unsigned RecycleInsnID) const override { - OS << " GIR_ConstrainSelectedInstOperands, /*InsnID*/" << InsnID << ",\n"; + OS << " GIR_ConstrainSelectedInstOperands, /*InsnID*/" << InsnID << ",\n"; } }; @@ -1185,7 +1185,7 @@ 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"; } }; @@ -1268,15 +1268,6 @@ 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" << NumPatternEmitted - << "\\n\");\n" - << " if (executeMatchTable(*this, State, MatcherInfo, MatchTable" - << NumPatternEmitted << ", 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) @@ -1293,8 +1284,7 @@ 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. @@ -1333,19 +1323,17 @@ } } - OS << " const static int64_t EmitTable" << NumPatternEmitted << "[] = {\n"; for (const auto &MA : Actions) MA->emitCxxActionStmts(OS, *this, 0); - OS << " GIR_Done,\n" - << " };\n" - << " NewMIVector OutMIs;\n" - << " DEBUG(dbgs() << \"Processing EmitTable" << NumPatternEmitted + OS << " GIR_Done,\n" + << " };\n" + << " State.MIs.resize(1);\n" + << " DEBUG(dbgs() << \"Processing MatchTable" << NumPatternEmitted << "\\n\");\n" - << " executeEmitTable(OutMIs, State, EmitTable" << NumPatternEmitted - << ", TII, TRI, RBI);\n"; - - OS << " return true;\n"; - OS << " }\n\n"; + << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable" + << NumPatternEmitted << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n" + << " return true;\n" + << " }\n\n"; } bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const { @@ -2167,7 +2155,10 @@ "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);