[llvm] r309804 - [globalisel][tablegen] Do not merge memoperands from instructions that weren't in the match.
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 3 02:01:18 PDT 2017
> On 2 Aug 2017, at 12:11, Daniel Sanders via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
>>
>> On 2 Aug 2017, at 12:07, Diana Picus <diana.picus at linaro.org> wrote:
>>
>> On 2 August 2017 at 13:03, Daniel Sanders via llvm-commits
>> <llvm-commits at lists.llvm.org> wrote:
>>> Author: dsanders
>>> Date: Wed Aug 2 04:03:36 2017
>>> New Revision: 309804
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=309804&view=rev
>>> Log:
>>> [globalisel][tablegen] Do not merge memoperands from instructions that weren't in the match.
>>>
>>> Summary:
>>> Fix a bug discovered in an out-of-tree target where memoperands from
>>> pseudo-instructions that weren't part of the match were being merged into the
>>> result instructions as part of GIR_MergeMemOperands.
>>>
>>> This bug was caused by a change to the handling of State.MIs between rules when
>>> the state machine tables were fused into a single table. Previously, each rule
>>> would reset State.MIs using State.MIs.resize(1) but this is no longer done, as a
>>> result stale data is occasionally left in some elements of State.MIs. Most
>>> opcodes aren't affected by this but GIR_MergeMemOperands merges all memoperands
>>> from the intructions recorded in State.MIs into the result instruction.
>>>
>>> Suppose for example, we processed but rejected the following pattern:
>>> (signextend (load x))
>>> at this point, State.MIs contains the signextend and the load. Now suppose we
>>> process and accept this pattern:
>>> (add x, y)
>>> at this point, State.MIs contains the add as well as the (now irrelevant) load.
>>> When GIR_MergeMemOperands is processed, the memoperands from that irrelevant
>>> load will be merged into the result instruction even though it was not part of
>>> the match.
>>>
>>> Bringing back the State.MIs.resize(1) would fix the problem but it would limit
>>> our ability to optimize the table in the future. Instead, this patch fixes the
>>> problem by explicitly stating which instructions should be merged into the result.
>>>
>>> There's no direct test case in this commit because a test case would be very brittle.
>>> However, at the time of writing this should fix the failures in
>>> http://green.lab.llvm.org/green/job/Compiler_Verifiers_GlobalISEL/ as well as a
>>> failure in test/CodeGen/ARM/GlobalISel/arm-isel.ll when expensive checks are enabled.
>>>
>>> Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
>>>
>>> Subscribers: fhahn, kristof.beyls, igorb, llvm-commits
>>>
>>> Differential Revision: https://reviews.llvm.org/D36094
>>>
>>>
>>> Modified:
>>> llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
>>> llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
>>> llvm/trunk/test/TableGen/GlobalISelEmitter.td
>>> llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
>>>
>>> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=309804&r1=309803&r2=309804&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h (original)
>>> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h Wed Aug 2 04:03:36 2017
>>> @@ -195,6 +195,8 @@ enum {
>>> GIR_ConstrainSelectedInstOperands,
>>> /// Merge all memory operands into instruction.
>>> /// - InsnID - Instruction ID to modify
>>> + /// - MergeInsnID... - One or more Instruction ID to merge into the result.
>>> + /// - -1 - Terminates the list of instructions to merge.
>>
>> This comment should say GIU_MergeMemOperands_EndOfList instead of -1.
>
> Thanks. I'll fix this once the commit has gone through the green dragon bot that was failing.
Fixed in r309924
>>> GIR_MergeMemOperands,
>>> /// Erase from parent.
>>> /// - InsnID - Instruction ID to erase
>>> @@ -204,6 +206,12 @@ enum {
>>> GIR_Done,
>>> };
>>>
>>> +enum {
>>> + /// Indicates the end of the variable-length MergeInsnID list in a
>>> + /// GIR_MergeMemOperands opcode.
>>> + GIU_MergeMemOperands_EndOfList = -1,
>>> +};
>>> +
>>> /// Provides the logic to select generic machine instructions.
>>> class InstructionSelector {
>>> public:
>>>
>>> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h?rev=309804&r1=309803&r2=309804&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h (original)
>>> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h Wed Aug 2 04:03:36 2017
>>> @@ -370,11 +370,17 @@ bool InstructionSelector::executeMatchTa
>>> case GIR_MergeMemOperands: {
>>> int64_t InsnID = MatchTable[CurrentIdx++];
>>> 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() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs[" << InsnID
>>> - << "])\n");
>>> + << "]");
>>> + int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
>>> + while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
>>> + GIU_MergeMemOperands_EndOfList) {
>>> + DEBUG(dbgs() << ", MIs[" << MergeInsnID << "]");
>>> + for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
>>> + OutMIs[InsnID].addMemOperand(MMO);
>>> + }
>>> + DEBUG(dbgs() << ")\n");
>>> break;
>>> }
>>> case GIR_EraseFromParent: {
>>>
>>> Modified: llvm/trunk/test/TableGen/GlobalISelEmitter.td
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=309804&r1=309803&r2=309804&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/TableGen/GlobalISelEmitter.td (original)
>>> +++ llvm/trunk/test/TableGen/GlobalISelEmitter.td Wed Aug 2 04:03:36 2017
>>> @@ -117,7 +117,7 @@ def HasC : Predicate<"Subtarget->hasC()"
>>> // 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_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,
>>> @@ -168,7 +168,7 @@ def : Pat<(select GPR32:$src1, complex:$
>>> // 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,
>>> +// 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,
>>> @@ -221,7 +221,7 @@ def ADD : I<(outs GPR32:$dst), (ins GPR3
>>> // 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,
>>> +// 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 +262,7 @@ def MOV : I<(outs GPR32:$dst), (ins GPR3
>>> // 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_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 +299,7 @@ def MOV : I<(outs GPR32:$dst), (ins GPR3
>>> // 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_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 +330,7 @@ def MULADD : I<(outs GPR32:$dst), (ins G
>>> // 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_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 +384,7 @@ def MUL : I<(outs GPR32:$dst), (ins GPR3
>>> // 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_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 +415,7 @@ def INSNBOB : I<(outs GPR32:$dst), (ins
>>> // 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_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 +444,7 @@ def : Pat<(sub GPR32:$src1, complex:$src
>>> // 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_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 +474,7 @@ def XORI : I<(outs GPR32:$dst), (ins m1:
>>> // 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_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 +505,7 @@ def XOR : I<(outs GPR32:$dst), (ins Z:$s
>>> // 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_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 +537,7 @@ def XORlike : I<(outs GPR32:$dst), (ins
>>> // 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_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 +569,7 @@ def XORManyDefaults : I<(outs GPR32:$dst
>>> // 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_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 +612,7 @@ 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,
>>> +// 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,
>>>
>>> Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=309804&r1=309803&r2=309804&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)
>>> +++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Wed Aug 2 04:03:36 2017
>>> @@ -460,9 +460,11 @@ class RuleMatcher {
>>> /// have succeeded.
>>> std::vector<std::unique_ptr<MatchAction>> Actions;
>>>
>>> + typedef std::map<const InstructionMatcher *, unsigned>
>>> + DefinedInsnVariablesMap;
>>> /// A map of instruction matchers to the local variables created by
>>> /// emitCaptureOpcodes().
>>> - std::map<const InstructionMatcher *, unsigned> InsnVariableIDs;
>>> + DefinedInsnVariablesMap InsnVariableIDs;
>>>
>>> /// ID for the next instruction variable defined with defineInsnVar()
>>> unsigned NextInsnVarID;
>>> @@ -488,6 +490,16 @@ public:
>>> unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
>>> unsigned InsnVarID, unsigned OpIdx);
>>> unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
>>> + DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
>>> + return InsnVariableIDs.begin();
>>> + }
>>> + DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
>>> + return InsnVariableIDs.end();
>>> + }
>>> + iterator_range<typename DefinedInsnVariablesMap::const_iterator>
>>> + defined_insn_vars() const {
>>> + return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
>>> + }
>>>
>>> void emitCaptureOpcodes(MatchTable &Table);
>>>
>>> @@ -1452,6 +1464,21 @@ public:
>>>
>>> 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")
>>> << MatchTable::Comment("InsnID")
>>> << MatchTable::IntValue(RecycleInsnID) << MatchTable::LineBreak;
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170803/c29bc282/attachment.html>
More information about the llvm-commits
mailing list