Index: include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h =================================================================== --- include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -58,7 +58,6 @@ // 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]"); - (void)NewInsnID; MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); if (!MO.isReg()) { @@ -74,9 +73,14 @@ break; } - assert((size_t)NewInsnID == State.MIs.size() && - "Expected to store MIs in order"); - State.MIs.push_back(MRI.getVRegDef(MO.getReg())); + MachineInstr *NewMI = MRI.getVRegDef(MO.getReg()); + if ((size_t)NewInsnID < State.MIs.size()) + State.MIs[NewInsnID] = NewMI; + else { + assert((size_t)NewInsnID == State.MIs.size() && + "Expected to store MIs in order"); + State.MIs.push_back(NewMI); + } DEBUG(dbgs() << CurrentIdx << ": MIs[" << NewInsnID << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx << ")\n"); @@ -213,7 +217,8 @@ assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); MachineOperand &OM = State.MIs[InsnID]->getOperand(OpIdx); if (!OM.isIntrinsicID() || OM.getIntrinsicID() != Value) - return false; + if (handleReject() == RejectAndGiveUp) + return false; break; } case GIM_CheckIsMBB: { Index: test/TableGen/GlobalISelEmitter.td =================================================================== --- test/TableGen/GlobalISelEmitter.td +++ test/TableGen/GlobalISelEmitter.td @@ -96,7 +96,7 @@ // // CHECK-LABEL: MatchTable0[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT, // CHECK-NEXT: // MIs[0] dst @@ -121,14 +121,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable0\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable0, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 0: @[[LABEL]] def INSN3 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, GPR32:$src3, complex:$src4, complex:$src5), []>; @@ -138,8 +131,7 @@ //===- Test a pattern with multiple ComplexPattern operands. --------------===// // -// CHECK-LABEL: MatchTable1[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 1*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4, // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1] // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/4, @@ -180,14 +172,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable1\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable1, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 1: @[[LABEL]] def : GINodeEquiv; def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>; @@ -196,8 +181,7 @@ //===- Test a simple pattern with regclass operands. ----------------------===// -// CHECK-LABEL: MatchTable2[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 2*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD, // CHECK-NEXT: // MIs[0] dst @@ -213,14 +197,7 @@ // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable2\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable2, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 2: @[[LABEL]] def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>; @@ -228,8 +205,7 @@ //===- Test a simple pattern with an intrinsic. ---------------------------===// // -// CHECK-LABEL: MatchTable3[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 3*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC, // CHECK-NEXT: // MIs[0] dst @@ -249,22 +225,14 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable3\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable3, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 3: @[[LABEL]] def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1), [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>; //===- Test a nested instruction match. -----------------------------------===// -// CHECK-LABEL: MatchTable4[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 4*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA, // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] @@ -298,18 +266,10 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable4\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable4, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 4: @[[LABEL]] // We also get a second rule by commutativity. -// CHECK-LABEL: MatchTable5[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 5*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA, // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, @@ -343,14 +303,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable5\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable5, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 5: @[[LABEL]] def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3), [(set GPR32:$dst, @@ -359,8 +312,7 @@ //===- Test another simple pattern with regclass operands. ----------------===// -// CHECK-LABEL: MatchTable6[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 6*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA_HasB_HasC, // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL, @@ -382,14 +334,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable6\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable6, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 6: @[[LABEL]] def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1), [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>, @@ -397,8 +342,7 @@ //===- Test a more complex multi-instruction match. -----------------------===// -// CHECK-LABEL: MatchTable7[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 7*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA, // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] @@ -444,14 +388,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable7\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable7, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 7: @[[LABEL]] def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4), [(set GPR32:$dst, @@ -461,8 +398,7 @@ //===- Test a pattern with ComplexPattern operands. -----------------------===// // -// CHECK-LABEL: MatchTable8[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 8*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB, // CHECK-NEXT: // MIs[0] dst @@ -483,14 +419,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable8\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable8, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 8: @[[LABEL]] def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>; def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>; @@ -498,8 +427,7 @@ //===- Test a simple pattern with a default operand. ----------------------===// // -// CHECK-LABEL: MatchTable9[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 9*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, // CHECK-NEXT: // MIs[0] dst @@ -520,14 +448,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable9\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable9, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 9: @[[LABEL]] // The -2 is just to distinguish it from the 'not' case below. def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1), @@ -536,8 +457,7 @@ //===- Test a simple pattern with a default register operand. -------------===// // -// CHECK-LABEL: MatchTable10[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 10*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, // CHECK-NEXT: // MIs[0] dst @@ -558,14 +478,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable10\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable10, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 10: @[[LABEL]] // The -3 is just to distinguish it from the 'not' case below and the other default op case above. def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1), @@ -574,8 +487,7 @@ //===- Test a simple pattern with a multiple default operands. ------------===// // -// CHECK-LABEL: MatchTable11[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 11*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, // CHECK-NEXT: // MIs[0] dst @@ -597,14 +509,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable11\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable11, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 11: @[[LABEL]] // The -4 is just to distinguish it from the other 'not' cases. def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1), @@ -613,8 +518,7 @@ //===- Test a simple pattern with multiple operands with defaults. --------===// // -// CHECK-LABEL: MatchTable12[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 12*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, // CHECK-NEXT: // MIs[0] dst @@ -637,14 +541,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable12\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable12, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 12: @[[LABEL]] // The -5 is just to distinguish it from the other cases. def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1), @@ -655,8 +552,7 @@ // This must precede the 3-register variants because constant immediates have // priority over register banks. -// CHECK-LABEL: MatchTable13[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 13*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, // CHECK-NEXT: // MIs[0] dst @@ -677,14 +573,7 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable13\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable13, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 13: @[[LABEL]] def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>; def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>; @@ -692,8 +581,7 @@ //===- Test a COPY_TO_REGCLASS --------------------------------------------===// // -// CHECK-LABEL: MatchTable14[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 14*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST, // CHECK-NEXT: // MIs[0] dst @@ -706,22 +594,14 @@ // 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: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable14\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable14, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 14: @[[LABEL]] def : Pat<(i32 (bitconvert FPR32:$src1)), (COPY_TO_REGCLASS FPR32:$src1, GPR32)>; //===- Test a simple pattern with just a leaf immediate. ------------------===// -// CHECK-LABEL: MatchTable15[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 15*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, // CHECK-NEXT: // MIs[0] dst @@ -736,21 +616,13 @@ // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] -// CHECK-NEXT: GIM_Reject, -// CHECK-NEXT: }; -// CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable15\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable15, TII, MRI, TRI, RBI, AvailableFeatures)) { -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // Label 15: @[[LABEL]] def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>; //===- Test a pattern with an MBB operand. --------------------------------===// -// CHECK-LABEL: MatchTable16[] = { -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 16*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/1, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR, // CHECK-NEXT: // MIs[0] target @@ -759,12 +631,11 @@ // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::BR, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 0: @[[LABEL]] +// CHECK-NEXT: // Label 16: @[[LABEL]] // CHECK-NEXT: GIM_Reject, // CHECK-NEXT: }; // CHECK-NEXT: MIs.resize(1); -// CHECK-NEXT: DEBUG(dbgs() << "Processing MatchTable16\n"); -// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable16, TII, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable0, TII, MRI, TRI, RBI, AvailableFeatures)) { // CHECK-NEXT: return true; // CHECK-NEXT: } Index: utils/TableGen/GlobalISelEmitter.cpp =================================================================== --- utils/TableGen/GlobalISelEmitter.cpp +++ utils/TableGen/GlobalISelEmitter.cpp @@ -53,8 +53,8 @@ STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG"); STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped"); STATISTIC(NumPatternEmitted, "Number of patterns emitted"); -/// A unique identifier for a MatchTable. -static unsigned CurrentMatchTableID = 0; +/// A unique identifier for a MatchTable label. +static unsigned CurrentLabelID = 0; cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel"); @@ -338,7 +338,7 @@ MatchTableRecord::MTRF_LineBreakFollows); } static MatchTableRecord JumpTarget(unsigned LabelID) { - return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0, + return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1, MatchTableRecord::MTRF_JumpTarget | MatchTableRecord::MTRF_Comment | MatchTableRecord::MTRF_CommaFollows); @@ -354,7 +354,7 @@ } void defineLabel(unsigned LabelID) { - LabelMap.insert(std::make_pair(LabelID, CurrentSize + 1)); + LabelMap.insert(std::make_pair(LabelID, CurrentSize)); } unsigned getLabelIndex(unsigned LabelID) const { @@ -363,7 +363,9 @@ return I->second; } - void emit(raw_ostream &OS) const { + void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; } + + void emitDeclaration(raw_ostream &OS) const { unsigned Indentation = 4; OS << " const static int64_t MatchTable" << ID << "[] = {"; LineBreak.emit(OS, true, *this); @@ -436,11 +438,6 @@ return Table; } -raw_ostream &operator<<(raw_ostream &OS, const MatchTable &Table) { - Table.emit(OS); - return OS; -} - //===- Matchers -----------------------------------------------------------===// class OperandMatcher; @@ -489,7 +486,7 @@ void emitCaptureOpcodes(MatchTable &Table); - void emit(raw_ostream &OS); + void emit(MatchTable &Table); /// Compare the priority of this object and B. /// @@ -1548,7 +1545,7 @@ Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID); } -void RuleMatcher::emit(raw_ostream &OS) { +void RuleMatcher::emit(MatchTable &Table) { if (Matchers.empty()) llvm_unreachable("Unexpected empty matcher!"); @@ -1563,9 +1560,8 @@ // on some targets but we don't need to make use of that yet. assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet"); - MatchTable Table(CurrentMatchTableID); Table << MatchTable::Opcode("GIM_Try", +1) - << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(0) + << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(CurrentLabelID) << MatchTable::LineBreak; if (!RequiredFeatures.empty()) { @@ -1639,16 +1635,7 @@ for (const auto &MA : Actions) MA->emitActionOpcodes(Table, *this, 0); Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak - << MatchTable::Label(0) << MatchTable::Opcode("GIM_Reject") - << MatchTable::LineBreak; - OS << Table - << " State.MIs.resize(1);\n" - << " DEBUG(dbgs() << \"Processing MatchTable" << CurrentMatchTableID - << "\\n\");\n" - << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable" - << CurrentMatchTableID << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n" - << " return true;\n" - << " }\n\n"; + << MatchTable::Label(CurrentLabelID); } bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const { @@ -2498,13 +2485,22 @@ << " State.MIs.clear();\n" << " State.MIs.push_back(&I);\n\n"; + MatchTable Table(0); for (auto &Rule : Rules) { - Rule.emit(OS); - ++CurrentMatchTableID; + Rule.emit(Table); + ++CurrentLabelID; ++NumPatternEmitted; - assert(CurrentMatchTableID == NumPatternEmitted && - "Statistic deviates from number of emitted tables"); - } + assert(CurrentLabelID == NumPatternEmitted && + "Statistic deviates from number of emitted labels"); + } + Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak; + Table.emitDeclaration(OS); + OS << " State.MIs.resize(1);\n" + << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, "; + Table.emitUse(OS); + OS << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n" + << " return true;\n" + << " }\n\n"; OS << " return false;\n" << "}\n"