Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:09

0001 //===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file defines the SparseBitVector class.  See the doxygen comment for
0011 /// SparseBitVector for more details on the algorithm used.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_ADT_SPARSEBITVECTOR_H
0016 #define LLVM_ADT_SPARSEBITVECTOR_H
0017 
0018 #include "llvm/ADT/bit.h"
0019 #include "llvm/Support/ErrorHandling.h"
0020 #include "llvm/Support/raw_ostream.h"
0021 #include <cassert>
0022 #include <climits>
0023 #include <cstring>
0024 #include <iterator>
0025 #include <list>
0026 
0027 namespace llvm {
0028 
0029 /// SparseBitVector is an implementation of a bitvector that is sparse by only
0030 /// storing the elements that have non-zero bits set.  In order to make this
0031 /// fast for the most common cases, SparseBitVector is implemented as a linked
0032 /// list of SparseBitVectorElements.  We maintain a pointer to the last
0033 /// SparseBitVectorElement accessed (in the form of a list iterator), in order
0034 /// to make multiple in-order test/set constant time after the first one is
0035 /// executed.  Note that using vectors to store SparseBitVectorElement's does
0036 /// not work out very well because it causes insertion in the middle to take
0037 /// enormous amounts of time with a large amount of bits.  Other structures that
0038 /// have better worst cases for insertion in the middle (various balanced trees,
0039 /// etc) do not perform as well in practice as a linked list with this iterator
0040 /// kept up to date.  They are also significantly more memory intensive.
0041 
0042 template <unsigned ElementSize = 128> struct SparseBitVectorElement {
0043 public:
0044   using BitWord = unsigned long;
0045   using size_type = unsigned;
0046   enum {
0047     BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
0048     BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
0049     BITS_PER_ELEMENT = ElementSize
0050   };
0051 
0052 private:
0053   // Index of Element in terms of where first bit starts.
0054   unsigned ElementIndex;
0055   BitWord Bits[BITWORDS_PER_ELEMENT];
0056 
0057   SparseBitVectorElement() {
0058     ElementIndex = ~0U;
0059     memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
0060   }
0061 
0062 public:
0063   explicit SparseBitVectorElement(unsigned Idx) {
0064     ElementIndex = Idx;
0065     memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
0066   }
0067 
0068   // Comparison.
0069   bool operator==(const SparseBitVectorElement &RHS) const {
0070     if (ElementIndex != RHS.ElementIndex)
0071       return false;
0072     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0073       if (Bits[i] != RHS.Bits[i])
0074         return false;
0075     return true;
0076   }
0077 
0078   bool operator!=(const SparseBitVectorElement &RHS) const {
0079     return !(*this == RHS);
0080   }
0081 
0082   // Return the bits that make up word Idx in our element.
0083   BitWord word(unsigned Idx) const {
0084     assert(Idx < BITWORDS_PER_ELEMENT);
0085     return Bits[Idx];
0086   }
0087 
0088   unsigned index() const {
0089     return ElementIndex;
0090   }
0091 
0092   bool empty() const {
0093     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0094       if (Bits[i])
0095         return false;
0096     return true;
0097   }
0098 
0099   void set(unsigned Idx) {
0100     Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
0101   }
0102 
0103   bool test_and_set(unsigned Idx) {
0104     bool old = test(Idx);
0105     if (!old) {
0106       set(Idx);
0107       return true;
0108     }
0109     return false;
0110   }
0111 
0112   void reset(unsigned Idx) {
0113     Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
0114   }
0115 
0116   bool test(unsigned Idx) const {
0117     return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
0118   }
0119 
0120   size_type count() const {
0121     unsigned NumBits = 0;
0122     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0123       NumBits += llvm::popcount(Bits[i]);
0124     return NumBits;
0125   }
0126 
0127   /// find_first - Returns the index of the first set bit.
0128   int find_first() const {
0129     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0130       if (Bits[i] != 0)
0131         return i * BITWORD_SIZE + llvm::countr_zero(Bits[i]);
0132     llvm_unreachable("Illegal empty element");
0133   }
0134 
0135   /// find_last - Returns the index of the last set bit.
0136   int find_last() const {
0137     for (unsigned I = 0; I < BITWORDS_PER_ELEMENT; ++I) {
0138       unsigned Idx = BITWORDS_PER_ELEMENT - I - 1;
0139       if (Bits[Idx] != 0)
0140         return Idx * BITWORD_SIZE + BITWORD_SIZE -
0141                llvm::countl_zero(Bits[Idx]) - 1;
0142     }
0143     llvm_unreachable("Illegal empty element");
0144   }
0145 
0146   /// find_next - Returns the index of the next set bit starting from the
0147   /// "Curr" bit. Returns -1 if the next set bit is not found.
0148   int find_next(unsigned Curr) const {
0149     if (Curr >= BITS_PER_ELEMENT)
0150       return -1;
0151 
0152     unsigned WordPos = Curr / BITWORD_SIZE;
0153     unsigned BitPos = Curr % BITWORD_SIZE;
0154     BitWord Copy = Bits[WordPos];
0155     assert(WordPos <= BITWORDS_PER_ELEMENT
0156            && "Word Position outside of element");
0157 
0158     // Mask off previous bits.
0159     Copy &= ~0UL << BitPos;
0160 
0161     if (Copy != 0)
0162       return WordPos * BITWORD_SIZE + llvm::countr_zero(Copy);
0163 
0164     // Check subsequent words.
0165     for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
0166       if (Bits[i] != 0)
0167         return i * BITWORD_SIZE + llvm::countr_zero(Bits[i]);
0168     return -1;
0169   }
0170 
0171   // Union this element with RHS and return true if this one changed.
0172   bool unionWith(const SparseBitVectorElement &RHS) {
0173     bool changed = false;
0174     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0175       BitWord old = changed ? 0 : Bits[i];
0176 
0177       Bits[i] |= RHS.Bits[i];
0178       if (!changed && old != Bits[i])
0179         changed = true;
0180     }
0181     return changed;
0182   }
0183 
0184   // Return true if we have any bits in common with RHS
0185   bool intersects(const SparseBitVectorElement &RHS) const {
0186     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0187       if (RHS.Bits[i] & Bits[i])
0188         return true;
0189     }
0190     return false;
0191   }
0192 
0193   // Intersect this Element with RHS and return true if this one changed.
0194   // BecameZero is set to true if this element became all-zero bits.
0195   bool intersectWith(const SparseBitVectorElement &RHS,
0196                      bool &BecameZero) {
0197     bool changed = false;
0198     bool allzero = true;
0199 
0200     BecameZero = false;
0201     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0202       BitWord old = changed ? 0 : Bits[i];
0203 
0204       Bits[i] &= RHS.Bits[i];
0205       if (Bits[i] != 0)
0206         allzero = false;
0207 
0208       if (!changed && old != Bits[i])
0209         changed = true;
0210     }
0211     BecameZero = allzero;
0212     return changed;
0213   }
0214 
0215   // Intersect this Element with the complement of RHS and return true if this
0216   // one changed.  BecameZero is set to true if this element became all-zero
0217   // bits.
0218   bool intersectWithComplement(const SparseBitVectorElement &RHS,
0219                                bool &BecameZero) {
0220     bool changed = false;
0221     bool allzero = true;
0222 
0223     BecameZero = false;
0224     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0225       BitWord old = changed ? 0 : Bits[i];
0226 
0227       Bits[i] &= ~RHS.Bits[i];
0228       if (Bits[i] != 0)
0229         allzero = false;
0230 
0231       if (!changed && old != Bits[i])
0232         changed = true;
0233     }
0234     BecameZero = allzero;
0235     return changed;
0236   }
0237 
0238   // Three argument version of intersectWithComplement that intersects
0239   // RHS1 & ~RHS2 into this element
0240   void intersectWithComplement(const SparseBitVectorElement &RHS1,
0241                                const SparseBitVectorElement &RHS2,
0242                                bool &BecameZero) {
0243     bool allzero = true;
0244 
0245     BecameZero = false;
0246     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0247       Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
0248       if (Bits[i] != 0)
0249         allzero = false;
0250     }
0251     BecameZero = allzero;
0252   }
0253 };
0254 
0255 template <unsigned ElementSize = 128>
0256 class SparseBitVector {
0257   using ElementList = std::list<SparseBitVectorElement<ElementSize>>;
0258   using ElementListIter = typename ElementList::iterator;
0259   using ElementListConstIter = typename ElementList::const_iterator;
0260   enum {
0261     BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
0262   };
0263 
0264   ElementList Elements;
0265   // Pointer to our current Element. This has no visible effect on the external
0266   // state of a SparseBitVector, it's just used to improve performance in the
0267   // common case of testing/modifying bits with similar indices.
0268   mutable ElementListIter CurrElementIter;
0269 
0270   // This is like std::lower_bound, except we do linear searching from the
0271   // current position.
0272   ElementListIter FindLowerBoundImpl(unsigned ElementIndex) const {
0273 
0274     // We cache a non-const iterator so we're forced to resort to const_cast to
0275     // get the begin/end in the case where 'this' is const. To avoid duplication
0276     // of code with the only difference being whether the const cast is present
0277     // 'this' is always const in this particular function and we sort out the
0278     // difference in FindLowerBound and FindLowerBoundConst.
0279     ElementListIter Begin =
0280         const_cast<SparseBitVector<ElementSize> *>(this)->Elements.begin();
0281     ElementListIter End =
0282         const_cast<SparseBitVector<ElementSize> *>(this)->Elements.end();
0283 
0284     if (Elements.empty()) {
0285       CurrElementIter = Begin;
0286       return CurrElementIter;
0287     }
0288 
0289     // Make sure our current iterator is valid.
0290     if (CurrElementIter == End)
0291       --CurrElementIter;
0292 
0293     // Search from our current iterator, either backwards or forwards,
0294     // depending on what element we are looking for.
0295     ElementListIter ElementIter = CurrElementIter;
0296     if (CurrElementIter->index() == ElementIndex) {
0297       return ElementIter;
0298     } else if (CurrElementIter->index() > ElementIndex) {
0299       while (ElementIter != Begin
0300              && ElementIter->index() > ElementIndex)
0301         --ElementIter;
0302     } else {
0303       while (ElementIter != End &&
0304              ElementIter->index() < ElementIndex)
0305         ++ElementIter;
0306     }
0307     CurrElementIter = ElementIter;
0308     return ElementIter;
0309   }
0310   ElementListConstIter FindLowerBoundConst(unsigned ElementIndex) const {
0311     return FindLowerBoundImpl(ElementIndex);
0312   }
0313   ElementListIter FindLowerBound(unsigned ElementIndex) {
0314     return FindLowerBoundImpl(ElementIndex);
0315   }
0316 
0317   // Iterator to walk set bits in the bitmap.  This iterator is a lot uglier
0318   // than it would be, in order to be efficient.
0319   class SparseBitVectorIterator {
0320   private:
0321     bool AtEnd;
0322 
0323     const SparseBitVector<ElementSize> *BitVector = nullptr;
0324 
0325     // Current element inside of bitmap.
0326     ElementListConstIter Iter;
0327 
0328     // Current bit number inside of our bitmap.
0329     unsigned BitNumber;
0330 
0331     // Current word number inside of our element.
0332     unsigned WordNumber;
0333 
0334     // Current bits from the element.
0335     typename SparseBitVectorElement<ElementSize>::BitWord Bits;
0336 
0337     // Move our iterator to the first non-zero bit in the bitmap.
0338     void AdvanceToFirstNonZero() {
0339       if (AtEnd)
0340         return;
0341       if (BitVector->Elements.empty()) {
0342         AtEnd = true;
0343         return;
0344       }
0345       Iter = BitVector->Elements.begin();
0346       BitNumber = Iter->index() * ElementSize;
0347       unsigned BitPos = Iter->find_first();
0348       BitNumber += BitPos;
0349       WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
0350       Bits = Iter->word(WordNumber);
0351       Bits >>= BitPos % BITWORD_SIZE;
0352     }
0353 
0354     // Move our iterator to the next non-zero bit.
0355     void AdvanceToNextNonZero() {
0356       if (AtEnd)
0357         return;
0358 
0359       while (Bits && !(Bits & 1)) {
0360         Bits >>= 1;
0361         BitNumber += 1;
0362       }
0363 
0364       // See if we ran out of Bits in this word.
0365       if (!Bits) {
0366         int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
0367         // If we ran out of set bits in this element, move to next element.
0368         if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
0369           ++Iter;
0370           WordNumber = 0;
0371 
0372           // We may run out of elements in the bitmap.
0373           if (Iter == BitVector->Elements.end()) {
0374             AtEnd = true;
0375             return;
0376           }
0377           // Set up for next non-zero word in bitmap.
0378           BitNumber = Iter->index() * ElementSize;
0379           NextSetBitNumber = Iter->find_first();
0380           BitNumber += NextSetBitNumber;
0381           WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
0382           Bits = Iter->word(WordNumber);
0383           Bits >>= NextSetBitNumber % BITWORD_SIZE;
0384         } else {
0385           WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
0386           Bits = Iter->word(WordNumber);
0387           Bits >>= NextSetBitNumber % BITWORD_SIZE;
0388           BitNumber = Iter->index() * ElementSize;
0389           BitNumber += NextSetBitNumber;
0390         }
0391       }
0392     }
0393 
0394   public:
0395     SparseBitVectorIterator() = default;
0396 
0397     SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
0398                             bool end = false):BitVector(RHS) {
0399       Iter = BitVector->Elements.begin();
0400       BitNumber = 0;
0401       Bits = 0;
0402       WordNumber = ~0;
0403       AtEnd = end;
0404       AdvanceToFirstNonZero();
0405     }
0406 
0407     // Preincrement.
0408     inline SparseBitVectorIterator& operator++() {
0409       ++BitNumber;
0410       Bits >>= 1;
0411       AdvanceToNextNonZero();
0412       return *this;
0413     }
0414 
0415     // Postincrement.
0416     inline SparseBitVectorIterator operator++(int) {
0417       SparseBitVectorIterator tmp = *this;
0418       ++*this;
0419       return tmp;
0420     }
0421 
0422     // Return the current set bit number.
0423     unsigned operator*() const {
0424       return BitNumber;
0425     }
0426 
0427     bool operator==(const SparseBitVectorIterator &RHS) const {
0428       // If they are both at the end, ignore the rest of the fields.
0429       if (AtEnd && RHS.AtEnd)
0430         return true;
0431       // Otherwise they are the same if they have the same bit number and
0432       // bitmap.
0433       return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
0434     }
0435 
0436     bool operator!=(const SparseBitVectorIterator &RHS) const {
0437       return !(*this == RHS);
0438     }
0439   };
0440 
0441 public:
0442   using iterator = SparseBitVectorIterator;
0443 
0444   SparseBitVector() : Elements(), CurrElementIter(Elements.begin()) {}
0445 
0446   SparseBitVector(const SparseBitVector &RHS)
0447       : Elements(RHS.Elements), CurrElementIter(Elements.begin()) {}
0448   SparseBitVector(SparseBitVector &&RHS)
0449       : Elements(std::move(RHS.Elements)), CurrElementIter(Elements.begin()) {}
0450 
0451   // Clear.
0452   void clear() {
0453     Elements.clear();
0454   }
0455 
0456   // Assignment
0457   SparseBitVector& operator=(const SparseBitVector& RHS) {
0458     if (this == &RHS)
0459       return *this;
0460 
0461     Elements = RHS.Elements;
0462     CurrElementIter = Elements.begin();
0463     return *this;
0464   }
0465   SparseBitVector &operator=(SparseBitVector &&RHS) {
0466     Elements = std::move(RHS.Elements);
0467     CurrElementIter = Elements.begin();
0468     return *this;
0469   }
0470 
0471   // Test, Reset, and Set a bit in the bitmap.
0472   bool test(unsigned Idx) const {
0473     if (Elements.empty())
0474       return false;
0475 
0476     unsigned ElementIndex = Idx / ElementSize;
0477     ElementListConstIter ElementIter = FindLowerBoundConst(ElementIndex);
0478 
0479     // If we can't find an element that is supposed to contain this bit, there
0480     // is nothing more to do.
0481     if (ElementIter == Elements.end() ||
0482         ElementIter->index() != ElementIndex)
0483       return false;
0484     return ElementIter->test(Idx % ElementSize);
0485   }
0486 
0487   void reset(unsigned Idx) {
0488     if (Elements.empty())
0489       return;
0490 
0491     unsigned ElementIndex = Idx / ElementSize;
0492     ElementListIter ElementIter = FindLowerBound(ElementIndex);
0493 
0494     // If we can't find an element that is supposed to contain this bit, there
0495     // is nothing more to do.
0496     if (ElementIter == Elements.end() ||
0497         ElementIter->index() != ElementIndex)
0498       return;
0499     ElementIter->reset(Idx % ElementSize);
0500 
0501     // When the element is zeroed out, delete it.
0502     if (ElementIter->empty()) {
0503       ++CurrElementIter;
0504       Elements.erase(ElementIter);
0505     }
0506   }
0507 
0508   void set(unsigned Idx) {
0509     unsigned ElementIndex = Idx / ElementSize;
0510     ElementListIter ElementIter;
0511     if (Elements.empty()) {
0512       ElementIter = Elements.emplace(Elements.end(), ElementIndex);
0513     } else {
0514       ElementIter = FindLowerBound(ElementIndex);
0515 
0516       if (ElementIter == Elements.end() ||
0517           ElementIter->index() != ElementIndex) {
0518         // We may have hit the beginning of our SparseBitVector, in which case,
0519         // we may need to insert right after this element, which requires moving
0520         // the current iterator forward one, because insert does insert before.
0521         if (ElementIter != Elements.end() &&
0522             ElementIter->index() < ElementIndex)
0523           ++ElementIter;
0524         ElementIter = Elements.emplace(ElementIter, ElementIndex);
0525       }
0526     }
0527     CurrElementIter = ElementIter;
0528 
0529     ElementIter->set(Idx % ElementSize);
0530   }
0531 
0532   bool test_and_set(unsigned Idx) {
0533     bool old = test(Idx);
0534     if (!old) {
0535       set(Idx);
0536       return true;
0537     }
0538     return false;
0539   }
0540 
0541   bool operator!=(const SparseBitVector &RHS) const {
0542     return !(*this == RHS);
0543   }
0544 
0545   bool operator==(const SparseBitVector &RHS) const {
0546     ElementListConstIter Iter1 = Elements.begin();
0547     ElementListConstIter Iter2 = RHS.Elements.begin();
0548 
0549     for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
0550          ++Iter1, ++Iter2) {
0551       if (*Iter1 != *Iter2)
0552         return false;
0553     }
0554     return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
0555   }
0556 
0557   // Union our bitmap with the RHS and return true if we changed.
0558   bool operator|=(const SparseBitVector &RHS) {
0559     if (this == &RHS)
0560       return false;
0561 
0562     bool changed = false;
0563     ElementListIter Iter1 = Elements.begin();
0564     ElementListConstIter Iter2 = RHS.Elements.begin();
0565 
0566     // If RHS is empty, we are done
0567     if (RHS.Elements.empty())
0568       return false;
0569 
0570     while (Iter2 != RHS.Elements.end()) {
0571       if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
0572         Elements.insert(Iter1, *Iter2);
0573         ++Iter2;
0574         changed = true;
0575       } else if (Iter1->index() == Iter2->index()) {
0576         changed |= Iter1->unionWith(*Iter2);
0577         ++Iter1;
0578         ++Iter2;
0579       } else {
0580         ++Iter1;
0581       }
0582     }
0583     CurrElementIter = Elements.begin();
0584     return changed;
0585   }
0586 
0587   // Intersect our bitmap with the RHS and return true if ours changed.
0588   bool operator&=(const SparseBitVector &RHS) {
0589     if (this == &RHS)
0590       return false;
0591 
0592     bool changed = false;
0593     ElementListIter Iter1 = Elements.begin();
0594     ElementListConstIter Iter2 = RHS.Elements.begin();
0595 
0596     // Check if both bitmaps are empty.
0597     if (Elements.empty() && RHS.Elements.empty())
0598       return false;
0599 
0600     // Loop through, intersecting as we go, erasing elements when necessary.
0601     while (Iter2 != RHS.Elements.end()) {
0602       if (Iter1 == Elements.end()) {
0603         CurrElementIter = Elements.begin();
0604         return changed;
0605       }
0606 
0607       if (Iter1->index() > Iter2->index()) {
0608         ++Iter2;
0609       } else if (Iter1->index() == Iter2->index()) {
0610         bool BecameZero;
0611         changed |= Iter1->intersectWith(*Iter2, BecameZero);
0612         if (BecameZero) {
0613           ElementListIter IterTmp = Iter1;
0614           ++Iter1;
0615           Elements.erase(IterTmp);
0616         } else {
0617           ++Iter1;
0618         }
0619         ++Iter2;
0620       } else {
0621         ElementListIter IterTmp = Iter1;
0622         ++Iter1;
0623         Elements.erase(IterTmp);
0624         changed = true;
0625       }
0626     }
0627     if (Iter1 != Elements.end()) {
0628       Elements.erase(Iter1, Elements.end());
0629       changed = true;
0630     }
0631     CurrElementIter = Elements.begin();
0632     return changed;
0633   }
0634 
0635   // Intersect our bitmap with the complement of the RHS and return true
0636   // if ours changed.
0637   bool intersectWithComplement(const SparseBitVector &RHS) {
0638     if (this == &RHS) {
0639       if (!empty()) {
0640         clear();
0641         return true;
0642       }
0643       return false;
0644     }
0645 
0646     bool changed = false;
0647     ElementListIter Iter1 = Elements.begin();
0648     ElementListConstIter Iter2 = RHS.Elements.begin();
0649 
0650     // If either our bitmap or RHS is empty, we are done
0651     if (Elements.empty() || RHS.Elements.empty())
0652       return false;
0653 
0654     // Loop through, intersecting as we go, erasing elements when necessary.
0655     while (Iter2 != RHS.Elements.end()) {
0656       if (Iter1 == Elements.end()) {
0657         CurrElementIter = Elements.begin();
0658         return changed;
0659       }
0660 
0661       if (Iter1->index() > Iter2->index()) {
0662         ++Iter2;
0663       } else if (Iter1->index() == Iter2->index()) {
0664         bool BecameZero;
0665         changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
0666         if (BecameZero) {
0667           ElementListIter IterTmp = Iter1;
0668           ++Iter1;
0669           Elements.erase(IterTmp);
0670         } else {
0671           ++Iter1;
0672         }
0673         ++Iter2;
0674       } else {
0675         ++Iter1;
0676       }
0677     }
0678     CurrElementIter = Elements.begin();
0679     return changed;
0680   }
0681 
0682   bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
0683     return intersectWithComplement(*RHS);
0684   }
0685 
0686   //  Three argument version of intersectWithComplement.
0687   //  Result of RHS1 & ~RHS2 is stored into this bitmap.
0688   void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
0689                                const SparseBitVector<ElementSize> &RHS2)
0690   {
0691     if (this == &RHS1) {
0692       intersectWithComplement(RHS2);
0693       return;
0694     } else if (this == &RHS2) {
0695       SparseBitVector RHS2Copy(RHS2);
0696       intersectWithComplement(RHS1, RHS2Copy);
0697       return;
0698     }
0699 
0700     Elements.clear();
0701     CurrElementIter = Elements.begin();
0702     ElementListConstIter Iter1 = RHS1.Elements.begin();
0703     ElementListConstIter Iter2 = RHS2.Elements.begin();
0704 
0705     // If RHS1 is empty, we are done
0706     // If RHS2 is empty, we still have to copy RHS1
0707     if (RHS1.Elements.empty())
0708       return;
0709 
0710     // Loop through, intersecting as we go, erasing elements when necessary.
0711     while (Iter2 != RHS2.Elements.end()) {
0712       if (Iter1 == RHS1.Elements.end())
0713         return;
0714 
0715       if (Iter1->index() > Iter2->index()) {
0716         ++Iter2;
0717       } else if (Iter1->index() == Iter2->index()) {
0718         bool BecameZero = false;
0719         Elements.emplace_back(Iter1->index());
0720         Elements.back().intersectWithComplement(*Iter1, *Iter2, BecameZero);
0721         if (BecameZero)
0722           Elements.pop_back();
0723         ++Iter1;
0724         ++Iter2;
0725       } else {
0726         Elements.push_back(*Iter1++);
0727       }
0728     }
0729 
0730     // copy the remaining elements
0731     std::copy(Iter1, RHS1.Elements.end(), std::back_inserter(Elements));
0732   }
0733 
0734   void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
0735                                const SparseBitVector<ElementSize> *RHS2) {
0736     intersectWithComplement(*RHS1, *RHS2);
0737   }
0738 
0739   bool intersects(const SparseBitVector<ElementSize> *RHS) const {
0740     return intersects(*RHS);
0741   }
0742 
0743   // Return true if we share any bits in common with RHS
0744   bool intersects(const SparseBitVector<ElementSize> &RHS) const {
0745     ElementListConstIter Iter1 = Elements.begin();
0746     ElementListConstIter Iter2 = RHS.Elements.begin();
0747 
0748     // Check if both bitmaps are empty.
0749     if (Elements.empty() && RHS.Elements.empty())
0750       return false;
0751 
0752     // Loop through, intersecting stopping when we hit bits in common.
0753     while (Iter2 != RHS.Elements.end()) {
0754       if (Iter1 == Elements.end())
0755         return false;
0756 
0757       if (Iter1->index() > Iter2->index()) {
0758         ++Iter2;
0759       } else if (Iter1->index() == Iter2->index()) {
0760         if (Iter1->intersects(*Iter2))
0761           return true;
0762         ++Iter1;
0763         ++Iter2;
0764       } else {
0765         ++Iter1;
0766       }
0767     }
0768     return false;
0769   }
0770 
0771   // Return true iff all bits set in this SparseBitVector are
0772   // also set in RHS.
0773   bool contains(const SparseBitVector<ElementSize> &RHS) const {
0774     SparseBitVector<ElementSize> Result(*this);
0775     Result &= RHS;
0776     return (Result == RHS);
0777   }
0778 
0779   // Return the first set bit in the bitmap.  Return -1 if no bits are set.
0780   int find_first() const {
0781     if (Elements.empty())
0782       return -1;
0783     const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
0784     return (First.index() * ElementSize) + First.find_first();
0785   }
0786 
0787   // Return the last set bit in the bitmap.  Return -1 if no bits are set.
0788   int find_last() const {
0789     if (Elements.empty())
0790       return -1;
0791     const SparseBitVectorElement<ElementSize> &Last = *(Elements.rbegin());
0792     return (Last.index() * ElementSize) + Last.find_last();
0793   }
0794 
0795   // Return true if the SparseBitVector is empty
0796   bool empty() const {
0797     return Elements.empty();
0798   }
0799 
0800   unsigned count() const {
0801     unsigned BitCount = 0;
0802     for (ElementListConstIter Iter = Elements.begin();
0803          Iter != Elements.end();
0804          ++Iter)
0805       BitCount += Iter->count();
0806 
0807     return BitCount;
0808   }
0809 
0810   iterator begin() const {
0811     return iterator(this);
0812   }
0813 
0814   iterator end() const {
0815     return iterator(this, true);
0816   }
0817 };
0818 
0819 // Convenience functions to allow Or and And without dereferencing in the user
0820 // code.
0821 
0822 template <unsigned ElementSize>
0823 inline bool operator |=(SparseBitVector<ElementSize> &LHS,
0824                         const SparseBitVector<ElementSize> *RHS) {
0825   return LHS |= *RHS;
0826 }
0827 
0828 template <unsigned ElementSize>
0829 inline bool operator |=(SparseBitVector<ElementSize> *LHS,
0830                         const SparseBitVector<ElementSize> &RHS) {
0831   return LHS->operator|=(RHS);
0832 }
0833 
0834 template <unsigned ElementSize>
0835 inline bool operator &=(SparseBitVector<ElementSize> *LHS,
0836                         const SparseBitVector<ElementSize> &RHS) {
0837   return LHS->operator&=(RHS);
0838 }
0839 
0840 template <unsigned ElementSize>
0841 inline bool operator &=(SparseBitVector<ElementSize> &LHS,
0842                         const SparseBitVector<ElementSize> *RHS) {
0843   return LHS &= *RHS;
0844 }
0845 
0846 // Convenience functions for infix union, intersection, difference operators.
0847 
0848 template <unsigned ElementSize>
0849 inline SparseBitVector<ElementSize>
0850 operator|(const SparseBitVector<ElementSize> &LHS,
0851           const SparseBitVector<ElementSize> &RHS) {
0852   SparseBitVector<ElementSize> Result(LHS);
0853   Result |= RHS;
0854   return Result;
0855 }
0856 
0857 template <unsigned ElementSize>
0858 inline SparseBitVector<ElementSize>
0859 operator&(const SparseBitVector<ElementSize> &LHS,
0860           const SparseBitVector<ElementSize> &RHS) {
0861   SparseBitVector<ElementSize> Result(LHS);
0862   Result &= RHS;
0863   return Result;
0864 }
0865 
0866 template <unsigned ElementSize>
0867 inline SparseBitVector<ElementSize>
0868 operator-(const SparseBitVector<ElementSize> &LHS,
0869           const SparseBitVector<ElementSize> &RHS) {
0870   SparseBitVector<ElementSize> Result;
0871   Result.intersectWithComplement(LHS, RHS);
0872   return Result;
0873 }
0874 
0875 // Dump a SparseBitVector to a stream
0876 template <unsigned ElementSize>
0877 void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
0878   out << "[";
0879 
0880   typename SparseBitVector<ElementSize>::iterator bi = LHS.begin(),
0881     be = LHS.end();
0882   if (bi != be) {
0883     out << *bi;
0884     for (++bi; bi != be; ++bi) {
0885       out << " " << *bi;
0886     }
0887   }
0888   out << "]\n";
0889 }
0890 
0891 } // end namespace llvm
0892 
0893 #endif // LLVM_ADT_SPARSEBITVECTOR_H