mirror of
https://github.com/RPCSX/llvm.git
synced 2025-05-13 19:06:05 +00:00
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
This commit is contained in:
parent
f19063b33f
commit
5eb0cecbc5
@ -2205,7 +2205,8 @@ public:
|
|||||||
|
|
||||||
/// Set this call to not be marked as a tail call. Normally setter
|
/// Set this call to not be marked as a tail call. Normally setter
|
||||||
/// methods in SDNodes are unsafe because it breaks the CSE map,
|
/// 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; }
|
void setNotTailCall() { IsTailCall = false; }
|
||||||
|
|
||||||
SDValue getChain() const { return getOperand(0); }
|
SDValue getChain() const { return getOperand(0); }
|
||||||
|
@ -423,6 +423,12 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {
|
|||||||
ID.AddPointer(CP->getConstVal());
|
ID.AddPointer(CP->getConstVal());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ISD::CALL: {
|
||||||
|
const CallSDNode *Call = cast<CallSDNode>(N);
|
||||||
|
ID.AddInteger(Call->getCallingConv());
|
||||||
|
ID.AddInteger(Call->isVarArg());
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ISD::LOAD: {
|
case ISD::LOAD: {
|
||||||
const LoadSDNode *LD = cast<LoadSDNode>(N);
|
const LoadSDNode *LD = cast<LoadSDNode>(N);
|
||||||
ID.AddInteger(LD->getAddressingMode());
|
ID.AddInteger(LD->getAddressingMode());
|
||||||
@ -636,7 +642,6 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
|
|||||||
// not subject to CSE.
|
// not subject to CSE.
|
||||||
if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag &&
|
if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag &&
|
||||||
!N->isMachineOpcode() &&
|
!N->isMachineOpcode() &&
|
||||||
N->getOpcode() != ISD::CALL &&
|
|
||||||
N->getOpcode() != ISD::DBG_LABEL &&
|
N->getOpcode() != ISD::DBG_LABEL &&
|
||||||
N->getOpcode() != ISD::DBG_STOPPOINT &&
|
N->getOpcode() != ISD::DBG_STOPPOINT &&
|
||||||
N->getOpcode() != ISD::EH_LABEL &&
|
N->getOpcode() != ISD::EH_LABEL &&
|
||||||
@ -662,7 +667,6 @@ SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) {
|
|||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::CALL:
|
|
||||||
case ISD::HANDLENODE:
|
case ISD::HANDLENODE:
|
||||||
case ISD::DBG_LABEL:
|
case ISD::DBG_LABEL:
|
||||||
case ISD::DBG_STOPPOINT:
|
case ISD::DBG_STOPPOINT:
|
||||||
@ -3310,13 +3314,23 @@ SDValue
|
|||||||
SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
|
SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
|
||||||
SDVTList VTs,
|
SDVTList VTs,
|
||||||
const SDValue *Operands, unsigned NumOperands) {
|
const SDValue *Operands, unsigned NumOperands) {
|
||||||
// Do not CSE calls. Note that in addition to being a compile-time
|
// Do not include isTailCall in the folding set profile.
|
||||||
// optimization (since attempting CSE of calls is unlikely to be
|
FoldingSetNodeID ID;
|
||||||
// meaningful), we actually depend on this behavior. CallSDNode can
|
AddNodeIDNode(ID, ISD::CALL, VTs, Operands, NumOperands);
|
||||||
// be mutated, which is only safe if calls are not CSE'd.
|
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>();
|
SDNode *N = NodeAllocator.Allocate<CallSDNode>();
|
||||||
new (N) CallSDNode(CallingConv, IsVarArgs, IsTailCall,
|
new (N) CallSDNode(CallingConv, IsVarArgs, IsTailCall,
|
||||||
VTs, Operands, NumOperands);
|
VTs, Operands, NumOperands);
|
||||||
|
CSEMap.InsertNode(N, IP);
|
||||||
AllNodes.push_back(N);
|
AllNodes.push_back(N);
|
||||||
return SDValue(N, 0);
|
return SDValue(N, 0);
|
||||||
}
|
}
|
||||||
|
30
test/CodeGen/ARM/cse-libcalls.ll
Normal file
30
test/CodeGen/ARM/cse-libcalls.ll
Normal file
@ -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 ; <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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user