Revert r131152, r129796, r129761. This code is currently considered

to be unreliable on platforms which require memcpy calls, and it is
complicating broader legalize cleanups. It is hoped that these cleanups
will make memcpy byval easier to implement in the future.

llvm-svn: 138977
This commit is contained in:
Dan Gohman 2011-09-01 23:07:08 +00:00
parent 6397051ece
commit 3767be9aee
5 changed files with 56 additions and 52 deletions

View File

@ -53,10 +53,15 @@ class SelectionDAGLegalize {
// Libcall insertion helpers. // Libcall insertion helpers.
/// LastCALLSEQ - This keeps track of the CALLSEQ_END node that has been /// LastCALLSEQ_END - This keeps track of the CALLSEQ_END node that has been
/// legalized. We use this to ensure that calls are properly serialized /// legalized. We use this to ensure that calls are properly serialized
/// against each other, including inserted libcalls. /// against each other, including inserted libcalls.
SmallVector<SDValue, 8> LastCALLSEQ; SDValue LastCALLSEQ_END;
/// IsLegalizingCall - This member is used *only* for purposes of providing
/// helpful assertions that a libcall isn't created while another call is
/// being legalized (which could lead to non-serialized call sequences).
bool IsLegalizingCall;
/// LegalizedNodes - For nodes that are of legal width, and that have more /// LegalizedNodes - For nodes that are of legal width, and that have more
/// than one use, this map indicates what regularized operand to use. This /// than one use, this map indicates what regularized operand to use. This
@ -149,15 +154,6 @@ private:
void ExpandNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); void ExpandNode(SDNode *Node, SmallVectorImpl<SDValue> &Results);
void PromoteNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); void PromoteNode(SDNode *Node, SmallVectorImpl<SDValue> &Results);
SDValue getLastCALLSEQ() { return LastCALLSEQ.back(); }
void setLastCALLSEQ(const SDValue s) { LastCALLSEQ.back() = s; }
void pushLastCALLSEQ(SDValue s) {
LastCALLSEQ.push_back(s);
}
void popLastCALLSEQ() {
LastCALLSEQ.pop_back();
}
}; };
} }
@ -199,7 +195,8 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)
} }
void SelectionDAGLegalize::LegalizeDAG() { void SelectionDAGLegalize::LegalizeDAG() {
pushLastCALLSEQ(DAG.getEntryNode()); LastCALLSEQ_END = DAG.getEntryNode();
IsLegalizingCall = false;
// The legalize process is inherently a bottom-up recursive process (users // The legalize process is inherently a bottom-up recursive process (users
// legalize their uses before themselves). Given infinite stack space, we // legalize their uses before themselves). Given infinite stack space, we
@ -227,15 +224,14 @@ void SelectionDAGLegalize::LegalizeDAG() {
/// FindCallEndFromCallStart - Given a chained node that is part of a call /// FindCallEndFromCallStart - Given a chained node that is part of a call
/// sequence, find the CALLSEQ_END node that terminates the call sequence. /// sequence, find the CALLSEQ_END node that terminates the call sequence.
static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) {
int next_depth = depth; // Nested CALLSEQ_START/END constructs aren't yet legal,
// but we can DTRT and handle them correctly here.
if (Node->getOpcode() == ISD::CALLSEQ_START) if (Node->getOpcode() == ISD::CALLSEQ_START)
next_depth = depth + 1; depth++;
if (Node->getOpcode() == ISD::CALLSEQ_END) { else if (Node->getOpcode() == ISD::CALLSEQ_END) {
assert(depth > 0 && "negative depth!"); depth--;
if (depth == 1) if (depth == 0)
return Node; return Node;
else
next_depth = depth - 1;
} }
if (Node->use_empty()) if (Node->use_empty())
return 0; // No CallSeqEnd return 0; // No CallSeqEnd
@ -266,7 +262,7 @@ static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) {
SDNode *User = *UI; SDNode *User = *UI;
for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
if (User->getOperand(i) == TheChain) if (User->getOperand(i) == TheChain)
if (SDNode *Result = FindCallEndFromCallStart(User, next_depth)) if (SDNode *Result = FindCallEndFromCallStart(User, depth))
return Result; return Result;
} }
return 0; return 0;
@ -287,7 +283,6 @@ static SDNode *FindCallStartFromCallEnd(SDNode *Node) {
case ISD::CALLSEQ_START: case ISD::CALLSEQ_START:
if (!nested) if (!nested)
return Node; return Node;
Node = Node->getOperand(0).getNode();
nested--; nested--;
break; break;
case ISD::CALLSEQ_END: case ISD::CALLSEQ_END:
@ -295,7 +290,7 @@ static SDNode *FindCallStartFromCallEnd(SDNode *Node) {
break; break;
} }
} }
return (Node->getOpcode() == ISD::CALLSEQ_START) ? Node : 0; return 0;
} }
/// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to /// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to
@ -917,12 +912,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::BR_JT: case ISD::BR_JT:
case ISD::BR_CC: case ISD::BR_CC:
case ISD::BRCOND: case ISD::BRCOND:
assert(LastCALLSEQ.size() == 1 && "branch inside CALLSEQ_BEGIN/END?"); // Branches tweak the chain to include LastCALLSEQ_END
// Branches tweak the chain to include LastCALLSEQ
Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0], Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0],
getLastCALLSEQ()); LastCALLSEQ_END);
Ops[0] = LegalizeOp(Ops[0]); Ops[0] = LegalizeOp(Ops[0]);
setLastCALLSEQ(DAG.getEntryNode()); LastCALLSEQ_END = DAG.getEntryNode();
break; break;
case ISD::SHL: case ISD::SHL:
case ISD::SRL: case ISD::SRL:
@ -1011,7 +1005,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break; break;
case ISD::CALLSEQ_START: { case ISD::CALLSEQ_START: {
SDNode *CallEnd = FindCallEndFromCallStart(Node); SDNode *CallEnd = FindCallEndFromCallStart(Node);
assert(CallEnd && "didn't find CALLSEQ_END!");
// Recursively Legalize all of the inputs of the call end that do not lead // Recursively Legalize all of the inputs of the call end that do not lead
// to this call start. This ensures that any libcalls that need be inserted // to this call start. This ensures that any libcalls that need be inserted
@ -1028,9 +1021,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Merge in the last call to ensure that this call starts after the last // Merge in the last call to ensure that this call starts after the last
// call ended. // call ended.
if (getLastCALLSEQ().getOpcode() != ISD::EntryToken) { if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) {
Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Tmp1, getLastCALLSEQ()); Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1); Tmp1 = LegalizeOp(Tmp1);
} }
@ -1051,29 +1044,25 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// sequence have been legalized, legalize the call itself. During this // sequence have been legalized, legalize the call itself. During this
// process, no libcalls can/will be inserted, guaranteeing that no calls // process, no libcalls can/will be inserted, guaranteeing that no calls
// can overlap. // can overlap.
assert(!IsLegalizingCall && "Inconsistent sequentialization of calls!");
// Note that we are selecting this call! // Note that we are selecting this call!
setLastCALLSEQ(SDValue(CallEnd, 0)); LastCALLSEQ_END = SDValue(CallEnd, 0);
IsLegalizingCall = true;
// Legalize the call, starting from the CALLSEQ_END. // Legalize the call, starting from the CALLSEQ_END.
LegalizeOp(getLastCALLSEQ()); LegalizeOp(LastCALLSEQ_END);
assert(!IsLegalizingCall && "CALLSEQ_END should have cleared this!");
return Result; return Result;
} }
case ISD::CALLSEQ_END: case ISD::CALLSEQ_END:
{ // If the CALLSEQ_START node hasn't been legalized first, legalize it. This
SDNode *myCALLSEQ_BEGIN = FindCallStartFromCallEnd(Node); // will cause this node to be legalized as well as handling libcalls right.
if (LastCALLSEQ_END.getNode() != Node) {
// If the CALLSEQ_START node hasn't been legalized first, legalize it. LegalizeOp(SDValue(FindCallStartFromCallEnd(Node), 0));
// This will cause this node to be legalized as well as handling libcalls DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op);
// right. assert(I != LegalizedNodes.end() &&
if (getLastCALLSEQ().getNode() != Node) { "Legalizing the call start should have legalized this node!");
LegalizeOp(SDValue(myCALLSEQ_BEGIN, 0)); return I->second;
DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op);
assert(I != LegalizedNodes.end() &&
"Legalizing the call start should have legalized this node!");
return I->second;
}
pushLastCALLSEQ(SDValue(myCALLSEQ_BEGIN, 0));
} }
// Otherwise, the call start has been legalized and everything is going // Otherwise, the call start has been legalized and everything is going
@ -1101,8 +1090,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Result.getResNo()); Result.getResNo());
} }
} }
assert(IsLegalizingCall && "Call sequence imbalance between start/end?");
// This finishes up call legalization. // This finishes up call legalization.
popLastCALLSEQ(); IsLegalizingCall = false;
// If the CALLSEQ_END node has a flag, remember that we legalized it. // If the CALLSEQ_END node has a flag, remember that we legalized it.
AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
@ -2155,6 +2145,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
// and leave the Hi part unset. // and leave the Hi part unset.
SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
bool isSigned) { bool isSigned) {
assert(!IsLegalizingCall && "Cannot overlap legalization of calls!");
// The input chain to this libcall is the entry node of the function. // The input chain to this libcall is the entry node of the function.
// Legalizing the call will automatically add the previous call to the // Legalizing the call will automatically add the previous call to the
// dependence. // dependence.
@ -2190,7 +2181,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
return DAG.getRoot(); return DAG.getRoot();
// Legalize the call sequence, starting with the chain. This will advance // Legalize the call sequence, starting with the chain. This will advance
// the LastCALLSEQ to the legalized version of the CALLSEQ_END node that // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
// was added by LowerCallTo (guaranteeing proper serialization of calls). // was added by LowerCallTo (guaranteeing proper serialization of calls).
LegalizeOp(CallInfo.second); LegalizeOp(CallInfo.second);
return CallInfo.first; return CallInfo.first;
@ -2236,6 +2227,7 @@ std::pair<SDValue, SDValue>
SelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC, SelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC,
SDNode *Node, SDNode *Node,
bool isSigned) { bool isSigned) {
assert(!IsLegalizingCall && "Cannot overlap legalization of calls!");
SDValue InChain = Node->getOperand(0); SDValue InChain = Node->getOperand(0);
TargetLowering::ArgListTy Args; TargetLowering::ArgListTy Args;
@ -2261,7 +2253,7 @@ SelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC,
Callee, Args, DAG, Node->getDebugLoc()); Callee, Args, DAG, Node->getDebugLoc());
// Legalize the call sequence, starting with the chain. This will advance // Legalize the call sequence, starting with the chain. This will advance
// the LastCALLSEQ to the legalized version of the CALLSEQ_END node that // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
// was added by LowerCallTo (guaranteeing proper serialization of calls). // was added by LowerCallTo (guaranteeing proper serialization of calls).
LegalizeOp(CallInfo.second); LegalizeOp(CallInfo.second);
return CallInfo; return CallInfo;
@ -2402,7 +2394,7 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
LegalizeOp(CallInfo.second); LegalizeOp(CallInfo.second);
// Remainder is loaded back from the stack frame. // Remainder is loaded back from the stack frame.
SDValue Rem = DAG.getLoad(RetVT, dl, getLastCALLSEQ(), FIPtr, SDValue Rem = DAG.getLoad(RetVT, dl, LastCALLSEQ_END, FIPtr,
MachinePointerInfo(), false, false, 0); MachinePointerInfo(), false, false, 0);
Results.push_back(CallInfo.first); Results.push_back(CallInfo.first);
Results.push_back(Rem); Results.push_back(Rem);
@ -3760,8 +3752,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp2.getValueType()), LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp2.getValueType()),
Tmp2, Tmp3, Tmp4, dl); Tmp2, Tmp3, Tmp4, dl);
assert(LastCALLSEQ.size() == 1 && "branch inside CALLSEQ_BEGIN/END?"); LastCALLSEQ_END = DAG.getEntryNode();
setLastCALLSEQ(DAG.getEntryNode());
assert(!Tmp3.getNode() && "Can't legalize BR_CC with legal condition!"); assert(!Tmp3.getNode() && "Can't legalize BR_CC with legal condition!");
Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); Tmp3 = DAG.getConstant(0, Tmp2.getValueType());

