[TableGen] Use std::remove_if instead of manually coded loops that call erase multipl...
[oota-llvm.git] / utils / TableGen / CodeGenDAGPatterns.cpp
index b05eac6fcdf3205f017b9f6be47d8b077d8257f3..8bd0dc3b4b247c0212eeacb9abd9117eec83dc23 100644 (file)
@@ -159,7 +159,7 @@ bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){
     return true;
   }
 
-  assert(TypeVec.size() >= 1 && InVT.TypeVec.size() >= 1 && "No unknowns");
+  assert(!TypeVec.empty() && !InVT.TypeVec.empty() && "No unknowns");
 
   // Handle the abstract cases, seeing if we can resolve them better.
   switch (TypeVec[0]) {
@@ -194,8 +194,7 @@ bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){
     // 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];
+      TypeVec.assign(1, InVT.TypeVec[0]);
       MadeChange = true;
     }
 
@@ -204,21 +203,20 @@ bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){
 
   // 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) {
-    if (std::find(InVT.TypeVec.begin(), InVT.TypeVec.end(), TypeVec[i]) !=
-        InVT.TypeVec.end())
-      continue;
+  TypeVec.clear();
+  std::set_intersection(InputSet.TypeVec.begin(), InputSet.TypeVec.end(),
+                        InVT.TypeVec.begin(), InVT.TypeVec.end(),
+                        std::back_inserter(TypeVec));
 
-    TypeVec.erase(TypeVec.begin()+i--);
-    MadeChange = true;
-  }
+  // If the intersection is the same size as the original set then we're done.
+  if (TypeVec.size() == InputSet.TypeVec.size())
+    return false;
 
   // If we removed all of our types, we have a type contradiction.
   if (!TypeVec.empty())
