[llvm-commits] [llvm] r98534 - in /llvm/trunk/utils/TableGen: CodeGenDAGPatterns.cpp CodeGenDAGPatterns.h CodeGenTarget.cpp CodeGenTarget.h DAGISelEmitter.cpp DAGISelMatcherGen.cpp FastISelEmitter.cpp

Chris Lattner sabre at nondot.org
Sun Mar 14 23:00:16 PDT 2010


Author: lattner
Date: Mon Mar 15 01:00:16 2010
New Revision: 98534

URL: http://llvm.org/viewvc/llvm-project?rev=98534&view=rev
Log:
Completely rewrite tblgen's type inference mechanism,
changing the primary datastructure from being a 
"std::vector<unsigned char>" to being a new TypeSet class
that actually has (gasp) invariants!

This changes more things than I remember, but one major
innovation here is that it enforces that named input 
values agree in type with their output values.

This also eliminates code that transparently assumes (in 
some cases) that SDNodeXForm input/output types are the
same, because this is wrong in many case.

This also eliminates a bug which caused a lot of ambiguous
patterns to go undetected, where a register class would
sometimes pick the first possible type, causing an
ambiguous pattern to get arbitrary results.

With all the recent target changes, this causes no 
functionality change!

Modified:
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
    llvm/trunk/utils/TableGen/CodeGenTarget.cpp
    llvm/trunk/utils/TableGen/CodeGenTarget.h
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
    llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
    llvm/trunk/utils/TableGen/FastISelEmitter.cpp

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=98534&r1=98533&r2=98534&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon Mar 15 01:00:16 2010
@@ -15,44 +15,17 @@
 #include "CodeGenDAGPatterns.h"
 #include "Record.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Debug.h"
 #include <set>
 #include <algorithm>
-#include <iostream>
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
-// Helpers for working with extended types.
-
-/// FilterVTs - Filter a list of VT's according to a predicate.
-///
-template<typename T>
-static std::vector<MVT::SimpleValueType>
-FilterVTs(const std::vector<MVT::SimpleValueType> &InVTs, T Filter) {
-  std::vector<MVT::SimpleValueType> Result;
-  for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
-    if (Filter(InVTs[i]))
-      Result.push_back(InVTs[i]);
-  return Result;
-}
-
-template<typename T>
-static std::vector<unsigned char> 
-FilterEVTs(const std::vector<unsigned char> &InVTs, T Filter) {
-  std::vector<unsigned char> Result;
-  for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
-    if (Filter((MVT::SimpleValueType)InVTs[i]))
-      Result.push_back(InVTs[i]);
-  return Result;
-}
+//  EEVT::TypeSet Implementation
+//===----------------------------------------------------------------------===//
 
-static std::vector<unsigned char>
-ConvertVTs(const std::vector<MVT::SimpleValueType> &InVTs) {
-  std::vector<unsigned char> Result;
-  for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
-    Result.push_back(InVTs[i]);
-  return Result;
-}
+// FIXME: Remove EEVT::isUnknown!
 
 static inline bool isInteger(MVT::SimpleValueType VT) {
   return EVT(VT).isInteger();
@@ -66,39 +39,361 @@
   return EVT(VT).isVector();
 }
 
-static bool LHSIsSubsetOfRHS(const std::vector<unsigned char> &LHS,
-                             const std::vector<unsigned char> &RHS) {
-  if (LHS.size() > RHS.size()) return false;
-  for (unsigned i = 0, e = LHS.size(); i != e; ++i)
-    if (std::find(RHS.begin(), RHS.end(), LHS[i]) == RHS.end())
-      return false;
-  return true;
+EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) {
+  if (VT == MVT::iAny)
+    EnforceInteger(TP);
+  else if (VT == MVT::fAny)
+    EnforceFloatingPoint(TP);
+  else if (VT == MVT::vAny)
+    EnforceVector(TP);
+  else {
+    assert((VT < MVT::LAST_VALUETYPE || VT == MVT::iPTR ||
+            VT == MVT::iPTRAny) && "Not a concrete type!");
+    TypeVec.push_back(VT);
+  }
+}
+
+
+EEVT::TypeSet::TypeSet(const std::vector<MVT::SimpleValueType> &VTList) {
+  assert(!VTList.empty() && "empty list?");
+  TypeVec.append(VTList.begin(), VTList.end());
+  
+  if (!VTList.empty())
+    assert(VTList[0] != MVT::iAny && VTList[0] != MVT::vAny &&
+           VTList[0] != MVT::fAny);
+  
+  // Remove duplicates.
+  array_pod_sort(TypeVec.begin(), TypeVec.end());
+  TypeVec.erase(std::unique(TypeVec.begin(), TypeVec.end()), TypeVec.end());
+}
+
+
+/// hasIntegerTypes - Return true if this TypeSet contains iAny or an
+/// integer value type.
+bool EEVT::TypeSet::hasIntegerTypes() const {
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
+    if (isInteger(TypeVec[i]))
+      return true;
+  return false;
+}  
+
+/// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or
+/// a floating point value type.
+bool EEVT::TypeSet::hasFloatingPointTypes() const {
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
+    if (isFloatingPoint(TypeVec[i]))
+      return true;
+  return false;
+}  
+
+/// hasVectorTypes - Return true if this TypeSet contains a vAny or a vector
+/// value type.
+bool EEVT::TypeSet::hasVectorTypes() const {
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
+    if (isVector(TypeVec[i]))
+      return true;
+  return false;
+}
+
+
+std::string EEVT::TypeSet::getName() const {
+  if (TypeVec.empty()) return "isUnknown";
+  
+  std::string Result;
+    
+  for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) {
+    std::string VTName = llvm::getEnumName(TypeVec[i]);
+    // Strip off MVT:: prefix if present.
+    if (VTName.substr(0,5) == "MVT::")
+      VTName = VTName.substr(5);
+    if (i) Result += ':';
+    Result += VTName;
+  }
+  
+  if (TypeVec.size() == 1)
+    return Result;
+  return "{" + Result + "}";
+}
+
+/// MergeInTypeInfo - This merges in type information from the specified
+/// argument.  If 'this' changes, it returns true.  If the two types are
+/// contradictory (e.g. merge f32 into i32) then this throws an exception.
+bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){
+  if (InVT.isCompletelyUnknown() || *this == InVT)
+    return false;
+  
+  if (isCompletelyUnknown()) {
+    *this = InVT;
+    return true;
+  }
+  
+  assert(TypeVec.size() >= 1 && InVT.TypeVec.size() >= 1 && "No unknowns");
+  
+  // Handle the abstract cases, seeing if we can resolve them better.
+  switch (TypeVec[0]) {
+  default: break;
+  case MVT::iPTR:
+  case MVT::iPTRAny:
+    if (InVT.hasIntegerTypes()) {
+      EEVT::TypeSet InCopy(InVT);
+      InCopy.EnforceInteger(TP);
+      InCopy.EnforceScalar(TP);
+      
+      if (InCopy.isConcrete()) {
+        // If the RHS has one integer type, upgrade iPTR to i32.
+        TypeVec[0] = InVT.TypeVec[0];
+        return true;
+      }
+      
+      // If the input has multiple scalar integers, this doesn't add any info.
+      if (!InCopy.isCompletelyUnknown())
+        return false;
+    }
+    break;
+  }
+  
+  // If the input constraint is iAny/iPTR and this is an integer type list,
+  // remove non-integer types from the list.
+  if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) &&
+      hasIntegerTypes()) {
+    bool MadeChange = EnforceInteger(TP);
+    
+    // If we're merging in iPTR/iPTRAny and the node currently has a list of
+    // multiple different integer types, replace them with a single iPTR.
+    if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) &&
+        TypeVec.size() != 1) {
+      TypeVec.resize(1);
+      TypeVec[0] = InVT.TypeVec[0];
+      MadeChange = true;
+    }
+    
+    return MadeChange;
+  }
+  
+  // If this is a type list and the RHS is a typelist as well, eliminate entries
+  // from this list that aren't in the other one.
+  bool MadeChange = false;
+  TypeSet InputSet(*this);
+
+  for (unsigned i = 0; i != TypeVec.size(); ++i) {
+    bool InInVT = false;
+    for (unsigned j = 0, e = InVT.TypeVec.size(); j != e; ++j)
+      if (TypeVec[i] == InVT.TypeVec[j]) {
+        InInVT = true;
+        break;
+      }
+    
+    if (InInVT) continue;
+    TypeVec.erase(TypeVec.begin()+i--);
+    MadeChange = true;
+  }
+  
+  // If we removed all of our types, we have a type contradiction.
+  if (!TypeVec.empty())
+    return MadeChange;
+  
+  // FIXME: Really want an SMLoc here!
+  TP.error("Type inference contradiction found, merging '" +
+           InVT.getName() + "' into '" + InputSet.getName() + "'");
+  return true; // unreachable
+}
+
+/// EnforceInteger - Remove all non-integer types from this set.
+bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) {
+  TypeSet InputSet(*this);
+  bool MadeChange = false;
+  
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty()) {
+    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+    MadeChange = true;
+  }
+  
+  if (!hasFloatingPointTypes())
+    return MadeChange;
+  
+  // Filter out all the fp types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (isFloatingPoint(TypeVec[i]))
+      TypeVec.erase(TypeVec.begin()+i--);
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be integer");
+  return MadeChange;
 }
 
