[llvm] r309804 - [globalisel][tablegen] Do not merge memoperands from instructions that weren't in the match.

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 3 02:03:03 PDT 2017


Ok, thanks.

On 3 August 2017 at 11:01, Daniel Sanders <daniel_l_sanders at apple.com> wrote:
>
>
> 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
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>


More information about the llvm-commits mailing list