Expand small memmovs using inline code. Set the X86 threshold for expanding
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeTypes.cpp
index cc9caf071844a01757563d928c40a6ce3d55ac1f..c0cfe216bfe2f3c2a9f729b6d8964f8b34fb330a 100644 (file)
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "LegalizeTypes.h"
+#include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Support/CommandLine.h"
@@ -137,7 +138,7 @@ NodeDone:
     
     for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end();
          UI != E; ++UI) {
-      SDNode *User = *UI;
+      SDNode *User = UI->getUser();
       int NodeID = User->getNodeId();
       assert(NodeID != ReadyToProcess && NodeID != Processed &&
              "Invalid node id for user of unprocessed node!");
@@ -267,6 +268,51 @@ void DAGTypeLegalizer::AnalyzeNewNode(SDNode *&N) {
     Worklist.push_back(N);
 }
 
+void DAGTypeLegalizer::SanityCheck(SDNode *N) {
+  for (SmallVector<SDNode*, 128>::iterator I = Worklist.begin(),
+       E = Worklist.end(); I != E; ++I)
+    assert(*I != N);
+
+  for (DenseMap<SDOperand, SDOperand>::iterator I = ReplacedNodes.begin(),
+       E = ReplacedNodes.end(); I != E; ++I) {
+    assert(I->first.Val != N);
+    assert(I->second.Val != N);
+  }
+
+  for (DenseMap<SDOperand, SDOperand>::iterator I = PromotedNodes.begin(),
+       E = PromotedNodes.end(); I != E; ++I) {
+    assert(I->first.Val != N);
+    assert(I->second.Val != N);
+  }
+
+  for (DenseMap<SDOperand, SDOperand>::iterator
+       I = FloatToIntedNodes.begin(),
+       E = FloatToIntedNodes.end(); I != E; ++I) {
+    assert(I->first.Val != N);
+    assert(I->second.Val != N);
+  }
+
+  for (DenseMap<SDOperand, SDOperand>::iterator I = ScalarizedNodes.begin(),
+       E = ScalarizedNodes.end(); I != E; ++I) {
+    assert(I->first.Val != N);
+    assert(I->second.Val != N);
+  }
+
+  for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
+       I = ExpandedNodes.begin(), E = ExpandedNodes.end(); I != E; ++I) {
+    assert(I->first.Val != N);
+    assert(I->second.first.Val != N);
+    assert(I->second.second.Val != N);
+  }
+
+  for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
+       I = SplitNodes.begin(), E = SplitNodes.end(); I != E; ++I) {
+    assert(I->first.Val != N);
+    assert(I->second.first.Val != N);
+    assert(I->second.second.Val != N);
+  }
+}
+
 namespace {
   /// NodeUpdateListener - This class is a DAGUpdateListener that listens for
   /// updates to nodes and recomputes their ready state.
@@ -281,6 +327,9 @@ namespace {
       assert(N->getNodeId() != DAGTypeLegalizer::Processed &&
              N->getNodeId() != DAGTypeLegalizer::ReadyToProcess &&
              "RAUW deleted processed node!");
+#ifndef NDEBUG
+      DTL.SanityCheck(N);
+#endif
     }
 
     virtual void NodeUpdated(SDNode *N) {
@@ -439,51 +488,6 @@ SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op,
   return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0);
 }
 
-/// HandleMemIntrinsic - This handles memcpy/memset/memmove with invalid
-/// operands.  This promotes or expands the operands as required.
-SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) {
-  // The chain and pointer [operands #0 and #1] are always valid types.
-  SDOperand Chain = N->getOperand(0);
-  SDOperand Ptr   = N->getOperand(1);
-  SDOperand Op2   = N->getOperand(2);
-  
-  // Op #2 is either a value (memset) or a pointer.  Promote it if required.
-  switch (getTypeAction(Op2.getValueType())) {
-  default: assert(0 && "Unknown action for pointer/value operand");
-  case Legal: break;
-  case Promote: Op2 = GetPromotedOp(Op2); break;
-  }
-
-  // The length could have any action required.
-  SDOperand Length = N->getOperand(3);
-  switch (getTypeAction(Length.getValueType())) {
-  default: assert(0 && "Unknown action for memop operand");
-  case Legal: break;
-  case Promote: Length = GetPromotedZExtOp(Length); break;
-  case Expand:
-    SDOperand Dummy;  // discard the high part.
-    GetExpandedOp(Length, Length, Dummy);
-    break;
-  }
-
-  SDOperand Align = N->getOperand(4);
-  switch (getTypeAction(Align.getValueType())) {
-  default: assert(0 && "Unknown action for memop operand");
-  case Legal: break;
-  case Promote: Align = GetPromotedZExtOp(Align); break;
-  }
-
-  SDOperand AlwaysInline = N->getOperand(5);
-  switch (getTypeAction(AlwaysInline.getValueType())) {
-  default: assert(0 && "Unknown action for memop operand");
-  case Legal: break;
-  case Promote: AlwaysInline = GetPromotedZExtOp(AlwaysInline); break;
-  }
-
-  SDOperand Ops[] = { Chain, Ptr, Op2, Length, Align, AlwaysInline };
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6);
-}
-
 /// JoinIntegers - Build an integer with low bits Lo and high bits Hi.
 SDOperand DAGTypeLegalizer::JoinIntegers(SDOperand Lo, SDOperand Hi) {
   MVT::ValueType LVT = Lo.getValueType();
@@ -521,6 +525,32 @@ void DAGTypeLegalizer::SplitInteger(SDOperand Op,
   SplitInteger(Op, HalfVT, HalfVT, Lo, Hi);
 }
 
+/// MakeLibCall - Generate a libcall taking the given operands as arguments and
+/// returning a result of type RetVT.
+SDOperand DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT::ValueType RetVT,
+                                        const SDOperand *Ops, unsigned NumOps,
+                                        bool isSigned) {
+  TargetLowering::ArgListTy Args;
+  Args.reserve(NumOps);
+
+  TargetLowering::ArgListEntry Entry;
+  for (unsigned i = 0; i != NumOps; ++i) {
+    Entry.Node = Ops[i];
+    Entry.Ty = MVT::getTypeForValueType(Entry.Node.getValueType());
+    Entry.isSExt = isSigned;
+    Entry.isZExt = !isSigned;
+    Args.push_back(Entry);
+  }
+  SDOperand Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
+                                           TLI.getPointerTy());
+
+  const Type *RetTy = MVT::getTypeForValueType(RetVT);
+  std::pair<SDOperand,SDOperand> CallInfo =
+    TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
+                    CallingConv::C, false, Callee, Args, DAG);
+  return CallInfo.first;
+}
+
 //===----------------------------------------------------------------------===//
 //  Entry Point
 //===----------------------------------------------------------------------===//