-namespace llvm {
-namespace EEVT {
-/// isExtIntegerInVTs - Return true if the specified extended value type vector
-/// contains iAny or an integer value type.
-bool isExtIntegerInVTs(const std::vector<unsigned char> &EVTs) {
-  assert(!EVTs.empty() && "Cannot check for integer in empty ExtVT list!");
-  return EVTs[0] == MVT::iAny || !(FilterEVTs(EVTs, isInteger).empty());
-}
-
-/// isExtFloatingPointInVTs - Return true if the specified extended value type
-/// vector contains fAny or a FP value type.
-bool isExtFloatingPointInVTs(const std::vector<unsigned char> &EVTs) {
-  assert(!EVTs.empty() && "Cannot check for FP in empty ExtVT list!");
-  return EVTs[0] == MVT::fAny || !(FilterEVTs(EVTs, isFloatingPoint).empty());
-}
-
-/// isExtVectorInVTs - Return true if the specified extended value type
-/// vector contains vAny or a vector value type.
-bool isExtVectorInVTs(const std::vector<unsigned char> &EVTs) {
-  assert(!EVTs.empty() && "Cannot check for vector in empty ExtVT list!");
-  return EVTs[0] == MVT::vAny || !(FilterEVTs(EVTs, isVector).empty());
+/// EnforceFloatingPoint - Remove all integer types from this set.
+bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) {
+  TypeSet InputSet(*this);
+  bool MadeChange = false;
+  
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty()) {
+    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+    MadeChange = true;
+  }
+  
+  if (!hasIntegerTypes())
+    return MadeChange;
+  
+  // Filter out all the fp types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (isInteger(TypeVec[i]))
+      TypeVec.erase(TypeVec.begin()+i--);
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be floating point");
+  return MadeChange;
 }
-} // end namespace EEVT.
-} // end namespace llvm.
+
+/// EnforceScalar - Remove all vector types from this.
+bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) {
+  TypeSet InputSet(*this);
+  bool MadeChange = false;
+  
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty()) {
+    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+    MadeChange = true;
+  }
+  
+  if (!hasVectorTypes())
+    return MadeChange;
+  
+  // Filter out all the vector types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (isVector(TypeVec[i]))
+      TypeVec.erase(TypeVec.begin()+i--);
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be scalar");
+  return MadeChange;
+}
+
+/// EnforceVector - Remove all vector types from this.
+bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
+  TypeSet InputSet(*this);
+  bool MadeChange = false;
+  
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty()) {
+    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+    MadeChange = true;
+  }
+  
+  // Filter out all the scalar types.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (!isVector(TypeVec[i]))
+      TypeVec.erase(TypeVec.begin()+i--);
+  
+  if (TypeVec.empty())
+    TP.error("Type inference contradiction found, '" +
+             InputSet.getName() + "' needs to be a vector");
+  return MadeChange;
+}
+
+
+/// EnforceSmallerThan - 'this' must be a smaller VT than Other.  Update
+/// this an other based on this information.
+bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
+  // Both operands must be integer or FP, but we don't care which.
+  bool MadeChange = false;
+  
+  // This code does not currently handle nodes which have multiple types,
+  // where some types are integer, and some are fp.  Assert that this is not
+  // the case.
+  assert(!(hasIntegerTypes() && hasFloatingPointTypes()) &&
+         !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) &&
+         "SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
+  // If one side is known to be integer or known to be FP but the other side has
+  // no information, get at least the type integrality info in there.
+  if (hasIntegerTypes())
+    MadeChange |= Other.EnforceInteger(TP);
+  else if (hasFloatingPointTypes())
+    MadeChange |= Other.EnforceFloatingPoint(TP);
+  if (Other.hasIntegerTypes())
+    MadeChange |= EnforceInteger(TP);
+  else if (Other.hasFloatingPointTypes())
+    MadeChange |= EnforceFloatingPoint(TP);
+  
+  assert(!isCompletelyUnknown() && !Other.isCompletelyUnknown() &&
+         "Should have a type list now");
+  
+  // If one contains vectors but the other doesn't pull vectors out.
+  if (!hasVectorTypes() && Other.hasVectorTypes())
+    MadeChange |= Other.EnforceScalar(TP);
+  if (hasVectorTypes() && !Other.hasVectorTypes())
+    MadeChange |= EnforceScalar(TP);
+  
+  // FIXME: This is a bone-headed way to do this.
+  
+  // Get the set of legal VTs and filter it based on the known integrality.
+  const CodeGenTarget &CGT = TP.getDAGPatterns().getTargetInfo();
+  TypeSet LegalVTs = CGT.getLegalValueTypes();
+
+  // TODO: If one or the other side is known to be a specific VT, we could prune
+  // LegalVTs.
+  if (hasIntegerTypes())
+    LegalVTs.EnforceInteger(TP);
+  else if (hasFloatingPointTypes())
+    LegalVTs.EnforceFloatingPoint(TP);
+  else
+    return MadeChange;
+  
+  switch (LegalVTs.TypeVec.size()) {
+  case 0: assert(0 && "No legal VTs?");
+  default:         // Too many VT's to pick from.
+    // TODO: If the biggest type in LegalVTs is in this set, we could remove it.
+    // If one or the other side is known to be a specific VT, we could prune
+    // LegalVTs.
+    return MadeChange;
+  case 1: 
+    // Only one VT of this flavor.  Cannot ever satisfy the constraints.
+    return MergeInTypeInfo(MVT::Other, TP);  // throw
+  case 2:
+    // If we have exactly two possible types, the little operand must be the
+    // small one, the big operand should be the big one.  This is common with 
+    // float/double for example.
+    assert(LegalVTs.TypeVec[0] < LegalVTs.TypeVec[1] && "Should be sorted!");
+    MadeChange |= MergeInTypeInfo(LegalVTs.TypeVec[0], TP);
+    MadeChange |= Other.MergeInTypeInfo(LegalVTs.TypeVec[1], TP);
+    return MadeChange;
+  }    
+}
+
+/// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
+/// whose element is VT.
+bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT,
+                                           TreePattern &TP) {
+  TypeSet InputSet(*this);
+  bool MadeChange = false;
+  
+  // If we know nothing, then get the full set.
+  if (TypeVec.empty()) {
+    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+    MadeChange = true;
+  }
+  
+  // Filter out all the non-vector types and types which don't have the right
+  // element type.
+  for (unsigned i = 0; i != TypeVec.size(); ++i)
+    if (!isVector(TypeVec[i]) ||
+        EVT(TypeVec[i]).getVectorElementType().getSimpleVT().SimpleTy != VT) {
+      TypeVec.erase(TypeVec.begin()+i--);
+      MadeChange = true;
+    }
+  
+  if (TypeVec.empty())  // FIXME: Really want an SMLoc here!
+    TP.error("Type inference contradiction found, forcing '" +
+             InputSet.getName() + "' to have a vector element");
+  return MadeChange;
+}
+
+//===----------------------------------------------------------------------===//
+// Helpers for working with extended types.
 
 bool RecordPtrCmp::operator()(const Record *LHS, const Record *RHS) const {
   return LHS->getID() < RHS->getID();
@@ -208,8 +503,7 @@
       R->getValueAsInt("BigOperandNum");
   } else if (R->isSubClassOf("SDTCisEltOfVec")) {
     ConstraintType = SDTCisEltOfVec;
-    x.SDTCisEltOfVec_Info.OtherOperandNum =
-      R->getValueAsInt("OtherOpNum");
+    x.SDTCisEltOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum");
   } else {
     errs() << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n";
     exit(1);
@@ -255,8 +549,6 @@
                itostr(NodeInfo.getNumOperands()) + " operands!");
   }
 