View File

@ -1,4 +1,8 @@
; RUN: llc < %s -relocation-model=pic -mcpu=cortex-a8 -arm-tail-calls=1 | FileCheck %s ; RUN: llc < %s -relocation-model=pic -mcpu=cortex-a8 -arm-tail-calls=1 | FileCheck %s
; byval is currently unsupported.
; XFAIL: *
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
target triple = "thumbv7-apple-darwin10" target triple = "thumbv7-apple-darwin10"

View File

@ -1,5 +1,8 @@
; RUN: llc -march=mipsel < %s | FileCheck %s ; RUN: llc -march=mipsel < %s | FileCheck %s
; byval is currently unsupported.
; XFAIL: *
; CHECK: .set macro ; CHECK: .set macro
; CHECK-NEXT: .cprestore ; CHECK-NEXT: .cprestore
; CHECK-NEXT: .set nomacro ; CHECK-NEXT: .set nomacro

View File

@ -1,5 +1,8 @@
; RUN: llc -march=mipsel -mcpu=4ke < %s | FileCheck %s ; RUN: llc -march=mipsel -mcpu=4ke < %s | FileCheck %s
; byval is currently unsupported.
; XFAIL: *
%struct.S1 = type { [65536 x i8] } %struct.S1 = type { [65536 x i8] }
@s1 = external global %struct.S1 @s1 = external global %struct.S1

View File

@ -2,6 +2,9 @@
; rdar://problem/9416774 ; rdar://problem/9416774
; ModuleID = 'reduced.ll' ; ModuleID = 'reduced.ll'
; byval is currently unsupported.
; XFAIL: *
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
target triple = "thumbv7-apple-ios" target triple = "thumbv7-apple-ios"