[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
Wed Nov 16 12:48:56 PST 2011
Thanks. I think you can use getOpcodeAfterMemoryUnfold() to test if the instruction is folding both a load and a store.
Evan
On Nov 16, 2011, at 9:30 AM, Peter Cooper wrote:
> Hi Evan
>
> Thanks for the comments. I'll add the changes you requested.
>
> Pete
>
> On Nov 15, 2011, at 9:42 PM, Evan Cheng wrote:
>
>> 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