-  const CodeGenTarget &CGT = TP.getDAGPatterns().getTargetInfo();
-  
   TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NumResults);
   
   switch (ConstraintType) {
@@ -264,45 +556,23 @@
   case SDTCisVT:
     // Operand must be a particular type.
     return NodeToApply->UpdateNodeType(x.SDTCisVT_Info.VT, TP);
-  case SDTCisPtrTy: {
+  case SDTCisPtrTy:
     // Operand must be same as target pointer type.
     return NodeToApply->UpdateNodeType(MVT::iPTR, TP);
-  }
-  case SDTCisInt: {
-    // If there is only one integer type supported, this must be it.
-    std::vector<MVT::SimpleValueType> IntVTs =
-      FilterVTs(CGT.getLegalValueTypes(), isInteger);
-
-    // If we found exactly one supported integer type, apply it.
-    if (IntVTs.size() == 1)
-      return NodeToApply->UpdateNodeType(IntVTs[0], TP);
-    return NodeToApply->UpdateNodeType(MVT::iAny, TP);
-  }
-  case SDTCisFP: {
-    // If there is only one FP type supported, this must be it.
-    std::vector<MVT::SimpleValueType> FPVTs =
-      FilterVTs(CGT.getLegalValueTypes(), isFloatingPoint);
-        
-    // If we found exactly one supported FP type, apply it.
-    if (FPVTs.size() == 1)
-      return NodeToApply->UpdateNodeType(FPVTs[0], TP);
-    return NodeToApply->UpdateNodeType(MVT::fAny, TP);
-  }
-  case SDTCisVec: {
-    // If there is only one vector type supported, this must be it.
-    std::vector<MVT::SimpleValueType> VecVTs =
-      FilterVTs(CGT.getLegalValueTypes(), isVector);
-        
-    // If we found exactly one supported vector type, apply it.
-    if (VecVTs.size() == 1)
-      return NodeToApply->UpdateNodeType(VecVTs[0], TP);
-    return NodeToApply->UpdateNodeType(MVT::vAny, TP);
-  }
+  case SDTCisInt:
+    // Require it to be one of the legal integer VTs.
+    return NodeToApply->getExtType().EnforceInteger(TP);
+  case SDTCisFP:
+    // Require it to be one of the legal fp VTs.
+    return NodeToApply->getExtType().EnforceFloatingPoint(TP);
+  case SDTCisVec:
+    // Require it to be one of the legal vector VTs.
+    return NodeToApply->getExtType().EnforceVector(TP);
   case SDTCisSameAs: {
     TreePatternNode *OtherNode =
       getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NumResults);
-    return NodeToApply->UpdateNodeType(OtherNode->getExtTypes(), TP) |
-           OtherNode->UpdateNodeType(NodeToApply->getExtTypes(), TP);
+    return NodeToApply->UpdateNodeType(OtherNode->getExtType(), TP) |
+           OtherNode->UpdateNodeType(NodeToApply->getExtType(), TP);
   }
   case SDTCisVTSmallerThanOp: {
     // The NodeToApply must be a leaf node that is a VT.  OtherOperandNum must
@@ -321,78 +591,37 @@
       getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N,NumResults);
     
     // It must be integer.
-    bool MadeChange = OtherNode->UpdateNodeType(MVT::iAny, TP);
-    
-    // This code only handles nodes that have one type set.  Assert here so
-    // that we can change this if we ever need to deal with multiple value
-    // types at this point.
-    assert(OtherNode->getExtTypes().size() == 1 && "Node has too many types!");
-    if (OtherNode->hasTypeSet() && OtherNode->getTypeNum(0) <= VT)
+    bool MadeChange = OtherNode->getExtType().EnforceInteger(TP);
+
+    // This doesn't try to enforce any information on the OtherNode, it just
+    // validates it when information is determined.
+    if (OtherNode->hasTypeSet() && OtherNode->getType() <= VT)
       OtherNode->UpdateNodeType(MVT::Other, TP);  // Throw an error.
     return MadeChange;
   }
   case SDTCisOpSmallerThanOp: {
     TreePatternNode *BigOperand =
       getOperandNum(x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NumResults);
-
-    // Both operands must be integer or FP, but we don't care which.
-    bool MadeChange = false;
-    
-    // This code does not currently handle nodes which have multiple types,
-    // where some types are integer, and some are fp.  Assert that this is not
-    // the case.
-    assert(!(EEVT::isExtIntegerInVTs(NodeToApply->getExtTypes()) &&
-             EEVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) &&
-           !(EEVT::isExtIntegerInVTs(BigOperand->getExtTypes()) &&
-             EEVT::isExtFloatingPointInVTs(BigOperand->getExtTypes())) &&
-           "SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
-    if (EEVT::isExtIntegerInVTs(NodeToApply->getExtTypes()))
-      MadeChange |= BigOperand->UpdateNodeType(MVT::iAny, TP);
-    else if (EEVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes()))
-      MadeChange |= BigOperand->UpdateNodeType(MVT::fAny, TP);
-    if (EEVT::isExtIntegerInVTs(BigOperand->getExtTypes()))
-      MadeChange |= NodeToApply->UpdateNodeType(MVT::iAny, TP);
-    else if (EEVT::isExtFloatingPointInVTs(BigOperand->getExtTypes()))
-      MadeChange |= NodeToApply->UpdateNodeType(MVT::fAny, TP);
-
-    std::vector<MVT::SimpleValueType> VTs = CGT.getLegalValueTypes();
-
-    if (EEVT::isExtIntegerInVTs(NodeToApply->getExtTypes())) {
-      VTs = FilterVTs(VTs, isInteger);
-    } else if (EEVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) {
-      VTs = FilterVTs(VTs, isFloatingPoint);
-    } else {
-      VTs.clear();
-    }
-
-    switch (VTs.size()) {
-    default:         // Too many VT's to pick from.
-    case 0: break;   // No info yet.
-    case 1: 
-      // Only one VT of this flavor.  Cannot ever satisfy the constraints.
-      return NodeToApply->UpdateNodeType(MVT::Other, TP);  // throw
-    case 2:
-      // If we have exactly two possible types, the little operand must be the
-      // small one, the big operand should be the big one.  Common with 
-      // float/double for example.
-      assert(VTs[0] < VTs[1] && "Should be sorted!");
-      MadeChange |= NodeToApply->UpdateNodeType(VTs[0], TP);
-      MadeChange |= BigOperand->UpdateNodeType(VTs[1], TP);
-      break;
-    }    
-    return MadeChange;
+    return NodeToApply->getExtType().
+                  EnforceSmallerThan(BigOperand->getExtType(), TP);
   }
   case SDTCisEltOfVec: {
-    TreePatternNode *OtherOperand =
-      getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum,
-                    N, NumResults);
-    if (OtherOperand->hasTypeSet()) {
-      if (!isVector(OtherOperand->getTypeNum(0)))
+    TreePatternNode *VecOperand =
+      getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NumResults);
+    if (VecOperand->hasTypeSet()) {
+      if (!isVector(VecOperand->getType()))
         TP.error(N->getOperator()->getName() + " VT operand must be a vector!");
-      EVT IVT = OtherOperand->getTypeNum(0);
+      EVT IVT = VecOperand->getType();
       IVT = IVT.getVectorElementType();
       return NodeToApply->UpdateNodeType(IVT.getSimpleVT().SimpleTy, TP);
     }
+    
+    if (NodeToApply->hasTypeSet() && VecOperand->getExtType().hasVectorTypes()){
+      // Filter vector types out of VecOperand that don't have the right element
+      // type.
+      return VecOperand->getExtType().
+        EnforceVectorEltTypeIs(NodeToApply->getType(), TP);
+    }
     return false;
   }
   }  
@@ -482,133 +711,6 @@
 #endif
 }
 
