Initial infrastructure for arbitrary precision integer
codegen support.  This should have no effect on codegen
for other types.  Debatable bits: (1) the use (abuse?)
of a set in SDNode::getValueTypeList; (2) the length of
getTypeToTransformTo, which maybe should be refactored
with a non-inline part for extended value types.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43030 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b1b3bd4..d295a60 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -28,6 +28,7 @@
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include <algorithm>
@@ -846,6 +847,7 @@
 }
 
 SDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
+  assert(!MVT::isExtendedVT(VT) && "Expecting a simple value type!");
   if ((unsigned)VT >= ValueTypeNodes.size())
     ValueTypeNodes.resize(VT+1);
   if (ValueTypeNodes[VT] == 0) {
@@ -1734,7 +1736,8 @@
     assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
            "Invalid SIGN_EXTEND!");
     if (Operand.getValueType() == VT) return Operand;   // noop extension
-    assert(Operand.getValueType() < VT && "Invalid sext node, dst < src!");
+    assert(MVT::getSizeInBits(Operand.getValueType()) < MVT::getSizeInBits(VT)
+           && "Invalid sext node, dst < src!");
     if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND)
       return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
     break;
@@ -1742,7 +1745,8 @@
     assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
            "Invalid ZERO_EXTEND!");
     if (Operand.getValueType() == VT) return Operand;   // noop extension
-    assert(Operand.getValueType() < VT && "Invalid zext node, dst < src!");
+    assert(MVT::getSizeInBits(Operand.getValueType()) < MVT::getSizeInBits(VT)
+           && "Invalid zext node, dst < src!");
     if (OpOpcode == ISD::ZERO_EXTEND)   // (zext (zext x)) -> (zext x)
       return getNode(ISD::ZERO_EXTEND, VT, Operand.Val->getOperand(0));
     break;
@@ -1750,7 +1754,8 @@
     assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
            "Invalid ANY_EXTEND!");
     if (Operand.getValueType() == VT) return Operand;   // noop extension
-    assert(Operand.getValueType() < VT && "Invalid anyext node, dst < src!");
+    assert(MVT::getSizeInBits(Operand.getValueType()) < MVT::getSizeInBits(VT)
+           && "Invalid anyext node, dst < src!");
     if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND)
       // (ext (zext x)) -> (zext x)  and  (ext (sext x)) -> (sext x)
       return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
@@ -1759,15 +1764,18 @@
     assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
            "Invalid TRUNCATE!");
     if (Operand.getValueType() == VT) return Operand;   // noop truncate
-    assert(Operand.getValueType() > VT && "Invalid truncate node, src < dst!");
+    assert(MVT::getSizeInBits(Operand.getValueType()) > MVT::getSizeInBits(VT)
+           && "Invalid truncate node, src < dst!");
     if (OpOpcode == ISD::TRUNCATE)
       return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
     else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND ||
              OpOpcode == ISD::ANY_EXTEND) {
       // If the source is smaller than the dest, we still need an extend.
-      if (Operand.Val->getOperand(0).getValueType() < VT)
+      if (MVT::getSizeInBits(Operand.Val->getOperand(0).getValueType())
+          < MVT::getSizeInBits(VT))
         return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
-      else if (Operand.Val->getOperand(0).getValueType() > VT)
+      else if (MVT::getSizeInBits(Operand.Val->getOperand(0).getValueType())
+               > MVT::getSizeInBits(VT))
         return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
       else
         return Operand.Val->getOperand(0);
@@ -1874,7 +1882,8 @@
     assert(VT == N1.getValueType() && "Not an inreg round!");
     assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
            "Cannot FP_ROUND_INREG integer types");
-    assert(EVT <= VT && "Not rounding down!");
+    assert(MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(VT) &&
+           "Not rounding down!");
     break;
   }
   case ISD::AssertSext:
@@ -1884,7 +1893,8 @@
     assert(VT == N1.getValueType() && "Not an inreg extend!");
     assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
            "Cannot *_EXTEND_INREG FP types");
-    assert(EVT <= VT && "Not extending!");
+    assert(MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(VT) &&
+           "Not extending!");
   }
 
   default: break;
@@ -2299,7 +2309,8 @@
   if (MVT::isVector(VT))
     assert(EVT == MVT::getVectorElementType(VT) && "Invalid vector extload!");
   else
-    assert(EVT < VT && "Should only be an extending load, not truncating!");
+    assert(MVT::getSizeInBits(EVT) < MVT::getSizeInBits(VT) &&
+           "Should only be an extending load, not truncating!");
   assert((ExtType == ISD::EXTLOAD || MVT::isInteger(VT)) &&
          "Cannot sign/zero extend a FP/Vector load!");
   assert(MVT::isInteger(VT) == MVT::isInteger(EVT) &&
@@ -2415,7 +2426,8 @@
   MVT::ValueType VT = Val.getValueType();
   bool isTrunc = VT != SVT;
 
-  assert(VT > SVT && "Not a truncation?");
+  assert(MVT::getSizeInBits(VT) > MVT::getSizeInBits(SVT) &&
+         "Not a truncation?");
   assert(MVT::isInteger(VT) == MVT::isInteger(SVT) &&
          "Can't do FP-INT conversion!");
 
@@ -2648,18 +2660,7 @@
 }
 
 SDVTList SelectionDAG::getVTList(MVT::ValueType VT) {
-  if (!MVT::isExtendedVT(VT))
-    return makeVTList(SDNode::getValueTypeList(VT), 1);
-
-  for (std::list<std::vector<MVT::ValueType> >::iterator I = VTList.begin(),
-       E = VTList.end(); I != E; ++I) {
-    if (I->size() == 1 && (*I)[0] == VT)
-      return makeVTList(&(*I)[0], 1);
-  }
-  std::vector<MVT::ValueType> V;
-  V.push_back(VT);
-  VTList.push_front(V);
-  return makeVTList(&(*VTList.begin())[0], 1);
+  return makeVTList(SDNode::getValueTypeList(VT), 1);
 }
 
 SDVTList SelectionDAG::getVTList(MVT::ValueType VT1, MVT::ValueType VT2) {
@@ -3427,11 +3428,16 @@
 /// getValueTypeList - Return a pointer to the specified value type.
 ///
 MVT::ValueType *SDNode::getValueTypeList(MVT::ValueType VT) {
-  static MVT::ValueType VTs[MVT::LAST_VALUETYPE];
-  VTs[VT] = VT;
-  return &VTs[VT];
+  if (MVT::isExtendedVT(VT)) {
+    static std::set<MVT::ValueType> EVTs;
+    return (MVT::ValueType *)&(*EVTs.insert(VT).first);
+  } else {
+    static MVT::ValueType VTs[MVT::LAST_VALUETYPE];
+    VTs[VT] = VT;
+    return &VTs[VT];
+  }
 }
-  
+
 /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
 /// indicated value.  This method ignores uses of other values defined by this
 /// operation.