Fix a problem that nate reduced for me.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeDAG.cpp
index 135045582db63b9ec48516c6bfe786acb6ed5fa3..793037930c0159f80c2cd75ff0f68cf86eec9dc2 100644 (file)
@@ -323,10 +323,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     break;
   }
 
-  case ISD::ADJCALLSTACKDOWN:
-  case ISD::ADJCALLSTACKUP:
+  case ISD::CALLSEQ_START:
+  case ISD::CALLSEQ_END:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    // There is no need to legalize the size argument (Operand #1)
+    // Do not try to legalize the target-specific arguments (#1+)
     Tmp2 = Node->getOperand(0);
     if (Tmp1 != Tmp2) {
       Node->setAdjCallChain(Tmp1);
@@ -339,7 +339,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         DAG.getNode(ISD::PCMARKER, MVT::Other, Tmp2,
                     DAG.getConstant(0, MVT::i32));
     }
-    // Note that we do not create new ADJCALLSTACK DOWN/UP nodes here.  These
+    // Note that we do not create new CALLSEQ_DOWN/UP nodes here.  These
     // nodes are treated specially and are mutated in place.  This makes the dag
     // legalization process more efficient and also makes libcall insertion
     // easier.
@@ -928,7 +928,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       }
 
       std::pair<SDOperand,SDOperand> CallResult =