-/// UpdateNodeType - Set the node type of N to VT if VT contains
-/// information.  If N already contains a conflicting type, then throw an
-/// exception.  This returns true if any information was updated.
-///
-bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
-                                     TreePattern &TP) {
-  assert(!ExtVTs.empty() && "Cannot update node type with empty type vector!");
-  
-  if (ExtVTs[0] == EEVT::isUnknown || LHSIsSubsetOfRHS(getExtTypes(), ExtVTs))
-    return false;
-  if (isTypeCompletelyUnknown() || LHSIsSubsetOfRHS(ExtVTs, getExtTypes())) {
-    setTypes(ExtVTs);
-    return true;
-  }
-
-  if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) {
-    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny ||
-        ExtVTs[0] == MVT::iAny)
-      return false;
-    if (EEVT::isExtIntegerInVTs(ExtVTs)) {
-      std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, isInteger);
-      if (FVTs.size()) {
-        setTypes(ExtVTs);
-        return true;
-      }
-    }
-  }
-
-  // Merge vAny with iAny/fAny.  The latter include vector types so keep them
-  // as the more specific information.
-  if (ExtVTs[0] == MVT::vAny && 
-      (getExtTypeNum(0) == MVT::iAny || getExtTypeNum(0) == MVT::fAny))
-    return false;
-  if (getExtTypeNum(0) == MVT::vAny &&
-      (ExtVTs[0] == MVT::iAny || ExtVTs[0] == MVT::fAny)) {
-    setTypes(ExtVTs);
-    return true;
-  }
-
-  if (ExtVTs[0] == MVT::iAny &&
-      EEVT::isExtIntegerInVTs(getExtTypes())) {
-    assert(hasTypeSet() && "should be handled above!");
-    std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
-    if (getExtTypes() == FVTs)
-      return false;
-    setTypes(FVTs);
-    return true;
-  }
-  if ((ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny) &&
-      EEVT::isExtIntegerInVTs(getExtTypes())) {
-    //assert(hasTypeSet() && "should be handled above!");
-    std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
-    if (getExtTypes() == FVTs)
-      return false;
-    if (FVTs.size()) {
-      setTypes(FVTs);
-      return true;
-    }
-  }      
-  if (ExtVTs[0] == MVT::fAny &&
-      EEVT::isExtFloatingPointInVTs(getExtTypes())) {
-    assert(hasTypeSet() && "should be handled above!");
-    std::vector<unsigned char> FVTs =
-      FilterEVTs(getExtTypes(), isFloatingPoint);
-    if (getExtTypes() == FVTs)
-      return false;
-    setTypes(FVTs);
-    return true;
-  }
-  if (ExtVTs[0] == MVT::vAny &&
-      EEVT::isExtVectorInVTs(getExtTypes())) {
-    assert(hasTypeSet() && "should be handled above!");
-    std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isVector);
-    if (getExtTypes() == FVTs)
-      return false;
-    setTypes(FVTs);
-    return true;
-  }
-
-  // If we know this is an int, FP, or vector type, and we are told it is a
-  // specific one, take the advice.
-  //
-  // Similarly, we should probably set the type here to the intersection of
-  // {iAny|fAny|vAny} and ExtVTs
-  if ((getExtTypeNum(0) == MVT::iAny &&
-       EEVT::isExtIntegerInVTs(ExtVTs)) ||
-      (getExtTypeNum(0) == MVT::fAny &&
-       EEVT::isExtFloatingPointInVTs(ExtVTs)) ||
-      (getExtTypeNum(0) == MVT::vAny &&
-       EEVT::isExtVectorInVTs(ExtVTs))) {
-    setTypes(ExtVTs);
-    return true;
-  }
-  if (getExtTypeNum(0) == MVT::iAny &&
-      (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny)) {
-    setTypes(ExtVTs);
-    return true;
-  }
-
-  if (isLeaf()) {
-    dump();
-    errs() << " ";
-    TP.error("Type inference contradiction found in node!");
-  } else {
-    TP.error("Type inference contradiction found in node " + 
-             getOperator()->getName() + "!");
-  }
-  return true; // unreachable
-}
-
-static std::string GetTypeName(unsigned char TypeID) {
-  switch (TypeID) {
-  case MVT::Other:      return "Other";
-  case MVT::iAny:       return "iAny";
-  case MVT::fAny:       return "fAny";
-  case MVT::vAny:       return "vAny";
-  case EEVT::isUnknown: return "isUnknown";
-  case MVT::iPTR:       return "iPTR";
-  case MVT::iPTRAny:    return "iPTRAny";
-  default:
-    std::string VTName = llvm::getName((MVT::SimpleValueType)TypeID);
-    // Strip off EVT:: prefix if present.
-    if (VTName.substr(0,5) == "MVT::")
-      VTName = VTName.substr(5);
-    return VTName;
-  }
-}
 
 
 void TreePatternNode::print(raw_ostream &OS) const {
@@ -618,10 +720,8 @@
     OS << '(' << getOperator()->getName();
   }
   
-  // FIXME: At some point we should handle printing all the value types for 
-  // nodes that are multiply typed.
-  if (getExtTypeNum(0) != EEVT::isUnknown)
-    OS << ':' << GetTypeName(getExtTypeNum(0));
+  if (!isTypeCompletelyUnknown())
+    OS << ':' << getExtType().getName();
 
   if (!isLeaf()) {
     if (getNumChildren() != 0) {
@@ -657,7 +757,7 @@
 bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N,
                                      const MultipleUseVarSet &DepVars) const {
   if (N == this) return true;
-  if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() ||
+  if (N->isLeaf() != isLeaf() || getExtType() != N->getExtType() ||
       getPredicateFns() != N->getPredicateFns() ||
       getTransformFn() != N->getTransformFn())
     return false;
@@ -695,7 +795,7 @@
     New = new TreePatternNode(getOperator(), CChildren);
   }
   New->setName(getName());
-  New->setTypes(getExtTypes());
+  New->setType(getExtType());
   New->setPredicateFns(getPredicateFns());
   New->setTransformFn(getTransformFn());
   return New;
@@ -703,7 +803,7 @@
 
 /// RemoveAllTypes - Recursively strip all the types of this tree.
 void TreePatternNode::RemoveAllTypes() {
-  removeTypes();
+  setType(EEVT::TypeSet());  // Reset to unknown type.
   if (isLeaf()) return;
   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
     getChild(i)->RemoveAllTypes();
@@ -785,7 +885,7 @@
   }
   
   FragTree->setName(getName());
-  FragTree->UpdateNodeType(getExtTypes(), TP);
+  FragTree->UpdateNodeType(getExtType(), TP);
 
   // Transfer in the old predicates.
   for (unsigned i = 0, e = getPredicateFns().size(); i != e; ++i)
@@ -803,47 +903,40 @@
 /// type which should be applied to it.  This will infer the type of register
 /// references from the register file information, for example.
 ///
-static std::vector<unsigned char> getImplicitType(Record *R, bool NotRegisters,
-                                                  TreePattern &TP) {
-  // Some common return values
-  std::vector<unsigned char> Unknown(1, EEVT::isUnknown);
-  std::vector<unsigned char> Other(1, MVT::Other);
-
-  // Check to see if this is a register or a register class...
+static EEVT::TypeSet getImplicitType(Record *R, bool NotRegisters,
+                                     TreePattern &TP) {
+  // Check to see if this is a register or a register class.
   if (R->isSubClassOf("RegisterClass")) {
     if (NotRegisters) 
-      return Unknown;
-    const CodeGenRegisterClass &RC = 
-      TP.getDAGPatterns().getTargetInfo().getRegisterClass(R);
-    return ConvertVTs(RC.getValueTypes());
+      return EEVT::TypeSet(); // Unknown.
+    const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
+    return EEVT::TypeSet(T.getRegisterClass(R).getValueTypes());
   } else if (R->isSubClassOf("PatFrag")) {
     // Pattern fragment types will be resolved when they are inlined.
-    return Unknown;
+    return EEVT::TypeSet(); // Unknown.
   } else if (R->isSubClassOf("Register")) {
     if (NotRegisters) 
-      return Unknown;
+      return EEVT::TypeSet(); // Unknown.
     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
-    return T.getRegisterVTs(R);
+    return EEVT::TypeSet(T.getRegisterVTs(R));
   } else if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
     // Using a VTSDNode or CondCodeSDNode.
-    return Other;
+    return EEVT::TypeSet(MVT::Other, TP);
   } else if (R->isSubClassOf("ComplexPattern")) {
     if (NotRegisters) 
-      return Unknown;
-    std::vector<unsigned char>
-    ComplexPat(1, TP.getDAGPatterns().getComplexPattern(R).getValueType());
-    return ComplexPat;
+      return EEVT::TypeSet(); // Unknown.
+   return EEVT::TypeSet(TP.getDAGPatterns().getComplexPattern(R).getValueType(),
+                         TP);
   } else if (R->isSubClassOf("PointerLikeRegClass")) {
-    Other[0] = MVT::iPTR;
-    return Other;
+    return EEVT::TypeSet(MVT::iPTR, TP);
   } else if (R->getName() == "node" || R->getName() == "srcvalue" ||
              R->getName() == "zero_reg") {
     // Placeholder.
-    return Unknown;
+    return EEVT::TypeSet(); // Unknown.
   }
   
   TP.error("Unknown node flavor used in pattern: " + R->getName());
-  return Other;
+  return EEVT::TypeSet(MVT::Other, TP);
 }
 
 
@@ -927,40 +1020,33 @@
     
     if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
       // Int inits are always integers. :)
-      bool MadeChange = UpdateNodeType(MVT::iAny, TP);
+      bool MadeChange = Type.EnforceInteger(TP);
       
-      if (hasTypeSet()) {
-        // At some point, it may make sense for this tree pattern to have
-        // multiple types.  Assert here that it does not, so we revisit this
-        // code when appropriate.
-        assert(getExtTypes().size() >= 1 && "TreePattern doesn't have a type!");
-        MVT::SimpleValueType VT = getTypeNum(0);
-        for (unsigned i = 1, e = getExtTypes().size(); i != e; ++i)
-          assert(getTypeNum(i) == VT && "TreePattern has too many types!");
-        
-        VT = getTypeNum(0);
-        if (VT != MVT::iPTR && VT != MVT::iPTRAny) {
-          unsigned Size = EVT(VT).getSizeInBits();
-          // Make sure that the value is representable for this type.
-          if (Size < 32) {
-            int Val = (II->getValue() << (32-Size)) >> (32-Size);
-            if (Val != II->getValue()) {
-              // If sign-extended doesn't fit, does it fit as unsigned?
-              unsigned ValueMask;
-              unsigned UnsignedVal;
-              ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
-              UnsignedVal = unsigned(II->getValue());
-
-              if ((ValueMask & UnsignedVal) != UnsignedVal) {
-                TP.error("Integer value '" + itostr(II->getValue())+
-                         "' is out of range for type '" + 
-                         getEnumName(getTypeNum(0)) + "'!");
-              }
-            }
-          }
-        }
-      }
+      if (!hasTypeSet())
+        return MadeChange;
+      
+      MVT::SimpleValueType VT = getType();
+      if (VT == MVT::iPTR || VT == MVT::iPTRAny)
+        return MadeChange;
+      
+      unsigned Size = EVT(VT).getSizeInBits();
+      // Make sure that the value is representable for this type.
+      if (Size >= 32) return MadeChange;
       
+      int Val = (II->getValue() << (32-Size)) >> (32-Size);
+      if (Val == II->getValue()) return MadeChange;
+      
+      // If sign-extended doesn't fit, does it fit as unsigned?
+      unsigned ValueMask;
+      unsigned UnsignedVal;
+      ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
+      UnsignedVal = unsigned(II->getValue());
+
+      if ((ValueMask & UnsignedVal) == UnsignedVal)
+        return MadeChange;
+      
+      TP.error("Integer value '" + itostr(II->getValue())+
+               "' is out of range for type '" + getEnumName(getType()) + "'!");
       return MadeChange;
     }
     return false;
