Revert commit 158979 (dyatkovskiy) since it is causing several buildbots to
[oota-llvm.git] / include / llvm / Support / IntegersSubset.h
index ac4eb97a3ad52dc68c55b4234b2bb359c99ed164..2ceeea5b665dfc236d88c8e95ffa43c15d205a8d 100644 (file)
@@ -1,4 +1,4 @@
-//===-- llvm/ConstantRangesSet.h - The constant set of ranges ---*- C++ -*-===//
+//===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -9,10 +9,9 @@
 //
 /// @file
 /// This file contains class that implements constant set of ranges:
-/// [<Low0,High0>,...,<LowN,HighN>]. Mainly, this set is used by SwitchInst and
-/// represents case value that may contain multiple ranges for a single
-/// successor.
-///
+/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
+/// SwitchInst and was used for case value representation that may contain
+/// multiple ranges for a single successor.
 //
 //===----------------------------------------------------------------------===//
 
@@ -184,7 +183,9 @@ public:
     typedef std::pair<self, self> SubRes;
     
     IntRange() : IsEmpty(true) {}
-    
+    IntRange(const self &RHS) :
+      Low(RHS.Low), High(RHS.High),
+      IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
     IntRange(const IntType &C) :
       Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
     
@@ -280,7 +281,9 @@ public:
   typedef std::list<IntTy> FlatCollectionTy;
   typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
   typedef SmallVector<RangeLinkTy, 64> RangeLinksTy;
-  typedef typename RangeLinksTy::iterator RangeLinksConstIt;
+  typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
+  
+  typedef IntegersSubsetGeneric<IntTy> self;
   
 protected:
   
@@ -290,7 +293,7 @@ protected:
 public:
   
   template<class RangesCollectionTy>
-  IntegersSubsetGeneric(const RangesCollectionTy& Links) {
+  explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
     assert(Links.size() && "Empty ranges are not allowed.");
     for (typename RangesCollectionTy::const_iterator i = Links.begin(),
          e = Links.end(); i != e; ++i) {
@@ -304,6 +307,26 @@ public:
     }
   }
   
+  IntegersSubsetGeneric(const self& RHS) {
+    *this = RHS;
+  }
+  
+  self& operator=(const self& RHS) {
+    FlatCollection.clear();
+    RangeLinks.clear();
+    for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
+         i != e; ++i) {
+      RangeLinkTy RangeLink;
+      FlatCollection.push_back(*(i->first));
+      RangeLink.first = &FlatCollection.back();
+      if (i->first != i->second)
+        FlatCollection.push_back(*(i->second));
+      RangeLink.second = &FlatCollection.back();
+      RangeLinks.push_back(RangeLink);
+    }
+    return *this;
+  }
+  
   typedef IntRange<IntTy> Range;
  
   /// Checks is the given constant satisfies this case. Returns
@@ -314,8 +337,8 @@ public:
       if (RangeLinks[i].first == RangeLinks[i].second) {
         if (*RangeLinks[i].first == CheckingVal)
           return true;
-      } else if (*RangeLinks[i].first >= CheckingVal &&
-                 *RangeLinks[i].second <= CheckingVal) 
+      } else if (*RangeLinks[i].first <= CheckingVal &&
+                 *RangeLinks[i].second >= CheckingVal) 
         return true;
     }
     return false;    
@@ -357,7 +380,7 @@ public:
     for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
       const APInt &Low = getItem(i).getLow();
       const APInt &High = getItem(i).getHigh();
-      const APInt &S = High - Low;
+      APInt S = High - Low + 1;
       sz += S;
     }
     return sz.getZExtValue();    
@@ -372,12 +395,12 @@ public:
     for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
       const APInt &Low = getItem(i).getLow();
       const APInt &High = getItem(i).getHigh();      
-      const APInt& S = High - Low;
+      APInt S = High - Low + 1;
       APInt oldSz = sz;
       sz += S;
-      if (oldSz.uge(i) && sz.ult(i)) {
+      if (sz.ugt(idx)) {
         APInt Res = Low;
-        APInt Offset(oldSz.getBitWidth(), i);
+        APInt Offset(oldSz.getBitWidth(), idx);
         Offset -= oldSz;
         Res += Offset;
         return Res;
@@ -436,9 +459,8 @@ public:
   IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
                                 Holder(C) {}
   
-  // implicit
   template<class RangesCollectionTy>
-  IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
+  explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
     std::vector<Constant*> Elts;
     Elts.reserve(Src.size());
     for (typename RangesCollectionTy::const_iterator i = Src.begin(),