ID.AddPointer(CP->getConstVal());
break;
}
+ case ISD::CALL: {
+ const CallSDNode *Call = cast<CallSDNode>(N);
+ ID.AddInteger(Call->getCallingConv());
+ ID.AddInteger(Call->isVarArg());
+ break;
+ }
case ISD::LOAD: {
const LoadSDNode *LD = cast<LoadSDNode>(N);
ID.AddInteger(LD->getAddressingMode());
// 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 &&
switch (N->getOpcode()) {
default: break;
- case ISD::CALL:
case ISD::HANDLENODE:
case ISD::DBG_LABEL:
case ISD::DBG_STOPPOINT:
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<CallSDNode>(E)->setNotTailCall();
+ return SDValue(E, 0);
+ }
SDNode *N = NodeAllocator.Allocate<CallSDNode>();
new (N) CallSDNode(CallingConv, IsVarArgs, IsTailCall,
VTs, Operands, NumOperands);
+ CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
}
--- /dev/null
+; 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 ; <double> [#uses=2]
+ %tmp6.i = fcmp olt double %tmp19.i.i, 1.000000e+00 ; <i1> [#uses=1]
+ %dielectric.0.i = select i1 %tmp6.i, double 1.000000e+00, double %tmp19.i.i ; <double> [#uses=1]
+ %tmp10.i4 = fdiv double 0x4074C2D71F36262D, %dielectric.0.i ; <double> [#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 ; <double> [#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
+}