@@ -976,11 +1062,9 @@
       MadeChange |= getChild(NC-1)->ApplyTypeConstraints(TP, NotRegisters);
     
       // Types of operands must match.
-      MadeChange |= getChild(i)->UpdateNodeType(getChild(NC-1)->getExtTypes(),
-                                                TP);
-      MadeChange |= getChild(NC-1)->UpdateNodeType(getChild(i)->getExtTypes(),
-                                                   TP);
-      MadeChange |= UpdateNodeType(MVT::isVoid, TP);
+      MadeChange |=getChild(i)->UpdateNodeType(getChild(NC-1)->getExtType(),TP);
+      MadeChange |=getChild(NC-1)->UpdateNodeType(getChild(i)->getExtType(),TP);
+      MadeChange |=UpdateNodeType(MVT::isVoid, TP);
     }
     return MadeChange;
   }
@@ -998,6 +1082,15 @@
     bool MadeChange = false;
     MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
     MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters);
+    
+    // child #1 of COPY_TO_REGCLASS should be a register class.  We don't care
+    // what type it gets, so if it didn't get a concrete type just give it the
+    // first viable type from the reg class.
+    if (!getChild(1)->hasTypeSet() &&
+        !getChild(1)->getExtType().isCompletelyUnknown()) {
+      MVT::SimpleValueType RCVT = getChild(1)->getExtType().getTypeList()[0];
+      MadeChange |= getChild(1)->UpdateNodeType(RCVT, TP);
+    }
     return MadeChange;
   }
   
@@ -1058,22 +1151,26 @@
       Record *ResultNode = Inst.getResult(0);
       
       if (ResultNode->isSubClassOf("PointerLikeRegClass")) {
-        std::vector<unsigned char> VT;
-        VT.push_back(MVT::iPTR);
-        MadeChange = UpdateNodeType(VT, TP);
+        MadeChange = UpdateNodeType(MVT::iPTR, TP);
       } else if (ResultNode->getName() == "unknown") {
-        std::vector<unsigned char> VT;
-        VT.push_back(EEVT::isUnknown);
-        MadeChange = UpdateNodeType(VT, TP);
+        // Nothing to do.
       } else {
         assert(ResultNode->isSubClassOf("RegisterClass") &&
                "Operands should be register classes!");
 
         const CodeGenRegisterClass &RC = 
           CDP.getTargetInfo().getRegisterClass(ResultNode);
-        MadeChange = UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
+        MadeChange = UpdateNodeType(RC.getValueTypes(), TP);
       }
     }
+    
+    // If this is an INSERT_SUBREG, constrain the source and destination VTs to
+    // be the same.
+    if (getOperator()->getName() == "INSERT_SUBREG") {
+      MadeChange |= UpdateNodeType(getChild(0)->getExtType(), TP);
+      MadeChange |= getChild(0)->UpdateNodeType(getExtType(), TP);
+    }
+    
 
     unsigned ChildNo = 0;
     for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
@@ -1097,14 +1194,14 @@
       if (OperandNode->isSubClassOf("RegisterClass")) {
         const CodeGenRegisterClass &RC = 
           CDP.getTargetInfo().getRegisterClass(OperandNode);
-        MadeChange |= Child->UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
+        MadeChange |= Child->UpdateNodeType(RC.getValueTypes(), TP);
       } else if (OperandNode->isSubClassOf("Operand")) {
         VT = getValueType(OperandNode->getValueAsDef("Type"));
         MadeChange |= Child->UpdateNodeType(VT, TP);
       } else if (OperandNode->isSubClassOf("PointerLikeRegClass")) {
         MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP);
       } else if (OperandNode->getName() == "unknown") {
-        MadeChange |= Child->UpdateNodeType(EEVT::isUnknown, TP);
+        // Nothing to do.
       } else {
         assert(0 && "Unknown operand type!");
         abort();
@@ -1126,15 +1223,20 @@
     TP.error("Node transform '" + getOperator()->getName() +
              "' requires one operand!");
 
+  bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
+
+  
   // If either the output or input of the xform does not have exact
   // type info. We assume they must be the same. Otherwise, it is perfectly
   // legal to transform from one type to a completely different type.
+#if 0
   if (!hasTypeSet() || !getChild(0)->hasTypeSet()) {
-    bool MadeChange = UpdateNodeType(getChild(0)->getExtTypes(), TP);
-    MadeChange |= getChild(0)->UpdateNodeType(getExtTypes(), TP);
+    bool MadeChange = UpdateNodeType(getChild(0)->getExtType(), TP);
+    MadeChange |= getChild(0)->UpdateNodeType(getExtType(), TP);
     return MadeChange;
   }
-  return false;
+#endif
+  return MadeChange;
 }
 
 /// OnlyOnRHSOfCommutative - Return true if this value is only allowed on the
@@ -1194,9 +1296,9 @@
 
 TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
                          CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
-   isInputPattern = isInput;
-   for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
-     Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i)));
+  isInputPattern = isInput;
+  for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
+    Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i)));
 }
 
 TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
@@ -1211,13 +1313,24 @@
   Trees.push_back(Pat);
 }
 
-
-
 void TreePattern::error(const std::string &Msg) const {
   dump();
   throw TGError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg);
 }
 
+void TreePattern::ComputeNamedNodes() {
+  for (unsigned i = 0, e = Trees.size(); i != e; ++i)
+    ComputeNamedNodes(Trees[i]);
+}
+
+void TreePattern::ComputeNamedNodes(TreePatternNode *N) {
+  if (!N->getName().empty())
+    NamedNodes[N->getName()].push_back(N);
+  
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+    ComputeNamedNodes(N->getChild(i));
+}
+
 TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
   DefInit *OpDef = dynamic_cast<DefInit*>(Dag->getOperator());
   if (!OpDef) error("Pattern has unexpected operator type!");
@@ -1373,12 +1486,58 @@
 /// InferAllTypes - Infer/propagate as many types throughout the expression
 /// patterns as possible.  Return true if all types are inferred, false
 /// otherwise.  Throw an exception if a type contradiction is found.