-    return MadeChange;
+    return true;
 
   // FIXME: Really want an SMLoc here!
   TP.error("Type inference contradiction found, merging '" +
@@ -233,15 +231,16 @@ bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) {
   // If we know nothing, then get the full set.
   if (TypeVec.empty())
     return FillWithPossibleTypes(TP, isInteger, "integer");
+
   if (!hasFloatingPointTypes())
     return false;
 
   TypeSet InputSet(*this);
 
   // Filter out all the fp types.
-  for (unsigned i = 0; i != TypeVec.size(); ++i)
-    if (!isInteger(TypeVec[i]))
-      TypeVec.erase(TypeVec.begin()+i--);
+  TypeVec.erase(std::remove_if(TypeVec.begin(), TypeVec.end(),
+                               std::not1(std::ptr_fun(isInteger))),
+                TypeVec.end());
 
   if (TypeVec.empty()) {
     TP.error("Type inference contradiction found, '" +
@@ -264,10 +263,10 @@ bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) {
 
   TypeSet InputSet(*this);
 
-  // Filter out all the fp types.
-  for (unsigned i = 0; i != TypeVec.size(); ++i)
-    if (!isFloatingPoint(TypeVec[i]))
-      TypeVec.erase(TypeVec.begin()+i--);
+  // Filter out all the integer types.
+  TypeVec.erase(std::remove_if(TypeVec.begin(), TypeVec.end(),
+                               std::not1(std::ptr_fun(isFloatingPoint))),
+                TypeVec.end());
 
   if (TypeVec.empty()) {
     TP.error("Type inference contradiction found, '" +
@@ -292,9 +291,9 @@ bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) {
   TypeSet InputSet(*this);
 
   // Filter out all the vector types.
-  for (unsigned i = 0; i != TypeVec.size(); ++i)
-    if (!isScalar(TypeVec[i]))
-      TypeVec.erase(TypeVec.begin()+i--);
+  TypeVec.erase(std::remove_if(TypeVec.begin(), TypeVec.end(),
+                               std::not1(std::ptr_fun(isScalar))),
+                TypeVec.end());
 
   if (TypeVec.empty()) {
     TP.error("Type inference contradiction found, '" +
@@ -317,11 +316,9 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
   bool MadeChange = false;
 
   // Filter out all the scalar types.
-  for (unsigned i = 0; i != TypeVec.size(); ++i)
-    if (!isVector(TypeVec[i])) {
-      TypeVec.erase(TypeVec.begin()+i--);
-      MadeChange = true;
-    }
+  TypeVec.erase(std::remove_if(TypeVec.begin(), TypeVec.end(),
+                               std::not1(std::ptr_fun(isVector))),
+                TypeVec.end());
 
   if (TypeVec.empty()) {
     TP.error("Type inference contradiction found, '" +
@@ -388,55 +385,55 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
   // type size is smaller than the scalar size of the smallest type. For
   // vectors, we also need to make sure that the total size is no larger than
   // the size of the smallest type.
-  TypeSet InputSet(Other);
-  MVT Smallest = TypeVec[0];
-  for (unsigned i = 0; i != Other.TypeVec.size(); ++i) {
-    MVT OtherVT = Other.TypeVec[i];
-    // Don't compare vector and non-vector types.
-    if (OtherVT.isVector() != Smallest.isVector())
-      continue;
-    // The getSizeInBits() check here is only needed for vectors, but is
-    // a subset of the scalar check for scalars so no need to qualify.
-    if (OtherVT.getScalarSizeInBits() <= Smallest.getScalarSizeInBits() ||
-        OtherVT.getSizeInBits() < Smallest.getSizeInBits()) {
-      Other.TypeVec.erase(Other.TypeVec.begin()+i--);
-      MadeChange = true;
+  {
+    TypeSet InputSet(Other);
+    MVT Smallest = TypeVec[0];
+    auto I = std::remove_if(Other.TypeVec.begin(), Other.TypeVec.end(),
+      [Smallest](MVT OtherVT) {
+        // Don't compare vector and non-vector types.
+        if (OtherVT.isVector() != Smallest.isVector())
+          return false;
+        // The getSizeInBits() check here is only needed for vectors, but is
+        // a subset of the scalar check for scalars so no need to qualify.
+        return OtherVT.getScalarSizeInBits() <= Smallest.getScalarSizeInBits()||
+               OtherVT.getSizeInBits() < Smallest.getSizeInBits();
+      });
+    MadeChange |= I != Other.TypeVec.end(); // If we're about to remove types.
+    Other.TypeVec.erase(I, Other.TypeVec.end());
+
+    if (Other.TypeVec.empty()) {
+      TP.error("Type inference contradiction found, '" + InputSet.getName() +
+               "' has nothing larger than '" + getName() +"'!");
+      return false;
     }
   }
 
-  if (Other.TypeVec.empty()) {
-    TP.error("Type inference contradiction found, '" + InputSet.getName() +
-             "' has nothing larger than '" + getName() +"'!");
-    return false;
-  }
-
   // Okay, find the largest type from the other set and remove anything the
   // same or smaller from the current set. We need to ensure that the scalar
   // type size is larger than the scalar size of the largest type. For
   // vectors, we also need to make sure that the total size is no smaller than
   // the size of the largest type.
-  InputSet = TypeSet(*this);
-  MVT Largest = Other.TypeVec[Other.TypeVec.size()-1];
-  for (unsigned i = 0; i != TypeVec.size(); ++i) {
-    MVT OtherVT = TypeVec[i];
-    // Don't compare vector and non-vector types.
-    if (OtherVT.isVector() != Largest.isVector())
-      continue;
-    // The getSizeInBits() check here is only needed for vectors, but is
-    // a subset of the scalar check for scalars so no need to qualify.
-    if (OtherVT.getScalarSizeInBits() >= Largest.getScalarSizeInBits() ||
-         OtherVT.getSizeInBits() > Largest.getSizeInBits()) {
-      TypeVec.erase(TypeVec.begin()+i--);
-      MadeChange = true;
+  {
+    TypeSet InputSet(*this);
+    MVT Largest = Other.TypeVec[Other.TypeVec.size()-1];
+    auto I = std::remove_if(TypeVec.begin(), TypeVec.end(),
+      [Largest](MVT OtherVT) {
+        // Don't compare vector and non-vector types.
+        if (OtherVT.isVector() != Largest.isVector())
+          return false;
+        return OtherVT.getScalarSizeInBits() >= Largest.getScalarSizeInBits() ||
+               OtherVT.getSizeInBits() > Largest.getSizeInBits();
+      });
+    MadeChange |= I != TypeVec.end(); // If we're about to remove types.
+    TypeVec.erase(I, TypeVec.end());
+
+    if (TypeVec.empty()) {
+      TP.error("Type inference contradiction found, '" + InputSet.getName() +
+               "' has nothing smaller than '" + Other.getName() +"'!");
+      return false;
     }
   }
 
-  if (TypeVec.empty()) {
-    TP.error("Type inference contradiction found, '" + InputSet.getName() +
-             "' has nothing smaller than '" + Other.getName() +"'!");
-    return false;
-  }
-
   return MadeChange;
 }
 
@@ -451,17 +448,17 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT,
   TypeSet InputSet(*this);
 
   // Filter out all the types which don't have the right element type.
-  for (unsigned i = 0; i != TypeVec.size(); ++i) {
-    assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
-    if (MVT(TypeVec[i]).getVectorElementType().SimpleTy != VT) {
-      TypeVec.erase(TypeVec.begin()+i--);
-      MadeChange = true;
-    }
-  }
+  auto I = std::remove_if(TypeVec.begin(), TypeVec.end(),
+    [VT](MVT VVT) {
+      return VVT.getVectorElementType().SimpleTy != VT;
+    });
+  MadeChange |= I != TypeVec.end();
+  TypeVec.erase(I, TypeVec.end());
 
   if (TypeVec.empty()) {  // FIXME: Really want an SMLoc here!
     TP.error("Type inference contradiction found, forcing '" +
-             InputSet.getName() + "' to have a vector element");
+             InputSet.getName() + "' to have a vector element of type " +
+             getEnumName(VT));
     return false;
   }
 
@@ -484,8 +481,7 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand,
   if (isConcrete()) {
     MVT IVT = getConcrete();
     IVT = IVT.getVectorElementType();
-    return MadeChange |
-      VTOperand.MergeInTypeInfo(IVT.SimpleTy, TP);
+    return MadeChange || VTOperand.MergeInTypeInfo(IVT.SimpleTy, TP);
   }
 
   // If the scalar type is known, filter out vector types whose element types
@@ -495,22 +491,8 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand,
 
   MVT::SimpleValueType VT = VTOperand.getConcrete();
 
-  TypeSet InputSet(*this);
+  MadeChange |= EnforceVectorEltTypeIs(VT, TP);
 
-  // Filter out all the types which don't have the right element type.
-  for (unsigned i = 0; i != TypeVec.size(); ++i) {
-    assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
-    if (MVT(TypeVec[i]).getVectorElementType().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 false;
-  }
   return MadeChange;
 }
 
@@ -553,13 +535,13 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand,
     // Only keep types that have less elements than VTOperand.
     TypeSet InputSet(VTOperand);
 
-    for (unsigned i = 0; i != VTOperand.TypeVec.size(); ++i) {
-      assert(isVector(VTOperand.TypeVec[i]) && "EnforceVector didn't work");
-      if (MVT(VTOperand.TypeVec[i]).getVectorNumElements() >= NumElems) {
-        VTOperand.TypeVec.erase(VTOperand.TypeVec.begin()+i--);
-        MadeChange = true;
-      }
-    }
+    auto I = std::remove_if(VTOperand.TypeVec.begin(), VTOperand.TypeVec.end(),
+                            [NumElems](MVT VVT) {
+                              return VVT.getVectorNumElements() >= NumElems;
+                            });
+    MadeChange |= I != VTOperand.TypeVec.end();
+    VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end());
+
     if (VTOperand.TypeVec.empty()) {  // FIXME: Really want an SMLoc here!
       TP.error("Type inference contradiction found, forcing '" +
                InputSet.getName() + "' to have less vector elements than '" +
@@ -577,13 +559,13 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand,
     // Only keep types that have more elements than 'this'.
     TypeSet InputSet(*this);
 
-    for (unsigned i = 0; i != TypeVec.size(); ++i) {
-      assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
-      if (MVT(TypeVec[i]).getVectorNumElements() <= NumElems) {
-        TypeVec.erase(TypeVec.begin()+i--);
-        MadeChange = true;
-      }
-    }
+    auto I = std::remove_if(TypeVec.begin(), TypeVec.end(),
+                            [NumElems](MVT VVT) {
+                              return VVT.getVectorNumElements() <= NumElems;
+                            });
+    MadeChange |= I != TypeVec.end();
+    TypeVec.erase(I, TypeVec.end());
+
     if (TypeVec.empty()) {  // FIXME: Really want an SMLoc here!
       TP.error("Type inference contradiction found, forcing '" +
                InputSet.getName() + "' to have more vector elements than '" +
@@ -615,13 +597,13 @@ bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand,
     // Only keep types that have same elements as VTOperand.
     TypeSet InputSet(VTOperand);
 
-    for (unsigned i = 0; i != VTOperand.TypeVec.size(); ++i) {
-      assert(isVector(VTOperand.TypeVec[i]) && "EnforceVector didn't work");
-      if (MVT(VTOperand.TypeVec[i]).getVectorNumElements() != NumElems) {
-        VTOperand.TypeVec.erase(VTOperand.TypeVec.begin()+i--);
-        MadeChange = true;
-      }
-    }
+    auto I = std::remove_if(VTOperand.TypeVec.begin(), VTOperand.TypeVec.end(),
+                            [NumElems](MVT VVT) {
+                              return VVT.getVectorNumElements() != NumElems;
+                            });
+    MadeChange |= I != VTOperand.TypeVec.end();
+    VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end());
+
     if (VTOperand.TypeVec.empty()) {  // FIXME: Really want an SMLoc here!
       TP.error("Type inference contradiction found, forcing '" +
                InputSet.getName() + "' to have same number elements as '" +
@@ -635,13 +617,13 @@ bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand,
     // Only keep types that have same elements as 'this'.
     TypeSet InputSet(*this);
 
-    for (unsigned i = 0; i != TypeVec.size(); ++i) {
-      assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
-      if (MVT(TypeVec[i]).getVectorNumElements() != NumElems) {
-        TypeVec.erase(TypeVec.begin()+i--);
-        MadeChange = true;
-      }
-    }
+    auto I = std::remove_if(TypeVec.begin(), TypeVec.end(),
+                            [NumElems](MVT VVT) {
+                              return VVT.getVectorNumElements() != NumElems;
+                            });
+    MadeChange |= I != TypeVec.end();
+    TypeVec.erase(I, TypeVec.end());
+
     if (TypeVec.empty()) {  // FIXME: Really want an SMLoc here!
       TP.error("Type inference contradiction found, forcing '" +
                InputSet.getName() + "' to have same number elements than '" +
@@ -3715,14 +3697,14 @@ void CodeGenDAGPatterns::GenerateVariants() {
   // intentionally do not reconsider these.  Any variants of added patterns have
   // already been added.
   //
-  for (PatternToMatch &PTM : PatternsToMatch) {
+  for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
     MultipleUseVarSet             DepVars;
     std::vector<TreePatternNode*> Variants;
-    FindDepVars(PTM.getSrcPattern(), DepVars);
+    FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars);
     DEBUG(errs() << "Dependent/multiply used variables: ");
     DEBUG(DumpDepVars(DepVars));
     DEBUG(errs() << "\n");
-    GenerateVariantsOf(PTM.getSrcPattern(), Variants, *this,
+    GenerateVariantsOf(PatternsToMatch[i].getSrcPattern(), Variants, *this,
                        DepVars);
 
     assert(!Variants.empty() && "Must create at least original variant!");
@@ -3732,7 +3714,7 @@ void CodeGenDAGPatterns::GenerateVariants() {
       continue;
 
     DEBUG(errs() << "FOUND VARIANTS OF: ";
-          PTM.getSrcPattern()->dump();
+          PatternsToMatch[i].getSrcPattern()->dump();
           errs() << "\n");
 
     for (unsigned v = 0, e = Variants.size(); v != e; ++v) {
@@ -3744,12 +3726,14 @@ void CodeGenDAGPatterns::GenerateVariants() {
 
       // Scan to see if an instruction or explicit pattern already matches this.
       bool AlreadyExists = false;
-      for (PatternToMatch &OtherPTM : PatternsToMatch) {
+      for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) {
         // Skip if the top level predicates do not match.
-        if (PTM.getPredicates() != OtherPTM.getPredicates())
+        if (PatternsToMatch[i].getPredicates() !=
+            PatternsToMatch[p].getPredicates())
           continue;
         // Check to see if this variant already exists.
-        if (Variant->isIsomorphicTo(OtherPTM.getSrcPattern(), DepVars)) {
+        if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(),
+                                    DepVars)) {
           DEBUG(errs() << "  *** ALREADY EXISTS, ignoring variant.\n");
           AlreadyExists = true;
           break;
@@ -3759,10 +3743,11 @@ void CodeGenDAGPatterns::GenerateVariants() {
       if (AlreadyExists) continue;
 
       // Otherwise, add it to the list of patterns we have.
-      PatternsToMatch.emplace_back(PTM.getSrcRecord(), PTM.getPredicates(),
-                                   Variant, PTM.getDstPattern(),
-                                   PTM.getDstRegs(), PTM.getAddedComplexity(),
-                                   Record::getNewUID());
+      PatternsToMatch.emplace_back(
+          PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(),
+          Variant, PatternsToMatch[i].getDstPattern(),
+          PatternsToMatch[i].getDstRegs(),
+          PatternsToMatch[i].getAddedComplexity(), Record::getNewUID());
     }
 
     DEBUG(errs() << "\n");