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