-bool TreePattern::InferAllTypes() {
+bool TreePattern::
+InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) {
+  if (NamedNodes.empty())
+    ComputeNamedNodes();
+
   bool MadeChange = true;
   while (MadeChange) {
     MadeChange = false;
     for (unsigned i = 0, e = Trees.size(); i != e; ++i)
       MadeChange |= Trees[i]->ApplyTypeConstraints(*this, false);
+
+    // If there are constraints on our named nodes, apply them.
+    for (StringMap<SmallVector<TreePatternNode*,1> >::iterator 
+         I = NamedNodes.begin(), E = NamedNodes.end(); I != E; ++I) {
+      SmallVectorImpl<TreePatternNode*> &Nodes = I->second;
+      
+      // If we have input named node types, propagate their types to the named
+      // values here.
+      if (InNamedTypes) {
+        // FIXME: Should be error?
+        assert(InNamedTypes->count(I->getKey()) &&
+               "Named node in output pattern but not input pattern?");
+
+        const SmallVectorImpl<TreePatternNode*> &InNodes =
+          InNamedTypes->find(I->getKey())->second;
+
+        // The input types should be fully resolved by now.
+        for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
+          // If this node is a register class, and it is the root of the pattern
+          // then we're mapping something onto an input register.  We allow
+          // changing the type of the input register in this case.  This allows
+          // us to match things like:
+          //  def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>;
+          if (Nodes[i] == Trees[0] && Nodes[i]->isLeaf()) {
+            DefInit *DI = dynamic_cast<DefInit*>(Nodes[i]->getLeafValue());
+            if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
+              continue;
+          }
+          
+          MadeChange |=Nodes[i]->UpdateNodeType(InNodes[0]->getExtType(),*this);
+        }
+      }
+      
+      // If there are multiple nodes with the same name, they must all have the
+      // same type.
+      if (I->second.size() > 1) {
+        for (unsigned i = 0, e = Nodes.size()-1; i != e; ++i) {
+          MadeChange |=Nodes[i]->UpdateNodeType(Nodes[i+1]->getExtType(),*this);
+          MadeChange |=Nodes[i+1]->UpdateNodeType(Nodes[i]->getExtType(),*this);
+        }
+      }
+    }
   }
   
   bool HasUnresolvedTypes = false;
@@ -1673,7 +1832,7 @@
   // Ensure that the inputs agree if we've already seen this input.
   if (Rec != SlotRec)
     I->error("All $" + Pat->getName() + " inputs must agree with each other");
-  if (Slot->getExtTypes() != Pat->getExtTypes())
+  if (Slot->getExtType() != Pat->getExtType())
     I->error("All $" + Pat->getName() + " inputs must agree with each other");
   return true;
 }
@@ -1712,7 +1871,7 @@
     // If this is not a set, verify that the children nodes are not void typed,
     // and recurse.
     for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
-      if (Pat->getChild(i)->getExtTypeNum(0) == MVT::isVoid)
+      if (Pat->getChild(i)->getType() == MVT::isVoid)
         I->error("Cannot have void nodes inside of patterns!");
       FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults,
                                   InstImpInputs, InstImpResults);
@@ -1960,7 +2119,7 @@
     // fill in the InstResults map.
     for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) {
       TreePatternNode *Pat = I->getTree(j);
-      if (Pat->getExtTypeNum(0) != MVT::isVoid)
+      if (!Pat->hasTypeSet() || Pat->getType() != MVT::isVoid)
         I->error("Top-level forms in instruction pattern should have"
                  " void types");
 
@@ -2072,7 +2231,7 @@
       new TreePatternNode(I->getRecord(), ResultNodeOperands);
     // Copy fully inferred output node type to instruction result pattern.
     if (NumResults > 0)
-      ResultPattern->setTypes(Res0Node->getExtTypes());
+      ResultPattern->setType(Res0Node->getExtType());
 
     // Create and insert the instruction.
     // FIXME: InstImpResults and InstImpInputs should not be part of
@@ -2084,7 +2243,7 @@
     // constructed result is correct.  This depends on the instruction already
     // being inserted into the Instructions map.
     TreePattern Temp(I->getRecord(), ResultPattern, false, *this);
-    Temp.InferAllTypes();
+    Temp.InferAllTypes(&I->getNamedNodesMap());
 
     DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second;
     TheInsertedInst.setResultPattern(Temp.getOnlyTree());
@@ -2133,7 +2292,7 @@
     // If this is the first instance of the name, remember the node.
     if (Rec.second++ == 0)
       Rec.first = P;
-    else if (Rec.first->getExtTypes() != P->getExtTypes())
+    else if (Rec.first->getType() != P->getType())
       PatternTop->error("repetition of value: $" + P->getName() +
                         " where different uses have different types!");
   }
@@ -2220,6 +2379,30 @@
   }
 }
 
+/// Given a pattern result with an unresolved type, see if we can find one
+/// instruction with an unresolved result type.  Force this result type to an
+/// arbitrary element if it's possible types to converge results.
+static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) {
+  if (N->isLeaf())
+    return false;
+  
+  // Analyze children.
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+    if (ForceArbitraryInstResultType(N->getChild(i), TP))
+      return true;
+
+  if (!N->getOperator()->isSubClassOf("Instruction"))
+    return false;
+
+  // If this type is already concrete or completely unknown we can't do
+  // anything.
+  if (N->getExtType().isCompletelyUnknown() || N->getExtType().isConcrete())
+    return false;
+  
+  // Otherwise, force its type to the first possibility (an arbitrary choice).
+  return N->getExtType().MergeInTypeInfo(N->getExtType().getTypeList()[0], TP);
+}
+
 void CodeGenDAGPatterns::ParsePatterns() {
   std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
 
@@ -2278,28 +2461,47 @@
     do {
       // Infer as many types as possible.  If we cannot infer all of them, we
       // can never do anything with this pattern: report it to the user.
-      InferredAllPatternTypes = Pattern->InferAllTypes();
+      InferredAllPatternTypes =
+        Pattern->InferAllTypes(&Pattern->getNamedNodesMap());
       
       // Infer as many types as possible.  If we cannot infer all of them, we
       // can never do anything with this pattern: report it to the user.
-      InferredAllResultTypes = Result->InferAllTypes();
+      InferredAllResultTypes =
+        Result->InferAllTypes(&Pattern->getNamedNodesMap());
 
       // Apply the type of the result to the source pattern.  This helps us
       // resolve cases where the input type is known to be a pointer type (which
       // is considered resolved), but the result knows it needs to be 32- or
       // 64-bits.  Infer the other way for good measure.
       IterateInference = Pattern->getTree(0)->
-        UpdateNodeType(Result->getTree(0)->getExtTypes(), *Result);
+        UpdateNodeType(Result->getTree(0)->getExtType(), *Result);
       IterateInference |= Result->getTree(0)->
-        UpdateNodeType(Pattern->getTree(0)->getExtTypes(), *Result);
+        UpdateNodeType(Pattern->getTree(0)->getExtType(), *Result);
+      
+      // If our iteration has converged and the input pattern's types are fully
+      // resolved but the result pattern is not fully resolved, we may have a
+      // situation where we have two instructions in the result pattern and
+      // the instructions require a common register class, but don't care about
+      // what actual MVT is used.  This is actually a bug in our modelling:
+      // output patterns should have register classes, not MVTs.
+      //
+      // In any case, to handle this, we just go through and disambiguate some
+      // arbitrary types to the result pattern's nodes.
+      if (!IterateInference && InferredAllPatternTypes &&
+          !InferredAllResultTypes)
+        IterateInference = ForceArbitraryInstResultType(Result->getTree(0),
+                                                        *Result);
+      
     } while (IterateInference);
     
     // Verify that we inferred enough types that we can do something with the
     // pattern and result.  If these fire the user has to add type casts.
     if (!InferredAllPatternTypes)
       Pattern->error("Could not infer all types in pattern!");
-    if (!InferredAllResultTypes)
+    if (!InferredAllResultTypes) {
+      Pattern->dump();
       Result->error("Could not infer all types in pattern result!");
+    }
     
     // Validate that the input pattern is correct.
     std::map<std::string, TreePatternNode*> InstInputs;
@@ -2328,7 +2530,7 @@
     if (!DstPattern->isLeaf())
       DstPattern = new TreePatternNode(DstPattern->getOperator(),
                                        ResultNodeOperands);
-    DstPattern->setTypes(Result->getOnlyTree()->getExtTypes());
+    DstPattern->setType(Result->getOnlyTree()->getExtType());
     TreePattern Temp(Result->getRecord(), DstPattern, false, *this);
     Temp.InferAllTypes();
 
@@ -2378,7 +2580,7 @@
     R->setName(Orig->getName());
     R->setPredicateFns(Orig->getPredicateFns());
     R->setTransformFn(Orig->getTransformFn());
-    R->setTypes(Orig->getExtTypes());
+    R->setType(Orig->getExtType());
     
     // If this pattern cannot match, do not include it as a variant.
     std::string ErrString;

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=98534&r1=98533&r2=98534&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Mon Mar 15 01:00:16 2010
@@ -21,6 +21,8 @@
 
 #include "CodeGenTarget.h"
 #include "CodeGenIntrinsics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
 
 namespace llvm {
   class Record;
@@ -40,20 +42,99 @@
 /// value is needed.
 namespace EEVT {
   enum DAGISelGenValueType {
+    // FIXME: Remove EEVT::isUnknown!
     isUnknown  = MVT::LAST_VALUETYPE
   };
-
-  /// isExtIntegerInVTs - Return true if the specified extended value type
-  /// vector contains iAny or an integer value type.
-  bool isExtIntegerInVTs(const std::vector<unsigned char> &EVTs);
-
-  /// isExtFloatingPointInVTs - Return true if the specified extended value
-  /// type vector contains fAny or a FP value type.
-  bool isExtFloatingPointInVTs(const std::vector<unsigned char> &EVTs);
-
-  /// isExtVectorinVTs - Return true if the specified extended value type 
-  /// vector contains vAny or a vector value type.
-  bool isExtVectorInVTs(const std::vector<unsigned char> &EVTs);
+  
+  /// TypeSet - This is either empty if it's completely unknown, or holds a set
+  /// of types.  It is used during type inference because register classes can
+  /// have multiple possible types and we don't know which one they get until
+  /// type inference is complete.
+  ///
+  /// TypeSet can have three states:
+  ///    Vector is empty: The type is completely unknown, it can be any valid
+  ///       target type.
+  ///    Vector has multiple constrained types: (e.g. v4i32 + v4f32) it is one
+  ///       of those types only.
+  ///    Vector has one concrete type: The type is completely known.
+  ///
+  class TypeSet {
+    SmallVector<MVT::SimpleValueType, 2> TypeVec;
+  public:
+    TypeSet() {}
+    TypeSet(MVT::SimpleValueType VT, TreePattern &TP);
+    TypeSet(const std::vector<MVT::SimpleValueType> &VTList);    
+    
+    bool isCompletelyUnknown() const { return TypeVec.empty(); }
+    
+    bool isConcrete() const {
+      if (TypeVec.size() != 1) return false;
+      unsigned char T = TypeVec[0]; (void)T;
+      assert(T < MVT::LAST_VALUETYPE || T == MVT::iPTR || T == MVT::iPTRAny);
+      return true;
+    }
+    
+    MVT::SimpleValueType getConcrete() const {
+      assert(isConcrete() && "Type isn't concrete yet");
+      return (MVT::SimpleValueType)TypeVec[0];
+    }
+    
+    bool isDynamicallyResolved() const {
+      return getConcrete() == MVT::iPTR || getConcrete() == MVT::iPTRAny;
+    }
+    
+    const SmallVectorImpl<MVT::SimpleValueType> &getTypeList() const {
+      assert(!TypeVec.empty() && "Not a type list!");
+      return TypeVec;
+    }
+    
+    /// hasIntegerTypes - Return true if this TypeSet contains any integer value
+    /// types.
+    bool hasIntegerTypes() const;
+    
+    /// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or
+    /// a floating point value type.
+    bool hasFloatingPointTypes() const;
+    
+    /// hasVectorTypes - Return true if this TypeSet contains a vector value
+    /// type.
+    bool hasVectorTypes() const;
+    
+    /// getName() - Return this TypeSet as a string.
+    std::string getName() const;
+    
+    /// MergeInTypeInfo - This merges in type information from the specified
+    /// argument.  If 'this' changes, it returns true.  If the two types are
+    /// contradictory (e.g. merge f32 into i32) then this throws an exception.
+    bool MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP);
+
+    bool MergeInTypeInfo(MVT::SimpleValueType InVT, TreePattern &TP) {
+      return MergeInTypeInfo(EEVT::TypeSet(InVT, TP), TP);
+    }
+
+    /// Force this type list to only contain integer types.
+    bool EnforceInteger(TreePattern &TP);
+
+    /// Force this type list to only contain floating point types.
+    bool EnforceFloatingPoint(TreePattern &TP);
+
+    /// EnforceScalar - Remove all vector types from this type list.
+    bool EnforceScalar(TreePattern &TP);
+
+    /// EnforceVector - Remove all non-vector types from this type list.
+    bool EnforceVector(TreePattern &TP);
+
+    /// EnforceSmallerThan - 'this' must be a smaller VT than Other.  Update
+    /// this an other based on this information.
+    bool EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP);
+    
+    /// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
+    /// whose element is VT.
+    bool EnforceVectorEltTypeIs(MVT::SimpleValueType VT, TreePattern &TP);
+    
+    bool operator!=(const TypeSet &RHS) const { return TypeVec != RHS.TypeVec; }
+    bool operator==(const TypeSet &RHS) const { return TypeVec == RHS.TypeVec; }
+  };
 }
 
 /// Set type used to track multiply used variables in patterns
