diff options
| author | Florian Hahn <florian.hahn@arm.com> | 2017-08-03 14:48:22 +0000 |
|---|---|---|
| committer | Florian Hahn <florian.hahn@arm.com> | 2017-08-03 14:48:22 +0000 |
| commit | 3bc3ec661cf750fefc3d093a8165c35a66d2c5fe (patch) | |
| tree | e9695f92f51565ddd57e44f763eed77877dcdfd8 | |
| parent | c1cfe0a82844c35d71f13cf8f09ddd4032dd58cd (diff) | |
| download | bcm5719-llvm-3bc3ec661cf750fefc3d093a8165c35a66d2c5fe.tar.gz bcm5719-llvm-3bc3ec661cf750fefc3d093a8165c35a66d2c5fe.zip | |
[GlobalISel] Only merge memory ops for mayLoad or mayStore instrs.
Summary:
We only need to merge memory operands for instructions that access
memory. This slightly reduces the number of actions executed.
Reviewers: MatzeB, rovka, dsanders
Reviewed By: dsanders
Subscribers: aemerson, igorb, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D36151
llvm-svn: 309944
| -rw-r--r-- | llvm/test/TableGen/GlobalISelEmitter.td | 20 | ||||
| -rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 39 |
2 files changed, 25 insertions, 34 deletions
diff --git a/llvm/test/TableGen/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter.td index 11400d8f6ae..638fe48f10d 100644 --- a/llvm/test/TableGen/GlobalISelEmitter.td +++ b/llvm/test/TableGen/GlobalISelEmitter.td @@ -117,8 +117,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, -// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, +// CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, // CHECK-NEXT: // Label 0: @[[LABEL]] @@ -168,14 +167,15 @@ def : Pat<(select GPR32:$src1, complex:$src2, (select GPR32:$src3, complex:$src4 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src3 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1, // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/2, -// CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, 1, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, // CHECK-NEXT: // Label 1: @[[LABEL]] def : GINodeEquiv<G_SELECT, select>; -def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>; +let mayLoad = 1 in { + def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>; +} def : Pat<(select GPR32:$src1, complex:$src2, complex:$src3), (INSN2 GPR32:$src1, complex:$src3, complex:$src2)>; @@ -221,7 +221,6 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV, // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src1 -// CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -262,7 +261,6 @@ def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1), // 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, /*MergeInsnID's*/0, 1, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -299,7 +297,6 @@ def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1), // 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, /*MergeInsnID's*/0, 1, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -330,7 +327,6 @@ def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3), // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -384,7 +380,6 @@ def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$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, /*MergeInsnID's*/0, 1, 2, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -415,7 +410,6 @@ def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, G // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -444,7 +438,6 @@ def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>; // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -474,7 +467,6 @@ def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1), // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -505,7 +497,6 @@ def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1), // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -537,7 +528,6 @@ def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1), // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -569,7 +559,6 @@ def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1) // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, @@ -612,7 +601,6 @@ def : Pat<(i32 (bitconvert FPR32:$src1)), // 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, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 13303ebc2b1..cac40a764ec 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -1462,24 +1462,27 @@ public: for (const auto &Renderer : OperandRenderers) Renderer->emitRenderOpcodes(Table, Rule); - Table << MatchTable::Opcode("GIR_MergeMemOperands") - << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID) - << MatchTable::Comment("MergeInsnID's"); - // Emit the ID's for all the instructions that are matched by this rule. - // TODO: Limit this to matched instructions that mayLoad/mayStore or have - // some other means of having a memoperand. Also limit this to emitted - // instructions that expect to have a memoperand too. For example, - // (G_SEXT (G_LOAD x)) that results in separate load and sign-extend - // instructions shouldn't put the memoperand on the sign-extend since - // it has no effect there. - std::vector<unsigned> MergeInsnIDs; - for (const auto &IDMatcherPair : Rule.defined_insn_vars()) - MergeInsnIDs.push_back(IDMatcherPair.second); - std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end()); - for (const auto &MergeInsnID : MergeInsnIDs) - Table << MatchTable::IntValue(MergeInsnID); - Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList") - << MatchTable::LineBreak << MatchTable::Opcode("GIR_EraseFromParent") + if (I->mayLoad || I->mayStore) { + Table << MatchTable::Opcode("GIR_MergeMemOperands") + << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID) + << MatchTable::Comment("MergeInsnID's"); + // Emit the ID's for all the instructions that are matched by this rule. + // TODO: Limit this to matched instructions that mayLoad/mayStore or have + // some other means of having a memoperand. Also limit this to + // emitted instructions that expect to have a memoperand too. For + // example, (G_SEXT (G_LOAD x)) that results in separate load and + // sign-extend instructions shouldn't put the memoperand on the + // sign-extend since it has no effect there. + std::vector<unsigned> MergeInsnIDs; + for (const auto &IDMatcherPair : Rule.defined_insn_vars()) + MergeInsnIDs.push_back(IDMatcherPair.second); + std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end()); + for (const auto &MergeInsnID : MergeInsnIDs) + Table << MatchTable::IntValue(MergeInsnID); + Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList"); + } + + Table << MatchTable::Opcode("GIR_EraseFromParent") << MatchTable::Comment("InsnID") << MatchTable::IntValue(RecycleInsnID) << MatchTable::LineBreak; } |

