summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStuart Hastings <stuart@apple.com>2010-12-09 21:25:20 +0000
committerStuart Hastings <stuart@apple.com>2010-12-09 21:25:20 +0000
commita304d02791b3e0297a9d545e0c602c9f916691f9 (patch)
tree41f6548b3e1efcfc4b4eb2ab2c0d3be6ac7ababf /lib
parentff092faffb85410b0013fb70bc991bb98b5663a5 (diff)
downloadllvm-a304d02791b3e0297a9d545e0c602c9f916691f9.tar.gz
llvm-a304d02791b3e0297a9d545e0c602c9f916691f9.tar.bz2
llvm-a304d02791b3e0297a9d545e0c602c9f916691f9.tar.xz
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')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp32
1 files changed, 24 insertions, 8 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index aff087f61e..de6863a71c 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