rewrite EnforceSmallerThan to be less bone headed.
authorChris Lattner <sabre@nondot.org>
Fri, 19 Mar 2010 04:54:36 +0000 (04:54 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 19 Mar 2010 04:54:36 +0000 (04:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98933 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/CodeGenDAGPatterns.cpp
utils/TableGen/CodeGenDAGPatterns.h

index 851dd8e833cd7703c501a276361b4a9d62edc251..98f86f8246ffdee4c53ab723adec22df25d09da0 100644 (file)
@@ -65,6 +65,13 @@ EEVT::TypeSet::TypeSet(const std::vector<MVT::SimpleValueType> &VTList) {
   TypeVec.erase(std::unique(TypeVec.begin(), TypeVec.end()), TypeVec.end());
 }
 
+/// FillWithPossibleTypes - Set to all legal types and return true, only valid
+/// on completely unknown type sets.
+bool EEVT::TypeSet::FillWithPossibleTypes(TreePattern &TP) {
+  assert(isCompletelyUnknown());
+  *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
+  return true;
+}
 
 /// hasIntegerTypes - Return true if this TypeSet contains iAny or an
 /// integer value type.
@@ -202,10 +209,8 @@ bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) {
   bool MadeChange = false;
   
   // If we know nothing, then get the full set.
-  if (TypeVec.empty()) {
-    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
-    MadeChange = true;
-  }
+  if (TypeVec.empty())
+    MadeChange = FillWithPossibleTypes(TP);
   
   if (!hasFloatingPointTypes())
     return MadeChange;
@@ -227,10 +232,8 @@ bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) {
   bool MadeChange = false;
   
   // If we know nothing, then get the full set.
-  if (TypeVec.empty()) {
-    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
-    MadeChange = true;
-  }
+  if (TypeVec.empty())
+    MadeChange = FillWithPossibleTypes(TP);
   
   if (!hasIntegerTypes())
     return MadeChange;
@@ -252,10 +255,8 @@ bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) {
   bool MadeChange = false;
   
   // If we know nothing, then get the full set.
-  if (TypeVec.empty()) {
-    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
-    MadeChange = true;
-  }
+  if (TypeVec.empty())
+    MadeChange = FillWithPossibleTypes(TP);
   
   if (!hasVectorTypes())
     return MadeChange;
@@ -277,10 +278,8 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
   bool MadeChange = false;
   
   // If we know nothing, then get the full set.
-  if (TypeVec.empty()) {
-    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
-    MadeChange = true;
-  }
+  if (TypeVec.empty())
+    MadeChange = FillWithPossibleTypes(TP);
   
   // Filter out all the scalar types.
   for (unsigned i = 0; i != TypeVec.size(); ++i)
@@ -294,72 +293,86 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
 }
 
 
+
 /// 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 (isCompletelyUnknown())
+    MadeChange = FillWithPossibleTypes(TP);
+
+  if (Other.isCompletelyUnknown())
+    MadeChange = Other.FillWithPossibleTypes(TP);
+    
   // 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())
+  if (!hasFloatingPointTypes())
     MadeChange |= Other.EnforceInteger(TP);
-  else if (hasFloatingPointTypes())
+  else if (!hasIntegerTypes())
     MadeChange |= Other.EnforceFloatingPoint(TP);
-  if (Other.hasIntegerTypes())
+  if (!Other.hasFloatingPointTypes())
     MadeChange |= EnforceInteger(TP);
-  else if (Other.hasFloatingPointTypes())
+  else if (!Other.hasIntegerTypes())
     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())
+  if (!hasVectorTypes())
     MadeChange |= Other.EnforceScalar(TP);
-  if (hasVectorTypes() && !Other.hasVectorTypes())
+  if (!hasVectorTypes())
     MadeChange |= EnforceScalar(TP);
   
-  // FIXME: This is a bone-headed way to do this.
+  // 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!");
   
-  // 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;
+  // Okay, find the smallest type from the current set and remove it from the
+  // largest set.
+  MVT::SimpleValueType Smallest = TypeVec[0];
+  for (unsigned i = 1, e = TypeVec.size(); i != e; ++i)
+    if (TypeVec[i] < Smallest)
+      Smallest = TypeVec[i];
   
-  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;
-  }    
+  // If this is the only type in the large set, the constraint can never be
+  // satisfied.
+  if (Other.TypeVec.size() == 1 && Other.TypeVec[0] == Smallest)
+    TP.error("Type inference contradiction found, '" +
+             Other.getName() + "' has nothing larger than '" + getName() +"'!");
+  
+  SmallVector<MVT::SimpleValueType, 2>::iterator TVI =
+    std::find(Other.TypeVec.begin(), Other.TypeVec.end(), Smallest);
+  if (TVI != Other.TypeVec.end()) {
+    Other.TypeVec.erase(TVI);
+    MadeChange = true;
+  }
+  
+  // Okay, find the largest type in the Other set and remove it from the
+  // current set.
+  MVT::SimpleValueType Largest = Other.TypeVec[0];
+  for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i)
+    if (Other.TypeVec[i] > Largest)
+      Largest = Other.TypeVec[i];
+  
+  // If this is the only type in the small set, the constraint can never be
+  // satisfied.
+  if (TypeVec.size() == 1 && TypeVec[0] == Largest)
+    TP.error("Type inference contradiction found, '" +
+             getName() + "' has nothing smaller than '" + Other.getName()+"'!");
+  
+  TVI = std::find(TypeVec.begin(), TypeVec.end(), Largest);
+  if (TVI != TypeVec.end()) {
+    TypeVec.erase(TVI);
+    MadeChange = true;
+  }
+  
+  return MadeChange;
 }
 
 /// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
@@ -370,10 +383,8 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT,
   bool MadeChange = false;
   
   // If we know nothing, then get the full set.
-  if (TypeVec.empty()) {
-    *this = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
-    MadeChange = true;
-  }
+  if (TypeVec.empty())
+    MadeChange = FillWithPossibleTypes(TP);
   
   // Filter out all the non-vector types and types which don't have the right
   // element type.
index 404cb35770b5e05e9bb6f2baf9a73d9ea1351235..caf053285d91a4fb5916a26f0d48f19cbb6abf47 100644 (file)
@@ -133,6 +133,11 @@ namespace EEVT {
     
     bool operator!=(const TypeSet &RHS) const { return TypeVec != RHS.TypeVec; }
     bool operator==(const TypeSet &RHS) const { return TypeVec == RHS.TypeVec; }
+    
+  private:
+    /// FillWithPossibleTypes - Set to all legal types and return true, only
+    /// valid on completely unknown type sets
+    bool FillWithPossibleTypes(TreePattern &TP);
   };
 }