LLVM API Documentation

SparseBitVector.h
Go to the documentation of this file.
00001 //===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector -*- C++ -*- ===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the SparseBitVector class.  See the doxygen comment for
00011 // SparseBitVector for more details on the algorithm used.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_ADT_SPARSEBITVECTOR_H
00016 #define LLVM_ADT_SPARSEBITVECTOR_H
00017 
00018 #include "llvm/ADT/ilist.h"
00019 #include "llvm/ADT/ilist_node.h"
00020 #include "llvm/Support/DataTypes.h"
00021 #include "llvm/Support/ErrorHandling.h"
00022 #include "llvm/Support/MathExtras.h"
00023 #include "llvm/Support/raw_ostream.h"
00024 #include <cassert>
00025 #include <climits>
00026 
00027 namespace llvm {
00028 
00029 /// SparseBitVector is an implementation of a bitvector that is sparse by only
00030 /// storing the elements that have non-zero bits set.  In order to make this
00031 /// fast for the most common cases, SparseBitVector is implemented as a linked
00032 /// list of SparseBitVectorElements.  We maintain a pointer to the last
00033 /// SparseBitVectorElement accessed (in the form of a list iterator), in order
00034 /// to make multiple in-order test/set constant time after the first one is
00035 /// executed.  Note that using vectors to store SparseBitVectorElement's does
00036 /// not work out very well because it causes insertion in the middle to take
00037 /// enormous amounts of time with a large amount of bits.  Other structures that
00038 /// have better worst cases for insertion in the middle (various balanced trees,
00039 /// etc) do not perform as well in practice as a linked list with this iterator
00040 /// kept up to date.  They are also significantly more memory intensive.
00041 
00042 
00043 template <unsigned ElementSize = 128>
00044 struct SparseBitVectorElement
00045   : public ilist_node<SparseBitVectorElement<ElementSize> > {
00046 public:
00047   typedef unsigned long BitWord;
00048   typedef unsigned size_type;
00049   enum {
00050     BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
00051     BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
00052     BITS_PER_ELEMENT = ElementSize
00053   };
00054 
00055 private:
00056   // Index of Element in terms of where first bit starts.
00057   unsigned ElementIndex;
00058   BitWord Bits[BITWORDS_PER_ELEMENT];
00059   // Needed for sentinels
00060   friend struct ilist_sentinel_traits<SparseBitVectorElement>;
00061   SparseBitVectorElement() {
00062     ElementIndex = ~0U;
00063     memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
00064   }
00065 
00066 public:
00067   explicit SparseBitVectorElement(unsigned Idx) {
00068     ElementIndex = Idx;
00069     memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
00070   }
00071 
00072   // Comparison.
00073   bool operator==(const SparseBitVectorElement &RHS) const {
00074     if (ElementIndex != RHS.ElementIndex)
00075       return false;
00076     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
00077       if (Bits[i] != RHS.Bits[i])
00078         return false;
00079     return true;
00080   }
00081 
00082   bool operator!=(const SparseBitVectorElement &RHS) const {
00083     return !(*this == RHS);
00084   }
00085 
00086   // Return the bits that make up word Idx in our element.
00087   BitWord word(unsigned Idx) const {
00088     assert (Idx < BITWORDS_PER_ELEMENT);
00089     return Bits[Idx];
00090   }
00091 
00092   unsigned index() const {
00093     return ElementIndex;
00094   }
00095 
00096   bool empty() const {
00097     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
00098       if (Bits[i])
00099         return false;
00100     return true;
00101   }
00102 
00103   void set(unsigned Idx) {
00104     Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
00105   }
00106 
00107   bool test_and_set (unsigned Idx) {
00108     bool old = test(Idx);
00109     if (!old) {
00110       set(Idx);
00111       return true;
00112     }
00113     return false;
00114   }
00115 
00116   void reset(unsigned Idx) {
00117     Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
00118   }
00119 
00120   bool test(unsigned Idx) const {
00121     return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
00122   }
00123 
00124   size_type count() const {
00125     unsigned NumBits = 0;
00126     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
00127       if (sizeof(BitWord) == 4)
00128         NumBits += CountPopulation_32(Bits[i]);
00129       else if (sizeof(BitWord) == 8)
00130         NumBits += CountPopulation_64(Bits[i]);
00131       else
00132         llvm_unreachable("Unsupported!");
00133     return NumBits;
00134   }
00135 
00136   /// find_first - Returns the index of the first set bit.
00137   int find_first() const {
00138     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
00139       if (Bits[i] != 0) {
00140         if (sizeof(BitWord) == 4)
00141           return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
00142         if (sizeof(BitWord) == 8)
00143           return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
00144         llvm_unreachable("Unsupported!");
00145       }
00146     llvm_unreachable("Illegal empty element");
00147   }
00148 
00149   /// find_next - Returns the index of the next set bit starting from the
00150   /// "Curr" bit. Returns -1 if the next set bit is not found.
00151   int find_next(unsigned Curr) const {
00152     if (Curr >= BITS_PER_ELEMENT)
00153       return -1;
00154 
00155     unsigned WordPos = Curr / BITWORD_SIZE;
00156     unsigned BitPos = Curr % BITWORD_SIZE;
00157     BitWord Copy = Bits[WordPos];
00158     assert (WordPos <= BITWORDS_PER_ELEMENT
00159             && "Word Position outside of element");
00160 
00161     // Mask off previous bits.
00162     Copy &= ~0UL << BitPos;
00163 
00164     if (Copy != 0) {
00165       if (sizeof(BitWord) == 4)
00166         return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
00167       if (sizeof(BitWord) == 8)
00168         return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
00169       llvm_unreachable("Unsupported!");
00170     }
00171 
00172     // Check subsequent words.
00173     for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
00174       if (Bits[i] != 0) {
00175         if (sizeof(BitWord) == 4)
00176           return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
00177         if (sizeof(BitWord) == 8)
00178           return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
00179         llvm_unreachable("Unsupported!");
00180       }
00181     return -1;
00182   }
00183 
00184   // Union this element with RHS and return true if this one changed.
00185   bool unionWith(const SparseBitVectorElement &RHS) {
00186     bool changed = false;
00187     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
00188       BitWord old = changed ? 0 : Bits[i];
00189 
00190       Bits[i] |= RHS.Bits[i];
00191       if (!changed && old != Bits[i])
00192         changed = true;
00193     }
00194     return changed;
00195   }
00196 
00197   // Return true if we have any bits in common with RHS
00198   bool intersects(const SparseBitVectorElement &RHS) const {
00199     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
00200       if (RHS.Bits[i] & Bits[i])
00201         return true;
00202     }
00203     return false;
00204   }
00205 
00206   // Intersect this Element with RHS and return true if this one changed.
00207   // BecameZero is set to true if this element became all-zero bits.
00208   bool intersectWith(const SparseBitVectorElement &RHS,
00209                      bool &BecameZero) {
00210     bool changed = false;
00211     bool allzero = true;
00212 
00213     BecameZero = false;
00214     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
00215       BitWord old = changed ? 0 : Bits[i];
00216 
00217       Bits[i] &= RHS.Bits[i];
00218       if (Bits[i] != 0)
00219         allzero = false;
00220 
00221       if (!changed && old != Bits[i])
00222         changed = true;
00223     }
00224     BecameZero = allzero;
00225     return changed;
00226   }
00227   // Intersect this Element with the complement of RHS and return true if this
00228   // one changed.  BecameZero is set to true if this element became all-zero
00229   // bits.
00230   bool intersectWithComplement(const SparseBitVectorElement &RHS,
00231                                bool &BecameZero) {
00232     bool changed = false;
00233     bool allzero = true;
00234 
00235     BecameZero = false;
00236     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
00237       BitWord old = changed ? 0 : Bits[i];
00238 
00239       Bits[i] &= ~RHS.Bits[i];
00240       if (Bits[i] != 0)
00241         allzero = false;
00242 
00243       if (!changed && old != Bits[i])
00244         changed = true;
00245     }
00246     BecameZero = allzero;
00247     return changed;
00248   }
00249   // Three argument version of intersectWithComplement that intersects
00250   // RHS1 & ~RHS2 into this element
00251   void intersectWithComplement(const SparseBitVectorElement &RHS1,
00252                                const SparseBitVectorElement &RHS2,
00253                                bool &BecameZero) {
00254     bool allzero = true;
00255 
00256     BecameZero = false;
00257     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
00258       Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
00259       if (Bits[i] != 0)
00260         allzero = false;
00261     }
00262     BecameZero = allzero;
00263   }
00264 };
00265 
00266 template <unsigned ElementSize>
00267 struct ilist_traits<SparseBitVectorElement<ElementSize> >
00268   : public ilist_default_traits<SparseBitVectorElement<ElementSize> > {
00269   typedef SparseBitVectorElement<ElementSize> Element;
00270 
00271   Element *createSentinel() const { return static_cast<Element *>(&Sentinel); }
00272   static void destroySentinel(Element *) {}
00273 
00274   Element *provideInitialHead() const { return createSentinel(); }
00275   Element *ensureHead(Element *) const { return createSentinel(); }
00276   static void noteHead(Element *, Element *) {}
00277 
00278 private:
00279   mutable ilist_half_node<Element> Sentinel;
00280 };
00281 
00282 template <unsigned ElementSize = 128>
00283 class SparseBitVector {
00284   typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;
00285   typedef typename ElementList::iterator ElementListIter;
00286   typedef typename ElementList::const_iterator ElementListConstIter;
00287   enum {
00288     BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
00289   };
00290 
00291   // Pointer to our current Element.
00292   ElementListIter CurrElementIter;
00293   ElementList Elements;
00294 
00295   // This is like std::lower_bound, except we do linear searching from the
00296   // current position.
00297   ElementListIter FindLowerBound(unsigned ElementIndex) {
00298 
00299     if (Elements.empty()) {
00300       CurrElementIter = Elements.begin();
00301       return Elements.begin();
00302     }
00303 
00304     // Make sure our current iterator is valid.
00305     if (CurrElementIter == Elements.end())
00306       --CurrElementIter;
00307 
00308     // Search from our current iterator, either backwards or forwards,
00309     // depending on what element we are looking for.
00310     ElementListIter ElementIter = CurrElementIter;
00311     if (CurrElementIter->index() == ElementIndex) {
00312       return ElementIter;
00313     } else if (CurrElementIter->index() > ElementIndex) {
00314       while (ElementIter != Elements.begin()
00315              && ElementIter->index() > ElementIndex)
00316         --ElementIter;
00317     } else {
00318       while (ElementIter != Elements.end() &&
00319              ElementIter->index() < ElementIndex)
00320         ++ElementIter;
00321     }
00322     CurrElementIter = ElementIter;
00323     return ElementIter;
00324   }
00325 
00326   // Iterator to walk set bits in the bitmap.  This iterator is a lot uglier
00327   // than it would be, in order to be efficient.
00328   class SparseBitVectorIterator {
00329   private:
00330     bool AtEnd;
00331 
00332     const SparseBitVector<ElementSize> *BitVector;
00333 
00334     // Current element inside of bitmap.
00335     ElementListConstIter Iter;
00336 
00337     // Current bit number inside of our bitmap.
00338     unsigned BitNumber;
00339 
00340     // Current word number inside of our element.
00341     unsigned WordNumber;
00342 
00343     // Current bits from the element.
00344     typename SparseBitVectorElement<ElementSize>::BitWord Bits;
00345 
00346     // Move our iterator to the first non-zero bit in the bitmap.
00347     void AdvanceToFirstNonZero() {
00348       if (AtEnd)
00349         return;
00350       if (BitVector->Elements.empty()) {
00351         AtEnd = true;
00352         return;
00353       }
00354       Iter = BitVector->Elements.begin();
00355       BitNumber = Iter->index() * ElementSize;
00356       unsigned BitPos = Iter->find_first();
00357       BitNumber += BitPos;
00358       WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
00359       Bits = Iter->word(WordNumber);
00360       Bits >>= BitPos % BITWORD_SIZE;
00361     }
00362 
00363     // Move our iterator to the next non-zero bit.
00364     void AdvanceToNextNonZero() {
00365       if (AtEnd)
00366         return;
00367 
00368       while (Bits && !(Bits & 1)) {
00369         Bits >>= 1;
00370         BitNumber += 1;
00371       }
00372 
00373       // See if we ran out of Bits in this word.
00374       if (!Bits) {
00375         int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
00376         // If we ran out of set bits in this element, move to next element.
00377         if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
00378           ++Iter;
00379           WordNumber = 0;
00380 
00381           // We may run out of elements in the bitmap.
00382           if (Iter == BitVector->Elements.end()) {
00383             AtEnd = true;
00384             return;
00385           }
00386           // Set up for next non-zero word in bitmap.
00387           BitNumber = Iter->index() * ElementSize;
00388           NextSetBitNumber = Iter->find_first();
00389           BitNumber += NextSetBitNumber;
00390           WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
00391           Bits = Iter->word(WordNumber);
00392           Bits >>= NextSetBitNumber % BITWORD_SIZE;
00393         } else {
00394           WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
00395           Bits = Iter->word(WordNumber);
00396           Bits >>= NextSetBitNumber % BITWORD_SIZE;
00397           BitNumber = Iter->index() * ElementSize;
00398           BitNumber += NextSetBitNumber;
00399         }
00400       }
00401     }
00402   public:
00403     // Preincrement.
00404     inline SparseBitVectorIterator& operator++() {
00405       ++BitNumber;
00406       Bits >>= 1;
00407       AdvanceToNextNonZero();
00408       return *this;
00409     }
00410 
00411     // Postincrement.
00412     inline SparseBitVectorIterator operator++(int) {
00413       SparseBitVectorIterator tmp = *this;
00414       ++*this;
00415       return tmp;
00416     }
00417 
00418     // Return the current set bit number.
00419     unsigned operator*() const {
00420       return BitNumber;
00421     }
00422 
00423     bool operator==(const SparseBitVectorIterator &RHS) const {
00424       // If they are both at the end, ignore the rest of the fields.
00425       if (AtEnd && RHS.AtEnd)
00426         return true;
00427       // Otherwise they are the same if they have the same bit number and
00428       // bitmap.
00429       return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
00430     }
00431     bool operator!=(const SparseBitVectorIterator &RHS) const {
00432       return !(*this == RHS);
00433     }
00434     SparseBitVectorIterator(): BitVector(NULL) {
00435     }
00436 
00437 
00438     SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
00439                             bool end = false):BitVector(RHS) {
00440       Iter = BitVector->Elements.begin();
00441       BitNumber = 0;
00442       Bits = 0;
00443       WordNumber = ~0;
00444       AtEnd = end;
00445       AdvanceToFirstNonZero();
00446     }
00447   };
00448 public:
00449   typedef SparseBitVectorIterator iterator;
00450 
00451   SparseBitVector () {
00452     CurrElementIter = Elements.begin ();
00453   }
00454 
00455   ~SparseBitVector() {
00456   }
00457 
00458   // SparseBitVector copy ctor.
00459   SparseBitVector(const SparseBitVector &RHS) {
00460     ElementListConstIter ElementIter = RHS.Elements.begin();
00461     while (ElementIter != RHS.Elements.end()) {
00462       Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
00463       ++ElementIter;
00464     }
00465 
00466     CurrElementIter = Elements.begin ();
00467   }
00468 
00469   // Clear.
00470   void clear() {
00471     Elements.clear();
00472   }
00473 
00474   // Assignment
00475   SparseBitVector& operator=(const SparseBitVector& RHS) {
00476     Elements.clear();
00477 
00478     ElementListConstIter ElementIter = RHS.Elements.begin();
00479     while (ElementIter != RHS.Elements.end()) {
00480       Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
00481       ++ElementIter;
00482     }
00483 
00484     CurrElementIter = Elements.begin ();
00485 
00486     return *this;
00487   }
00488 
00489   // Test, Reset, and Set a bit in the bitmap.
00490   bool test(unsigned Idx) {
00491     if (Elements.empty())
00492       return false;
00493 
00494     unsigned ElementIndex = Idx / ElementSize;
00495     ElementListIter ElementIter = FindLowerBound(ElementIndex);
00496 
00497     // If we can't find an element that is supposed to contain this bit, there
00498     // is nothing more to do.
00499     if (ElementIter == Elements.end() ||
00500         ElementIter->index() != ElementIndex)
00501       return false;
00502     return ElementIter->test(Idx % ElementSize);
00503   }
00504 
00505   void reset(unsigned Idx) {
00506     if (Elements.empty())
00507       return;
00508 
00509     unsigned ElementIndex = Idx / ElementSize;
00510     ElementListIter ElementIter = FindLowerBound(ElementIndex);
00511 
00512     // If we can't find an element that is supposed to contain this bit, there
00513     // is nothing more to do.
00514     if (ElementIter == Elements.end() ||
00515         ElementIter->index() != ElementIndex)
00516       return;
00517     ElementIter->reset(Idx % ElementSize);
00518 
00519     // When the element is zeroed out, delete it.
00520     if (ElementIter->empty()) {
00521       ++CurrElementIter;
00522       Elements.erase(ElementIter);
00523     }
00524   }
00525 
00526   void set(unsigned Idx) {
00527     unsigned ElementIndex = Idx / ElementSize;
00528     SparseBitVectorElement<ElementSize> *Element;
00529     ElementListIter ElementIter;
00530     if (Elements.empty()) {
00531       Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
00532       ElementIter = Elements.insert(Elements.end(), Element);
00533 
00534     } else {
00535       ElementIter = FindLowerBound(ElementIndex);
00536 
00537       if (ElementIter == Elements.end() ||
00538           ElementIter->index() != ElementIndex) {
00539         Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
00540         // We may have hit the beginning of our SparseBitVector, in which case,
00541         // we may need to insert right after this element, which requires moving
00542         // the current iterator forward one, because insert does insert before.
00543         if (ElementIter != Elements.end() &&
00544             ElementIter->index() < ElementIndex)
00545           ElementIter = Elements.insert(++ElementIter, Element);
00546         else
00547           ElementIter = Elements.insert(ElementIter, Element);
00548       }
00549     }
00550     CurrElementIter = ElementIter;
00551 
00552     ElementIter->set(Idx % ElementSize);
00553   }
00554 
00555   bool test_and_set (unsigned Idx) {
00556     bool old = test(Idx);
00557     if (!old) {
00558       set(Idx);
00559       return true;
00560     }
00561     return false;
00562   }
00563 
00564   bool operator!=(const SparseBitVector &RHS) const {
00565     return !(*this == RHS);
00566   }
00567 
00568   bool operator==(const SparseBitVector &RHS) const {
00569     ElementListConstIter Iter1 = Elements.begin();
00570     ElementListConstIter Iter2 = RHS.Elements.begin();
00571 
00572     for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
00573          ++Iter1, ++Iter2) {
00574       if (*Iter1 != *Iter2)
00575         return false;
00576     }
00577     return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
00578   }
00579 
00580   // Union our bitmap with the RHS and return true if we changed.
00581   bool operator|=(const SparseBitVector &RHS) {
00582     bool changed = false;
00583     ElementListIter Iter1 = Elements.begin();
00584     ElementListConstIter Iter2 = RHS.Elements.begin();
00585 
00586     // If RHS is empty, we are done
00587     if (RHS.Elements.empty())
00588       return false;
00589 
00590     while (Iter2 != RHS.Elements.end()) {
00591       if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
00592         Elements.insert(Iter1,
00593                         new SparseBitVectorElement<ElementSize>(*Iter2));
00594         ++Iter2;
00595         changed = true;
00596       } else if (Iter1->index() == Iter2->index()) {
00597         changed |= Iter1->unionWith(*Iter2);
00598         ++Iter1;
00599         ++Iter2;
00600       } else {
00601         ++Iter1;
00602       }
00603     }
00604     CurrElementIter = Elements.begin();
00605     return changed;
00606   }
00607 
00608   // Intersect our bitmap with the RHS and return true if ours changed.
00609   bool operator&=(const SparseBitVector &RHS) {
00610     bool changed = false;
00611     ElementListIter Iter1 = Elements.begin();
00612     ElementListConstIter Iter2 = RHS.Elements.begin();
00613 
00614     // Check if both bitmaps are empty.
00615     if (Elements.empty() && RHS.Elements.empty())
00616       return false;
00617 
00618     // Loop through, intersecting as we go, erasing elements when necessary.
00619     while (Iter2 != RHS.Elements.end()) {
00620       if (Iter1 == Elements.end()) {
00621         CurrElementIter = Elements.begin();
00622         return changed;
00623       }
00624 
00625       if (Iter1->index() > Iter2->index()) {
00626         ++Iter2;
00627       } else if (Iter1->index() == Iter2->index()) {
00628         bool BecameZero;
00629         changed |= Iter1->intersectWith(*Iter2, BecameZero);
00630         if (BecameZero) {
00631           ElementListIter IterTmp = Iter1;
00632           ++Iter1;
00633           Elements.erase(IterTmp);
00634         } else {
00635           ++Iter1;
00636         }
00637         ++Iter2;
00638       } else {
00639         ElementListIter IterTmp = Iter1;
00640         ++Iter1;
00641         Elements.erase(IterTmp);
00642       }
00643     }
00644     Elements.erase(Iter1, Elements.end());
00645     CurrElementIter = Elements.begin();
00646     return changed;
00647   }
00648 
00649   // Intersect our bitmap with the complement of the RHS and return true
00650   // if ours changed.
00651   bool intersectWithComplement(const SparseBitVector &RHS) {
00652     bool changed = false;
00653     ElementListIter Iter1 = Elements.begin();
00654     ElementListConstIter Iter2 = RHS.Elements.begin();
00655 
00656     // If either our bitmap or RHS is empty, we are done
00657     if (Elements.empty() || RHS.Elements.empty())
00658       return false;
00659 
00660     // Loop through, intersecting as we go, erasing elements when necessary.
00661     while (Iter2 != RHS.Elements.end()) {
00662       if (Iter1 == Elements.end()) {
00663         CurrElementIter = Elements.begin();
00664         return changed;
00665       }
00666 
00667       if (Iter1->index() > Iter2->index()) {
00668         ++Iter2;
00669       } else if (Iter1->index() == Iter2->index()) {
00670         bool BecameZero;
00671         changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
00672         if (BecameZero) {
00673           ElementListIter IterTmp = Iter1;
00674           ++Iter1;
00675           Elements.erase(IterTmp);
00676         } else {
00677           ++Iter1;
00678         }
00679         ++Iter2;
00680       } else {
00681         ++Iter1;
00682       }
00683     }
00684     CurrElementIter = Elements.begin();
00685     return changed;
00686   }
00687 
00688   bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
00689     return intersectWithComplement(*RHS);
00690   }
00691 
00692 
00693   //  Three argument version of intersectWithComplement.
00694   //  Result of RHS1 & ~RHS2 is stored into this bitmap.
00695   void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
00696                                const SparseBitVector<ElementSize> &RHS2)
00697   {
00698     Elements.clear();
00699     CurrElementIter = Elements.begin();
00700     ElementListConstIter Iter1 = RHS1.Elements.begin();
00701     ElementListConstIter Iter2 = RHS2.Elements.begin();
00702 
00703     // If RHS1 is empty, we are done
00704     // If RHS2 is empty, we still have to copy RHS1
00705     if (RHS1.Elements.empty())
00706       return;
00707 
00708     // Loop through, intersecting as we go, erasing elements when necessary.
00709     while (Iter2 != RHS2.Elements.end()) {
00710       if (Iter1 == RHS1.Elements.end())
00711         return;
00712 
00713       if (Iter1->index() > Iter2->index()) {
00714         ++Iter2;
00715       } else if (Iter1->index() == Iter2->index()) {
00716         bool BecameZero = false;
00717         SparseBitVectorElement<ElementSize> *NewElement =
00718           new SparseBitVectorElement<ElementSize>(Iter1->index());
00719         NewElement->intersectWithComplement(*Iter1, *Iter2, BecameZero);
00720         if (!BecameZero) {
00721           Elements.push_back(NewElement);
00722         }
00723         else
00724           delete NewElement;
00725         ++Iter1;
00726         ++Iter2;
00727       } else {
00728         SparseBitVectorElement<ElementSize> *NewElement =
00729           new SparseBitVectorElement<ElementSize>(*Iter1);
00730         Elements.push_back(NewElement);
00731         ++Iter1;
00732       }
00733     }
00734 
00735     // copy the remaining elements
00736     while (Iter1 != RHS1.Elements.end()) {
00737         SparseBitVectorElement<ElementSize> *NewElement =
00738           new SparseBitVectorElement<ElementSize>(*Iter1);
00739         Elements.push_back(NewElement);
00740         ++Iter1;
00741       }
00742 
00743     return;
00744   }
00745 
00746   void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
00747                                const SparseBitVector<ElementSize> *RHS2) {
00748     intersectWithComplement(*RHS1, *RHS2);
00749   }
00750 
00751   bool intersects(const SparseBitVector<ElementSize> *RHS) const {
00752     return intersects(*RHS);
00753   }
00754 
00755   // Return true if we share any bits in common with RHS
00756   bool intersects(const SparseBitVector<ElementSize> &RHS) const {
00757     ElementListConstIter Iter1 = Elements.begin();
00758     ElementListConstIter Iter2 = RHS.Elements.begin();
00759 
00760     // Check if both bitmaps are empty.
00761     if (Elements.empty() && RHS.Elements.empty())
00762       return false;
00763 
00764     // Loop through, intersecting stopping when we hit bits in common.
00765     while (Iter2 != RHS.Elements.end()) {
00766       if (Iter1 == Elements.end())
00767         return false;
00768 
00769       if (Iter1->index() > Iter2->index()) {
00770         ++Iter2;
00771       } else if (Iter1->index() == Iter2->index()) {
00772         if (Iter1->intersects(*Iter2))
00773           return true;
00774         ++Iter1;
00775         ++Iter2;
00776       } else {
00777         ++Iter1;
00778       }
00779     }
00780     return false;
00781   }
00782 
00783   // Return true iff all bits set in this SparseBitVector are
00784   // also set in RHS.
00785   bool contains(const SparseBitVector<ElementSize> &RHS) const {
00786     SparseBitVector<ElementSize> Result(*this);
00787     Result &= RHS;
00788     return (Result == RHS);
00789   }
00790 
00791   // Return the first set bit in the bitmap.  Return -1 if no bits are set.
00792   int find_first() const {
00793     if (Elements.empty())
00794       return -1;
00795     const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
00796     return (First.index() * ElementSize) + First.find_first();
00797   }
00798 
00799   // Return true if the SparseBitVector is empty
00800   bool empty() const {
00801     return Elements.empty();
00802   }
00803 
00804   unsigned count() const {
00805     unsigned BitCount = 0;
00806     for (ElementListConstIter Iter = Elements.begin();
00807          Iter != Elements.end();
00808          ++Iter)
00809       BitCount += Iter->count();
00810 
00811     return BitCount;
00812   }
00813   iterator begin() const {
00814     return iterator(this);
00815   }
00816 
00817   iterator end() const {
00818     return iterator(this, true);
00819   }
00820 };
00821 
00822 // Convenience functions to allow Or and And without dereferencing in the user
00823 // code.
00824 
00825 template <unsigned ElementSize>
00826 inline bool operator |=(SparseBitVector<ElementSize> &LHS,
00827                         const SparseBitVector<ElementSize> *RHS) {
00828   return LHS |= *RHS;
00829 }
00830 
00831 template <unsigned ElementSize>
00832 inline bool operator |=(SparseBitVector<ElementSize> *LHS,
00833                         const SparseBitVector<ElementSize> &RHS) {
00834   return LHS->operator|=(RHS);
00835 }
00836 
00837 template <unsigned ElementSize>
00838 inline bool operator &=(SparseBitVector<ElementSize> *LHS,
00839                         const SparseBitVector<ElementSize> &RHS) {
00840   return LHS->operator&=(RHS);
00841 }
00842 
00843 template <unsigned ElementSize>
00844 inline bool operator &=(SparseBitVector<ElementSize> &LHS,
00845                         const SparseBitVector<ElementSize> *RHS) {
00846   return LHS &= *RHS;
00847 }
00848 
00849 // Convenience functions for infix union, intersection, difference operators.
00850 
00851 template <unsigned ElementSize>
00852 inline SparseBitVector<ElementSize>
00853 operator|(const SparseBitVector<ElementSize> &LHS,
00854           const SparseBitVector<ElementSize> &RHS) {
00855   SparseBitVector<ElementSize> Result(LHS);
00856   Result |= RHS;
00857   return Result;
00858 }
00859 
00860 template <unsigned ElementSize>
00861 inline SparseBitVector<ElementSize>
00862 operator&(const SparseBitVector<ElementSize> &LHS,
00863           const SparseBitVector<ElementSize> &RHS) {
00864   SparseBitVector<ElementSize> Result(LHS);
00865   Result &= RHS;
00866   return Result;
00867 }
00868 
00869 template <unsigned ElementSize>
00870 inline SparseBitVector<ElementSize>
00871 operator-(const SparseBitVector<ElementSize> &LHS,
00872           const SparseBitVector<ElementSize> &RHS) {
00873   SparseBitVector<ElementSize> Result;
00874   Result.intersectWithComplement(LHS, RHS);
00875   return Result;
00876 }
00877 
00878 
00879 
00880 
00881 // Dump a SparseBitVector to a stream
00882 template <unsigned ElementSize>
00883 void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
00884   out << "[";
00885 
00886   typename SparseBitVector<ElementSize>::iterator bi = LHS.begin(),
00887     be = LHS.end();
00888   if (bi != be) {
00889     out << *bi;
00890     for (++bi; bi != be; ++bi) {
00891       out << " " << *bi;
00892     }
00893   }
00894   out << "]\n";
00895 }
00896 } // end namespace llvm
00897 
00898 #endif