diff options
author | Stuart Hastings <stuart@apple.com> | 2010-12-09 21:25:20 +0000 |
---|---|---|
committer | Stuart Hastings <stuart@apple.com> | 2010-12-09 21:25:20 +0000 |
commit | a304d02791b3e0297a9d545e0c602c9f916691f9 (patch) | |
tree | 41f6548b3e1efcfc4b4eb2ab2c0d3be6ac7ababf /lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | |
parent | ff092faffb85410b0013fb70bc991bb98b5663a5 (diff) | |
download | external_llvm-a304d02791b3e0297a9d545e0c602c9f916691f9.zip external_llvm-a304d02791b3e0297a9d545e0c602c9f916691f9.tar.gz external_llvm-a304d02791b3e0297a9d545e0c602c9f916691f9.tar.bz2 |
Initial support for nested CALLSEQ_START/CALLSEQ_END constructs in LegalizeDAG.
Necessary for byval support on ARM. Radar 7662569.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121412 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index aff087f..de6863a 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -252,8 +252,10 @@ void SelectionDAGLegalize::LegalizeDAG() { /// FindCallEndFromCallStart - Given a chained node that is part of a call /// sequence, find the CALLSEQ_END node that terminates the call sequence. -static SDNode *FindCallEndFromCallStart(SDNode *Node) { - if (Node->getOpcode() == ISD::CALLSEQ_END) +static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { + if (Node->getOpcode() == ISD::CALLSEQ_START) + depth++; + if ((Node->getOpcode() == ISD::CALLSEQ_END) && (depth == 1)) return Node; if (Node->use_empty()) return 0; // No CallSeqEnd @@ -284,7 +286,7 @@ static SDNode *FindCallEndFromCallStart(SDNode *Node) { SDNode *User = *UI; for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) if (User->getOperand(i) == TheChain) - if (SDNode *Result = FindCallEndFromCallStart(User)) + if (SDNode *Result = FindCallEndFromCallStart(User, depth)) return Result; } return 0; @@ -293,12 +295,26 @@ static SDNode *FindCallEndFromCallStart(SDNode *Node) { /// FindCallStartFromCallEnd - Given a chained node that is part of a call /// sequence, find the CALLSEQ_START node that initiates the call sequence. static SDNode *FindCallStartFromCallEnd(SDNode *Node) { + int nested = 0; assert(Node && "Didn't find callseq_start for a call??"); - if (Node->getOpcode() == ISD::CALLSEQ_START) return Node; - - assert(Node->getOperand(0).getValueType() == MVT::Other && - "Node doesn't have a token chain argument!"); - return FindCallStartFromCallEnd(Node->getOperand(0).getNode()); + while (Node->getOpcode() != ISD::CALLSEQ_START || nested) { + Node = Node->getOperand(0).getNode(); + assert(Node->getOperand(0).getValueType() == MVT::Other && + "Node doesn't have a token chain argument!"); + switch (Node->getOpcode()) { + default: + break; + case ISD::CALLSEQ_START: + if (!nested) + return Node; + nested--; + break; + case ISD::CALLSEQ_END: + nested++; + break; + } + } + return 0; } /// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to |