@@ -72,7 +153,7 @@
   
   union {   // The discriminated union.
     struct {
-      unsigned char VT;
+      MVT::SimpleValueType VT;
     } SDTCisVT_Info;
     struct {
       unsigned OtherOperandNum;
@@ -150,10 +231,10 @@
 /// patterns), and as such should be ref counted.  We currently just leak all
 /// TreePatternNode objects!
 class TreePatternNode {
-  /// The inferred type for this node, or EEVT::isUnknown if it hasn't
-  /// been determined yet. This is a std::vector because during inference
-  /// there may be multiple possible types.
-  std::vector<unsigned char> Types;
+  /// The type of this node.  Before and during type inference, this may be a
+  /// set of possible types.  After (successful) type inference, this is a
+  /// single type.
+  EEVT::TypeSet Type;
   
   /// Operator - The Record for the operator if this is an interior node (not
   /// a leaf).
@@ -178,11 +259,9 @@
   std::vector<TreePatternNode*> Children;
 public:
   TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch) 
-    : Types(), Operator(Op), Val(0), TransformFn(0),
-    Children(Ch) { Types.push_back(EEVT::isUnknown); }
+    : Operator(Op), Val(0), TransformFn(0), Children(Ch) { }
   TreePatternNode(Init *val)    // leaf ctor
-    : Types(), Operator(0), Val(val), TransformFn(0) {
-    Types.push_back(EEVT::isUnknown);
+    : Operator(0), Val(val), TransformFn(0) {
   }
   ~TreePatternNode();
   
@@ -190,28 +269,16 @@
   void setName(const std::string &N) { Name = N; }
   
   bool isLeaf() const { return Val != 0; }
-  bool hasTypeSet() const {
-    return (Types[0] < MVT::LAST_VALUETYPE) || (Types[0] == MVT::iPTR) || 
-          (Types[0] == MVT::iPTRAny);
-  }
-  bool isTypeCompletelyUnknown() const {
-    return Types[0] == EEVT::isUnknown;
-  }
-  bool isTypeDynamicallyResolved() const {
-    return (Types[0] == MVT::iPTR) || (Types[0] == MVT::iPTRAny);
-  }
-  MVT::SimpleValueType getTypeNum(unsigned Num) const {
-    assert(hasTypeSet() && "Doesn't have a type yet!");
-    assert(Types.size() > Num && "Type num out of range!");
-    return (MVT::SimpleValueType)Types[Num];
-  }
-  unsigned char getExtTypeNum(unsigned Num) const { 
-    assert(Types.size() > Num && "Extended type num out of range!");
-    return Types[Num]; 
-  }
-  const std::vector<unsigned char> &getExtTypes() const { return Types; }
-  void setTypes(const std::vector<unsigned char> &T) { Types = T; }
-  void removeTypes() { Types = std::vector<unsigned char>(1, EEVT::isUnknown); }
+  
+  // Type accessors.
+  MVT::SimpleValueType getType() const { return Type.getConcrete(); }
+  const EEVT::TypeSet &getExtType() const { return Type; }
+  EEVT::TypeSet &getExtType() { return Type; }
+  void setType(const EEVT::TypeSet &T) { Type = T; }
+  
+  bool hasTypeSet() const { return Type.isConcrete(); }
+  bool isTypeCompletelyUnknown() const { return Type.isCompletelyUnknown(); }
+  bool isTypeDynamicallyResolved() const { return Type.isDynamicallyResolved();}
   
   Init *getLeafValue() const { assert(isLeaf()); return Val; }
   Record *getOperator() const { assert(!isLeaf()); return Operator; }
@@ -304,17 +371,18 @@
   /// information.  If N already contains a conflicting type, then throw an
   /// exception.  This returns true if any information was updated.
   ///
-  bool UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
-                      TreePattern &TP);
-  bool UpdateNodeType(unsigned char ExtVT, TreePattern &TP) {
-    std::vector<unsigned char> ExtVTs(1, ExtVT);
-    return UpdateNodeType(ExtVTs, TP);
+  bool UpdateNodeType(const EEVT::TypeSet &InTy, TreePattern &TP) {
+    return Type.MergeInTypeInfo(InTy, TP);
+  }
+
+  bool UpdateNodeType(MVT::SimpleValueType InTy, TreePattern &TP) {
+    return Type.MergeInTypeInfo(EEVT::TypeSet(InTy, TP), TP);
   }
   
   /// ContainsUnresolvedType - Return true if this tree contains any
   /// unresolved types.
   bool ContainsUnresolvedType() const {
-    if (!hasTypeSet() && !isTypeDynamicallyResolved()) return true;
+    if (!hasTypeSet()) return true;
     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
       if (getChild(i)->ContainsUnresolvedType()) return true;
     return false;
@@ -340,6 +408,10 @@
   ///
   std::vector<TreePatternNode*> Trees;
   
+  /// NamedNodes - This is all of the nodes that have names in the trees in this
+  /// pattern.
+  StringMap<SmallVector<TreePatternNode*,1> > NamedNodes;
+  
   /// TheRecord - The actual TableGen record corresponding to this pattern.
   ///
   Record *TheRecord;
@@ -375,6 +447,12 @@
     assert(Trees.size() == 1 && "Doesn't have exactly one pattern!");
     return Trees[0];
   }
+  
+  const StringMap<SmallVector<TreePatternNode*,1> > &getNamedNodesMap() {
+    if (NamedNodes.empty())
+      ComputeNamedNodes();
+    return NamedNodes;
+  }
       
   /// getRecord - Return the actual TableGen record corresponding to this
   /// pattern.
@@ -401,7 +479,8 @@
   /// InferAllTypes - Infer/propagate as many types throughout the expression
   /// patterns as possible.  Return true if all types are inferred, false
   /// otherwise.  Throw an exception if a type contradiction is found.
-  bool InferAllTypes();
+  bool InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> >
+                          *NamedTypes=0);
   
   /// error - Throw an exception, prefixing it with information about this
   /// pattern.
@@ -412,6 +491,8 @@
   
 private:
   TreePatternNode *ParseTreePattern(DagInit *DI);
+  void ComputeNamedNodes();
+  void ComputeNamedNodes(TreePatternNode *N);
 };
 
 /// DAGDefaultOperand - One of these is created for each PredicateOperand

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=98534&r1=98533&r2=98534&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Mar 15 01:00:16 2010
@@ -184,16 +184,16 @@
   RegisterClasses.assign(RegClasses.begin(), RegClasses.end());
 }
 
