[llvm-commits] [llvm] r144705 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/dec-eflags-lower.ll
Evan Cheng
evan.cheng at apple.com
Tue Nov 15 21:42:30 PST 2011
Hi Pete,
Comments below.
On Nov 15, 2011, at 1:57 PM, Pete Cooper wrote:
> Author: pete
> Date: Tue Nov 15 15:57:53 2011
> New Revision: 144705
>
> URL: http://llvm.org/viewvc/llvm-project?rev=144705&view=rev
> Log:
> Added custom lowering for load->dec->store sequence in x86 when the EFLAGS registers is used
> by later instructions.
>
> Only done for DEC64m right now.
>
> Fixes <rdar://problem/6172640>
>
> Added:
> llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
> llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=144705&r1=144704&r2=144705&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Nov 15 15:57:53 2011
> @@ -948,6 +948,11 @@
> if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes))
> return NULL;
>
> + // unfolding an x86 DEC64m operation results in store, dec, load which
> + // can't be handled here so quit
> + if (NewNodes.size() == 3)
> + return NULL;
I don't think this is the right way. Can't you detect it's folding both a load and a store before doing a bunch of work?
> +
> DEBUG(dbgs() << "Unfolding SU #" << SU->NodeNum << "\n");
> assert(NewNodes.size() == 2 && "Expected a load folding node!");
>
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=144705&r1=144704&r2=144705&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Nov 15 15:57:53 2011
> @@ -2216,6 +2216,63 @@
> }
> break;
> }
> + case ISD::STORE: {
Please add comments to show why we need c++ code to isel this. Preferably with a example of what the isel pattern *should* look like when we get around to adding the tablegen syntax.
Thanks,
Evan
> + StoreSDNode *StoreNode = cast<StoreSDNode>(Node);
> + SDValue Chain = StoreNode->getOperand(0);
> + SDValue StoredVal = StoreNode->getOperand(1);
> + SDValue Address = StoreNode->getOperand(2);
> + SDValue Undef = StoreNode->getOperand(3);
> +
> + if (StoreNode->getMemOperand()->getSize() != 8 ||
> + Undef->getOpcode() != ISD::UNDEF ||
> + Chain->getOpcode() != ISD::LOAD ||
> + StoredVal->getOpcode() != X86ISD::DEC ||
> + StoredVal.getResNo() != 0 ||
> + StoredVal->getOperand(0).getNode() != Chain.getNode())
> + break;
> +
> + //OPC_CheckPredicate, 1, // Predicate_nontemporalstore
> + if (StoreNode->isNonTemporal())
> + break;
> +
> + LoadSDNode *LoadNode = cast<LoadSDNode>(Chain.getNode());
> + if (LoadNode->getOperand(1) != Address ||
> + LoadNode->getOperand(2) != Undef)
> + break;
> +
> + if (!ISD::isNormalLoad(LoadNode))
> + break;
> +
> + if (!ISD::isNormalStore(StoreNode))
> + break;
> +
> + // check load chain has only one use (from the store)
> + if (!Chain.hasOneUse())
> + break;
> +
> + // Merge the input chains if they are not intra-pattern references.
> + SDValue InputChain = LoadNode->getOperand(0);
> +
> + SDValue Base, Scale, Index, Disp, Segment;
> + if (!SelectAddr(LoadNode, LoadNode->getBasePtr(),
> + Base, Scale, Index, Disp, Segment))
> + break;
> +
> + MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(2);
> + MemOp[0] = StoreNode->getMemOperand();
> + MemOp[1] = LoadNode->getMemOperand();
> + const SDValue Ops[] = { Base, Scale, Index, Disp, Segment, InputChain };
> + MachineSDNode *Result = CurDAG->getMachineNode(X86::DEC64m,
> + Node->getDebugLoc(),
> + MVT::i32, MVT::Other, Ops,
> + array_lengthof(Ops));
> + Result->setMemRefs(MemOp, MemOp + 2);
> +
> + ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
> + ReplaceUses(SDValue(StoredVal.getNode(), 1), SDValue(Result, 0));
> +
> + return Result;
> + }
> }
>
> SDNode *ResNode = SelectCode(Node);
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=144705&r1=144704&r2=144705&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Nov 15 15:57:53 2011
> @@ -8263,8 +8263,10 @@
> // climbing the DAG back to the root, and it doesn't seem to be worth the
> // effort.
> for (SDNode::use_iterator UI = Op.getNode()->use_begin(),
> - UE = Op.getNode()->use_end(); UI != UE; ++UI)
> - if (UI->getOpcode() != ISD::CopyToReg && UI->getOpcode() != ISD::SETCC)
> + UE = Op.getNode()->use_end(); UI != UE; ++UI)
> + if (UI->getOpcode() != ISD::CopyToReg &&
> + UI->getOpcode() != ISD::SETCC &&
> + UI->getOpcode() != ISD::STORE)
> goto default_case;
>
> if (ConstantSDNode *C =
>
> Added: llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll?rev=144705&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll Tue Nov 15 15:57:53 2011
> @@ -0,0 +1,29 @@
> +; RUN: llc < %s -march=x86-64 | FileCheck %s
> +
> +%struct.obj = type { i64 }
> +
> +define void @_Z7releaseP3obj(%struct.obj* nocapture %o) nounwind uwtable ssp {
> +entry:
> +; CHECK: decq (%rdi)
> +; CHECK-NEXT: je
> + %refcnt = getelementptr inbounds %struct.obj* %o, i64 0, i32 0
> + %0 = load i64* %refcnt, align 8, !tbaa !0
> + %dec = add i64 %0, -1
> + store i64 %dec, i64* %refcnt, align 8, !tbaa !0
> + %tobool = icmp eq i64 %dec, 0
> + br i1 %tobool, label %if.end, label %return
> +
> +if.end: ; preds = %entry
> + %1 = bitcast %struct.obj* %o to i8*
> + tail call void @free(i8* %1)
> + br label %return
> +
> +return: ; preds = %entry, %if.end
> + ret void
> +}
> +
> +declare void @free(i8* nocapture) nounwind
> +
> +!0 = metadata !{metadata !"long", metadata !1}
> +!1 = metadata !{metadata !"omnipotent char", metadata !2}
> +!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list