mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-23 14:03:14 +00:00
[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
This commit is contained in:
parent
f7f1be8b97
commit
56043dcb28
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user