-std::vector<unsigned char> CodeGenTarget::getRegisterVTs(Record *R) const {
-  std::vector<unsigned char> Result;
+std::vector<MVT::SimpleValueType> CodeGenTarget::
+getRegisterVTs(Record *R) const {
+  std::vector<MVT::SimpleValueType> Result;
   const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
   for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
     const CodeGenRegisterClass &RC = RegisterClasses[i];
     for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
       if (R == RC.Elements[ei]) {
         const std::vector<MVT::SimpleValueType> &InVTs = RC.getValueTypes();
-        for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
-          Result.push_back(InVTs[i]);
+        Result.insert(Result.end(), InVTs.begin(), InVTs.end());
       }
     }
   }

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=98534&r1=98533&r2=98534&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.h Mon Mar 15 01:00:16 2010
@@ -167,7 +167,7 @@
 
   /// getRegisterVTs - Find the union of all possible SimpleValueTypes for the
   /// specified physical register.
-  std::vector<unsigned char> getRegisterVTs(Record *R) const;
+  std::vector<MVT::SimpleValueType> getRegisterVTs(Record *R) const;
   
   const std::vector<MVT::SimpleValueType> &getLegalValueTypes() const {
     if (LegalValueTypes.empty()) ReadLegalValueTypes();

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=98534&r1=98533&r2=98534&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Mon Mar 15 01:00:16 2010
@@ -25,13 +25,7 @@
 /// patterns before small ones.  This is used to determine the size of a
 /// pattern.
 static unsigned getPatternSize(TreePatternNode *P, CodeGenDAGPatterns &CGP) {
-  assert((EEVT::isExtIntegerInVTs(P->getExtTypes()) ||
-          EEVT::isExtFloatingPointInVTs(P->getExtTypes()) ||
-          P->getExtTypeNum(0) == MVT::isVoid ||
-          P->getExtTypeNum(0) == MVT::Flag ||
-          P->getExtTypeNum(0) == MVT::iPTR ||
-          P->getExtTypeNum(0) == MVT::iPTRAny) && 
-         "Not a valid pattern node to size!");
+  assert(P->hasTypeSet() && "Not a valid pattern node to size!");
   unsigned Size = 3;  // The node itself.
   // If the root node is a ConstantSDNode, increases its size.
   // e.g. (set R32:$dst, 0).
@@ -55,7 +49,7 @@
   // Count children in the count if they are also nodes.
   for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) {
     TreePatternNode *Child = P->getChild(i);
-    if (!Child->isLeaf() && Child->getExtTypeNum(0) != MVT::Other)
+    if (!Child->isLeaf() && Child->getType() != MVT::Other)
       Size += getPatternSize(Child, CGP);
     else if (Child->isLeaf()) {
       if (dynamic_cast<IntInit*>(Child->getLeafValue())) 

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=98534&r1=98533&r2=98534&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Mon Mar 15 01:00:16 2010
@@ -408,11 +408,11 @@
   // If N and NodeNoTypes don't agree on a type, then this is a case where we
   // need to do a type check.  Emit the check, apply the tyep to NodeNoTypes and
   // reinfer any correlated types.
-  unsigned NodeType = EEVT::isUnknown;
-  if (NodeNoTypes->getExtTypes() != N->getExtTypes()) {
-    NodeType = N->getTypeNum(0);
-    NodeNoTypes->setTypes(N->getExtTypes());
+  bool DoTypeCheck = false;
+  if (NodeNoTypes->getExtType() != N->getExtType()) {
+    NodeNoTypes->setType(N->getExtType());
     InferPossibleTypes();
+    DoTypeCheck = true;
   }
   
   // If this node has a name associated with it, capture it in VariableMap. If
@@ -442,8 +442,8 @@
   for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
     AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
   
-  if (NodeType != EEVT::isUnknown)
-    AddMatcher(new CheckTypeMatcher((MVT::SimpleValueType)NodeType));
+  if (DoTypeCheck)
+    AddMatcher(new CheckTypeMatcher(N->getType()));
 }
 
 /// EmitMatcherCode - Generate the code that matches the predicate of this
@@ -567,7 +567,7 @@
   assert(N->isLeaf() && "Must be a leaf");
   
   if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
-    AddMatcher(new EmitIntegerMatcher(II->getValue(),N->getTypeNum(0)));
+    AddMatcher(new EmitIntegerMatcher(II->getValue(), N->getType()));
     ResultOps.push_back(NextRecordedOperandNo++);
     return;
   }
@@ -575,14 +575,13 @@
   // If this is an explicit register reference, handle it.
   if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
     if (DI->getDef()->isSubClassOf("Register")) {
-      AddMatcher(new EmitRegisterMatcher(DI->getDef(),
-                                                 N->getTypeNum(0)));
+      AddMatcher(new EmitRegisterMatcher(DI->getDef(), N->getType()));
       ResultOps.push_back(NextRecordedOperandNo++);
       return;
     }
     
     if (DI->getDef()->getName() == "zero_reg") {
-      AddMatcher(new EmitRegisterMatcher(0, N->getTypeNum(0)));
+      AddMatcher(new EmitRegisterMatcher(0, N->getType()));
       ResultOps.push_back(NextRecordedOperandNo++);
       return;
     }
@@ -709,10 +708,10 @@
   
   // Determine the result types.
   SmallVector<MVT::SimpleValueType, 4> ResultVTs;
-  if (NumResults != 0 && N->getTypeNum(0) != MVT::isVoid) {
+  if (NumResults != 0 && N->getType() != MVT::isVoid) {
     // FIXME2: If the node has multiple results, we should add them.  For now,
     // preserve existing behavior?!
-    ResultVTs.push_back(N->getTypeNum(0));
+    ResultVTs.push_back(N->getType());
   }
 
   

Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FastISelEmitter.cpp?rev=98534&r1=98533&r2=98534&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FastISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FastISelEmitter.cpp Mon Mar 15 01:00:16 2010
@@ -73,10 +73,9 @@
       if (!Op->getPredicateFns().empty())
         return false;
       // For now, filter out any operand with multiple values.
-      if (Op->getExtTypes().size() != 1)
-        return false;
+      assert(Op->hasTypeSet() && "Type infererence not done?");
       // For now, all the operands must have the same type.
-      if (Op->getTypeNum(0) != VT)
+      if (Op->getType() != VT)
         return false;
       if (!Op->isLeaf()) {
         if (Op->getOperator()->getName() == "imm") {
@@ -296,10 +295,10 @@
 
     Record *InstPatOp = InstPatNode->getOperator();
     std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
-    MVT::SimpleValueType RetVT = InstPatNode->getTypeNum(0);
+    MVT::SimpleValueType RetVT = InstPatNode->getType();
     MVT::SimpleValueType VT = RetVT;
     if (InstPatNode->getNumChildren())
-      VT = InstPatNode->getChild(0)->getTypeNum(0);
+      VT = InstPatNode->getChild(0)->getType();
 
     // For now, filter out instructions which just set a register to
     // an Operand or an immediate, like MOV32ri.





More information about the llvm-commits mailing list