From 5eb0cecbc5dd370e33d4e0ab1abee7ce8597ca9c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 15 Sep 2008 19:46:03 +0000 Subject: [PATCH] Re-enable SelectionDAG CSE for calls. It matters in the case of libcalls, as in this testcase on ARM. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56226 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGNodes.h | 3 ++- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 26 +++++++++++++++----- test/CodeGen/ARM/cse-libcalls.ll | 30 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 test/CodeGen/ARM/cse-libcalls.ll diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 85c464965dd..7cd9eef2abc 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -2205,7 +2205,8 @@ public: /// Set this call to not be marked as a tail call. Normally setter /// methods in SDNodes are unsafe because it breaks the CSE map, - /// but we don't CSE calls so it's ok in this case. + /// but we don't include the tail call flag for calls so it's ok + /// in this case. void setNotTailCall() { IsTailCall = false; } SDValue getChain() const { return getOperand(0); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 921d7b060b9..793f5c99972 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -423,6 +423,12 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) { ID.AddPointer(CP->getConstVal()); break; } + case ISD::CALL: { + const CallSDNode *Call = cast(N); + ID.AddInteger(Call->getCallingConv()); + ID.AddInteger(Call->isVarArg()); + break; + } case ISD::LOAD: { const LoadSDNode *LD = cast(N); ID.AddInteger(LD->getAddressingMode()); @@ -636,7 +642,6 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { // not subject to CSE. if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag && !N->isMachineOpcode() && - N->getOpcode() != ISD::CALL && N->getOpcode() != ISD::DBG_LABEL && N->getOpcode() != ISD::DBG_STOPPOINT && N->getOpcode() != ISD::EH_LABEL && @@ -662,7 +667,6 @@ SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) { switch (N->getOpcode()) { default: break; - case ISD::CALL: case ISD::HANDLENODE: case ISD::DBG_LABEL: case ISD::DBG_STOPPOINT: @@ -3310,13 +3314,23 @@ SDValue SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall, SDVTList VTs, const SDValue *Operands, unsigned NumOperands) { - // Do not CSE calls. Note that in addition to being a compile-time - // optimization (since attempting CSE of calls is unlikely to be - // meaningful), we actually depend on this behavior. CallSDNode can - // be mutated, which is only safe if calls are not CSE'd. + // Do not include isTailCall in the folding set profile. + FoldingSetNodeID ID; + AddNodeIDNode(ID, ISD::CALL, VTs, Operands, NumOperands); + ID.AddInteger(CallingConv); + ID.AddInteger(IsVarArgs); + void *IP = 0; + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) { + // Instead of including isTailCall in the folding set, we just + // set the flag of the existing node. + if (!IsTailCall) + cast(E)->setNotTailCall(); + return SDValue(E, 0); + } SDNode *N = NodeAllocator.Allocate(); new (N) CallSDNode(CallingConv, IsVarArgs, IsTailCall, VTs, Operands, NumOperands); + CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); } diff --git a/test/CodeGen/ARM/cse-libcalls.ll b/test/CodeGen/ARM/cse-libcalls.ll new file mode 100644 index 00000000000..3b499a4021c --- /dev/null +++ b/test/CodeGen/ARM/cse-libcalls.ll @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | llc -march=arm | grep {bl.\*__ltdf} | count 1 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin8" + +; Without CSE of libcalls, there are two calls in the output instead of one. + +define i32 @u_f_nonbon(double %lambda) nounwind { +entry: + %tmp19.i.i = load double* null, align 4 ; [#uses=2] + %tmp6.i = fcmp olt double %tmp19.i.i, 1.000000e+00 ; [#uses=1] + %dielectric.0.i = select i1 %tmp6.i, double 1.000000e+00, double %tmp19.i.i ; [#uses=1] + %tmp10.i4 = fdiv double 0x4074C2D71F36262D, %dielectric.0.i ; [#uses=1] + br i1 false, label %bb28.i, label %bb508.i + +bb28.i: ; preds = %bb28.i, %entry + br i1 false, label %bb502.loopexit.i, label %bb28.i + +bb.nph53.i: ; preds = %bb502.loopexit.i + %tmp354.i = sub double -0.000000e+00, %tmp10.i4 ; [#uses=0] + br label %bb244.i + +bb244.i: ; preds = %bb244.i, %bb.nph53.i + br label %bb244.i + +bb502.loopexit.i: ; preds = %bb28.i + br i1 false, label %bb.nph53.i, label %bb508.i + +bb508.i: ; preds = %bb502.loopexit.i, %entry + ret i32 1 +}