Remove checking that prevented overlapping CALLSEQ_START/CALLSEQ_END

ranges, add legalizer support for nested calls.  Necessary for ARM
byval support.  Radar 7662569.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123704 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Stuart Hastings 2011-01-18 00:09:27 +00:00
parent edd0924d84
commit f22432282c

View File

@ -66,11 +66,6 @@ class SelectionDAGLegalize {
/// against each other, including inserted libcalls. /// against each other, including inserted libcalls.
SDValue LastCALLSEQ_END; 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;
enum LegalizeAction { enum LegalizeAction {
Legal, // The target natively supports this operation. Legal, // The target natively supports this operation.
Promote, // This operation should be executed in a larger type. Promote, // This operation should be executed in a larger type.
@ -225,7 +220,6 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag,
void SelectionDAGLegalize::LegalizeDAG() { void SelectionDAGLegalize::LegalizeDAG() {
LastCALLSEQ_END = 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
@ -1024,6 +1018,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
} }
break; break;
case ISD::CALLSEQ_START: { case ISD::CALLSEQ_START: {
static int depth = 0;
SDNode *CallEnd = FindCallEndFromCallStart(Node); SDNode *CallEnd = FindCallEndFromCallStart(Node);
// 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
@ -1041,7 +1036,7 @@ 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 (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) { if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken && depth == 0) {
Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Tmp1, LastCALLSEQ_END); Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1); Tmp1 = LegalizeOp(Tmp1);
@ -1064,14 +1059,18 @@ 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!");
SDValue Saved_LastCALLSEQ_END = LastCALLSEQ_END ;
// Note that we are selecting this call! // Note that we are selecting this call!
LastCALLSEQ_END = SDValue(CallEnd, 0); LastCALLSEQ_END = SDValue(CallEnd, 0);
IsLegalizingCall = true;
depth++;
// Legalize the call, starting from the CALLSEQ_END. // Legalize the call, starting from the CALLSEQ_END.
LegalizeOp(LastCALLSEQ_END); LegalizeOp(LastCALLSEQ_END);
assert(!IsLegalizingCall && "CALLSEQ_END should have cleared this!"); depth--;
assert(depth >= 0 && "Un-matched CALLSEQ_START?");
if (depth > 0)
LastCALLSEQ_END = Saved_LastCALLSEQ_END;
return Result; return Result;
} }
case ISD::CALLSEQ_END: case ISD::CALLSEQ_END:
@ -1110,10 +1109,7 @@ 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.
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));
if (Node->getNumValues() == 2) if (Node->getNumValues() == 2)
@ -1949,7 +1945,6 @@ 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.
@ -1997,7 +1992,6 @@ 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;