-        TLI.LowerCallTo(Tmp1, Type::VoidTy, false,
+        TLI.LowerCallTo(Tmp1, Type::VoidTy, false, 0,
                         DAG.getExternalSymbol(FnName, IntPtr), Args, DAG);
       Result = LegalizeOp(CallResult.second);
       break;
@@ -1253,7 +1253,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         Args.push_back(std::make_pair(Tmp1, T));
         // FIXME: should use ExpandLibCall!
         std::pair<SDOperand,SDOperand> CallResult =
-          TLI.LowerCallTo(DAG.getEntryNode(), T, false,
+          TLI.LowerCallTo(DAG.getEntryNode(), T, false, 0,
                           DAG.getExternalSymbol(FnName, VT), Args, DAG);
         Result = LegalizeOp(CallResult.first);
         break;
@@ -1939,15 +1939,15 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt,
   return true;
 }
 
-/// FindLatestAdjCallStackDown - Scan up the dag to find the latest (highest
-/// NodeDepth) node that is an AdjCallStackDown operation and occurs later than
+/// FindLatestCallSeqStart - Scan up the dag to find the latest (highest
+/// NodeDepth) node that is an CallSeqStart operation and occurs later than
 /// Found.
-static void FindLatestAdjCallStackDown(SDNode *Node, SDNode *&Found) {
+static void FindLatestCallSeqStart(SDNode *Node, SDNode *&Found) {
   if (Node->getNodeDepth() <= Found->getNodeDepth()) return;
 
-  // If we found an ADJCALLSTACKDOWN, we already know this node occurs later
+  // If we found an CALLSEQ_START, we already know this node occurs later
   // than the Found node. Just remember this node and return.
-  if (Node->getOpcode() == ISD::ADJCALLSTACKDOWN) {
+  if (Node->getOpcode() == ISD::CALLSEQ_START) {
     Found = Node;
     return;
   }
@@ -1956,23 +1956,23 @@ static void FindLatestAdjCallStackDown(SDNode *Node, SDNode *&Found) {
   assert(Node->getNumOperands() != 0 &&
          "All leaves should have depth equal to the entry node!");
   for (unsigned i = 0, e = Node->getNumOperands()-1; i != e; ++i)
-    FindLatestAdjCallStackDown(Node->getOperand(i).Val, Found);
+    FindLatestCallSeqStart(Node->getOperand(i).Val, Found);
 
   // Tail recurse for the last iteration.
-  FindLatestAdjCallStackDown(Node->getOperand(Node->getNumOperands()-1).Val,
+  FindLatestCallSeqStart(Node->getOperand(Node->getNumOperands()-1).Val,
                              Found);
 }
 
 
-/// FindEarliestAdjCallStackUp - Scan down the dag to find the earliest (lowest
-/// NodeDepth) node that is an AdjCallStackUp operation and occurs more recent
+/// FindEarliestCallSeqEnd - Scan down the dag to find the earliest (lowest
+/// NodeDepth) node that is an CallSeqEnd operation and occurs more recent
 /// than Found.
-static void FindEarliestAdjCallStackUp(SDNode *Node, SDNode *&Found) {
+static void FindEarliestCallSeqEnd(SDNode *Node, SDNode *&Found) {
   if (Found && Node->getNodeDepth() >= Found->getNodeDepth()) return;
 
-  // If we found an ADJCALLSTACKUP, we already know this node occurs earlier
+  // If we found an CALLSEQ_END, we already know this node occurs earlier
   // than the Found node. Just remember this node and return.
-  if (Node->getOpcode() == ISD::ADJCALLSTACKUP) {
+  if (Node->getOpcode() == ISD::CALLSEQ_END) {
     Found = Node;
     return;
   }
@@ -1981,49 +1981,50 @@ static void FindEarliestAdjCallStackUp(SDNode *Node, SDNode *&Found) {
   SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
   if (UI == E) return;
   for (--E; UI != E; ++UI)
-    FindEarliestAdjCallStackUp(*UI, Found);
+    FindEarliestCallSeqEnd(*UI, Found);
 
   // Tail recurse for the last iteration.
-  FindEarliestAdjCallStackUp(*UI, Found);
+  FindEarliestCallSeqEnd(*UI, Found);
 }
 
-/// FindAdjCallStackUp - Given a chained node that is part of a call sequence,
-/// find the ADJCALLSTACKUP node that terminates the call sequence.
-static SDNode *FindAdjCallStackUp(SDNode *Node) {
-  if (Node->getOpcode() == ISD::ADJCALLSTACKUP)
+/// FindCallSeqEnd - Given a chained node that is part of a call sequence,
+/// find the CALLSEQ_END node that terminates the call sequence.
+static SDNode *FindCallSeqEnd(SDNode *Node) {
+  if (Node->getOpcode() == ISD::CALLSEQ_END)
     return Node;
   if (Node->use_empty())
-    return 0;   // No adjcallstackup
+    return 0;   // No CallSeqEnd
 
   if (Node->hasOneUse())  // Simple case, only has one user to check.
-    return FindAdjCallStackUp(*Node->use_begin());
+    return FindCallSeqEnd(*Node->use_begin());
 
   SDOperand TheChain(Node, Node->getNumValues()-1);
   assert(TheChain.getValueType() == MVT::Other && "Is not a token chain!");
 
   for (SDNode::use_iterator UI = Node->use_begin(),
          E = Node->use_end(); ; ++UI) {
-    assert(UI != E && "Didn't find a user of the tokchain, no ADJCALLSTACKUP!");
+    assert(UI != E && "Didn't find a user of the tokchain, no CALLSEQ_END!");
 
     // Make sure to only follow users of our token chain.
     SDNode *User = *UI;
     for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
       if (User->getOperand(i) == TheChain)
-        return FindAdjCallStackUp(User);
+        if (SDNode *Result = FindCallSeqEnd(User))
+          return Result;
   }
   assert(0 && "Unreachable");
   abort();
 }
 
-/// FindAdjCallStackDown - Given a chained node that is part of a call sequence,
-/// find the ADJCALLSTACKDOWN node that initiates the call sequence.
-static SDNode *FindAdjCallStackDown(SDNode *Node) {
-  assert(Node && "Didn't find adjcallstackdown for a call??");
-  if (Node->getOpcode() == ISD::ADJCALLSTACKDOWN) return Node;
+/// FindCallSeqStart - Given a chained node that is part of a call sequence,
+/// find the CALLSEQ_START node that initiates the call sequence.
+static SDNode *FindCallSeqStart(SDNode *Node) {
+  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 FindAdjCallStackDown(Node->getOperand(0).Val);
+  return FindCallSeqStart(Node->getOperand(0).Val);
 }
 
 
@@ -2035,31 +2036,31 @@ static SDNode *FindAdjCallStackDown(SDNode *Node) {
 /// end of the call chain.
 static SDOperand FindInputOutputChains(SDNode *OpNode, SDNode *&OutChain,
                                        SDOperand Entry) {
-  SDNode *LatestAdjCallStackDown = Entry.Val;
-  SDNode *LatestAdjCallStackUp = 0;
-  FindLatestAdjCallStackDown(OpNode, LatestAdjCallStackDown);
-  //std::cerr<<"Found node: "; LatestAdjCallStackDown->dump(); std::cerr <<"\n";
+  SDNode *LatestCallSeqStart = Entry.Val;
+  SDNode *LatestCallSeqEnd = 0;
+  FindLatestCallSeqStart(OpNode, LatestCallSeqStart);
+  //std::cerr<<"Found node: "; LatestCallSeqStart->dump(); std::cerr <<"\n";
 
-  // It is possible that no ISD::ADJCALLSTACKDOWN was found because there is no
+  // It is possible that no ISD::CALLSEQ_START was found because there is no
   // previous call in the function.  LatestCallStackDown may in that case be
-  // the entry node itself.  Do not attempt to find a matching ADJCALLSTACKUP
-  // unless LatestCallStackDown is an ADJCALLSTACKDOWN.
-  if (LatestAdjCallStackDown->getOpcode() == ISD::ADJCALLSTACKDOWN)
-    LatestAdjCallStackUp = FindAdjCallStackUp(LatestAdjCallStackDown);
+  // the entry node itself.  Do not attempt to find a matching CALLSEQ_END
+  // unless LatestCallStackDown is an CALLSEQ_START.
+  if (LatestCallSeqStart->getOpcode() == ISD::CALLSEQ_START)
+    LatestCallSeqEnd = FindCallSeqEnd(LatestCallSeqStart);
   else
-    LatestAdjCallStackUp = Entry.Val;
-  assert(LatestAdjCallStackUp && "NULL return from FindAdjCallStackUp");
+    LatestCallSeqEnd = Entry.Val;
+  assert(LatestCallSeqEnd && "NULL return from FindCallSeqEnd");
 
   // Finally, find the first call that this must come before, first we find the
-  // adjcallstackup that ends the call.
+  // CallSeqEnd that ends the call.
   OutChain = 0;
-  FindEarliestAdjCallStackUp(OpNode, OutChain);
+  FindEarliestCallSeqEnd(OpNode, OutChain);
 
-  // If we found one, translate from the adj up to the adjdown.
+  // If we found one, translate from the adj up to the callseq_start.
   if (OutChain)
-    OutChain = FindAdjCallStackDown(OutChain);
+    OutChain = FindCallSeqStart(OutChain);
 
-  return SDOperand(LatestAdjCallStackUp, 0);
+  return SDOperand(LatestCallSeqEnd, 0);
 }
 
 /// SpliceCallInto - Given the result chain of a libcall (CallResult), and a 
@@ -2102,7 +2103,7 @@ SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node,
   // Splice the libcall in wherever FindInputOutputChains tells us to.
   const Type *RetTy = MVT::getTypeForValueType(Node->getValueType(0));
   std::pair<SDOperand,SDOperand> CallInfo =
-    TLI.LowerCallTo(InChain, RetTy, false, Callee, Args, DAG);
+    TLI.LowerCallTo(InChain, RetTy, false, 0, Callee, Args, DAG);
   SpliceCallInto(CallInfo.second, OutChain);
 
   NeedsAnotherIteration = true;
@@ -2131,10 +2132,6 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
   assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!");
 
   if (!isSigned) {
-    // If this is unsigned, and not supported, first perform the conversion to
-    // signed, then adjust the result if the sign bit is set.
-    SDOperand SignedConv = ExpandIntToFP(true, DestTy, Source);
-
     assert(Source.getValueType() == MVT::i64 &&
            "This only works for 64-bit -> FP");
     // The 64-bit value loaded will be incorrectly if the 'sign bit' of the
@@ -2143,6 +2140,11 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
     SDOperand Lo, Hi;
     ExpandOp(Source, Lo, Hi);
 
+    // If this is unsigned, and not supported, first perform the conversion to
+    // signed, then adjust the result if the sign bit is set.
+    SDOperand SignedConv = ExpandIntToFP(true, DestTy,
+                   DAG.getNode(ISD::BUILD_PAIR, Source.getValueType(), Lo, Hi));
+
     SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(), Hi,
                                      DAG.getConstant(0, Hi.getValueType()));
     SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
@@ -2198,7 +2200,7 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
   const Type *RetTy = MVT::getTypeForValueType(DestTy);
 
   std::pair<SDOperand,SDOperand> CallResult =
-    TLI.LowerCallTo(InChain, RetTy, false, Callee, Args, DAG);
+    TLI.LowerCallTo(InChain, RetTy, false, 0, Callee, Args, DAG);
 
   SpliceCallInto(CallResult.second, OutChain);
   return CallResult.first;