xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/SparseBitVector.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1 //===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file defines the SparseBitVector class.  See the doxygen comment for
11 /// SparseBitVector for more details on the algorithm used.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_ADT_SPARSEBITVECTOR_H
16 #define LLVM_ADT_SPARSEBITVECTOR_H
17 
18 #include "llvm/ADT/bit.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <cassert>
22 #include <climits>
23 #include <cstring>
24 #include <iterator>
25 #include <list>
26 
27 namespace llvm {
28 
29 /// SparseBitVector is an implementation of a bitvector that is sparse by only
30 /// storing the elements that have non-zero bits set.  In order to make this
31 /// fast for the most common cases, SparseBitVector is implemented as a linked
32 /// list of SparseBitVectorElements.  We maintain a pointer to the last
33 /// SparseBitVectorElement accessed (in the form of a list iterator), in order
34 /// to make multiple in-order test/set constant time after the first one is
35 /// executed.  Note that using vectors to store SparseBitVectorElement's does
36 /// not work out very well because it causes insertion in the middle to take
37 /// enormous amounts of time with a large amount of bits.  Other structures that
38 /// have better worst cases for insertion in the middle (various balanced trees,
39 /// etc) do not perform as well in practice as a linked list with this iterator
40 /// kept up to date.  They are also significantly more memory intensive.
41 
42 template <unsigned ElementSize = 128> struct SparseBitVectorElement {
43 public:
44   using BitWord = unsigned long;
45   using size_type = unsigned;
46   enum {
47     BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
48     BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
49     BITS_PER_ELEMENT = ElementSize
50   };
51 
52 private:
53   // Index of Element in terms of where first bit starts.
54   unsigned ElementIndex;
55   BitWord Bits[BITWORDS_PER_ELEMENT];
56 
57   SparseBitVectorElement() {
58     ElementIndex = ~0U;
59     memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
60   }
61 
62 public:
63   explicit SparseBitVectorElement(unsigned Idx) {
64     ElementIndex = Idx;
65     memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
66   }
67 
68   // Comparison.
69   bool operator==(const SparseBitVectorElement &RHS) const {
70     if (ElementIndex != RHS.ElementIndex)
71       return false;
72     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
73       if (Bits[i] != RHS.Bits[i])
74         return false;
75     return true;
76   }
77 
78   bool operator!=(const SparseBitVectorElement &RHS) const {
79     return !(*this == RHS);
80   }
81 
82   // Return the bits that make up word Idx in our element.
83   BitWord word(unsigned Idx) const {
84     assert(Idx < BITWORDS_PER_ELEMENT);
85     return Bits[Idx];
86   }
87 
88   unsigned index() const {
89     return ElementIndex;
90   }
91 
92   bool empty() const {
93     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
94       if (Bits[i])
95         return false;
96     return true;
97   }
98 
99   void set(unsigned Idx) {
100     Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
101   }
102 
103   bool test_and_set(unsigned Idx) {
104     bool old = test(Idx);
105     if (!old) {
106       set(Idx);
107       return true;
108     }
109     return false;
110   }
111 
112   void reset(unsigned Idx) {
113     Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
114   }
115 
116   bool test(unsigned Idx) const {
117     return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
118   }
119 
120   size_type count() const {
121     unsigned NumBits = 0;
122     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
123       NumBits += llvm::popcount(Bits[i]);
124     return NumBits;
125   }
126 
127   /// find_first - Returns the index of the first set bit.
128   int find_first() const {
129     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
130       if (Bits[i] != 0)
131         return i * BITWORD_SIZE + llvm::countr_zero(Bits[i]);
132     llvm_unreachable("Illegal empty element");
133   }
134 
135   /// find_last - Returns the index of the last set bit.
136   int find_last() const {
137     for (unsigned I = 0; I < BITWORDS_PER_ELEMENT; ++I) {
138       unsigned Idx = BITWORDS_PER_ELEMENT - I - 1;
139       if (Bits[Idx] != 0)
140         return Idx * BITWORD_SIZE + BITWORD_SIZE -
141                llvm::countl_zero(Bits[Idx]) - 1;
142     }
143     llvm_unreachable("Illegal empty element");
144   }
145 
146   /// find_next - Returns the index of the next set bit starting from the
147   /// "Curr" bit. Returns -1 if the next set bit is not found.
148   int find_next(unsigned Curr) const {
149     if (Curr >= BITS_PER_ELEMENT)
150       return -1;
151 
152     unsigned WordPos = Curr / BITWORD_SIZE;
153     unsigned BitPos = Curr % BITWORD_SIZE;
154     BitWord Copy = Bits[WordPos];
155     assert(WordPos <= BITWORDS_PER_ELEMENT
156            && "Word Position outside of element");
157 
158     // Mask off previous bits.
159     Copy &= ~0UL << BitPos;
160 
161     if (Copy != 0)
162       return WordPos * BITWORD_SIZE + llvm::countr_zero(Copy);
163 
164     // Check subsequent words.
165     for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
166       if (Bits[i] != 0)
167         return i * BITWORD_SIZE + llvm::countr_zero(Bits[i]);
168     return -1;
169   }
170 
171   // Union this element with RHS and return true if this one changed.
172   bool unionWith(const SparseBitVectorElement &RHS) {
173     bool changed = false;
174     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
175       BitWord old = changed ? 0 : Bits[i];
176 
177       Bits[i] |= RHS.Bits[i];
178       if (!changed && old != Bits[i])
179         changed = true;
180     }
181     return changed;
182   }
183 
184   // Return true if we have any bits in common with RHS
185   bool intersects(const SparseBitVectorElement &RHS) const {
186     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
187       if (RHS.Bits[i] & Bits[i])
188         return true;
189     }
190     return false;
191   }
192 
193   // Intersect this Element with RHS and return true if this one changed.
194   // BecameZero is set to true if this element became all-zero bits.
195   bool intersectWith(const SparseBitVectorElement &RHS,
196                      bool &BecameZero) {
197     bool changed = false;
198     bool allzero = true;
199 
200     BecameZero = false;
201     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
202       BitWord old = changed ? 0 : Bits[i];
203 
204       Bits[i] &= RHS.Bits[i];
205       if (Bits[i] != 0)
206         allzero = false;
207 
208       if (!changed && old != Bits[i])
209         changed = true;
210     }
211     BecameZero = allzero;
212     return changed;
213   }
214 
215   // Intersect this Element with the complement of RHS and return true if this
216   // one changed.  BecameZero is set to true if this element became all-zero
217   // bits.
218   bool intersectWithComplement(const SparseBitVectorElement &RHS,
219                                bool &BecameZero) {
220     bool changed = false;
221     bool allzero = true;
222 
223     BecameZero = false;
224     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
225       BitWord old = changed ? 0 : Bits[i];
226 
227       Bits[i] &= ~RHS.Bits[i];
228       if (Bits[i] != 0)
229         allzero = false;
230 
231       if (!changed && old != Bits[i])
232         changed = true;
233     }
234     BecameZero = allzero;
235     return changed;
236   }
237 
238   // Three argument version of intersectWithComplement that intersects
239   // RHS1 & ~RHS2 into this element
240   void intersectWithComplement(const SparseBitVectorElement &RHS1,
241                                const SparseBitVectorElement &RHS2,
242                                bool &BecameZero) {
243     bool allzero = true;
244 
245     BecameZero = false;
246     for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
247       Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
248       if (Bits[i] != 0)
249         allzero = false;
250     }
251     BecameZero = allzero;
252   }
253 };
254 
255 template <unsigned ElementSize = 128>
256 class SparseBitVector {
257   using ElementList = std::list<SparseBitVectorElement<ElementSize>>;
258   using ElementListIter = typename ElementList::iterator;
259   using ElementListConstIter = typename ElementList::const_iterator;
260   enum {
261     BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
262   };
263 
264   ElementList Elements;
265   // Pointer to our current Element. This has no visible effect on the external
266   // state of a SparseBitVector, it's just used to improve performance in the
267   // common case of testing/modifying bits with similar indices.
268   mutable ElementListIter CurrElementIter;
269 
270   // This is like std::lower_bound, except we do linear searching from the
271   // current position.
272   ElementListIter FindLowerBoundImpl(unsigned ElementIndex) const {
273 
274     // We cache a non-const iterator so we're forced to resort to const_cast to
275     // get the begin/end in the case where 'this' is const. To avoid duplication
276     // of code with the only difference being whether the const cast is present
277     // 'this' is always const in this particular function and we sort out the
278     // difference in FindLowerBound and FindLowerBoundConst.
279     ElementListIter Begin =
280         const_cast<SparseBitVector<ElementSize> *>(this)->Elements.begin();
281     ElementListIter End =
282         const_cast<SparseBitVector<ElementSize> *>(this)->Elements.end();
283 
284     if (Elements.empty()) {
285       CurrElementIter = Begin;
286       return CurrElementIter;
287     }
288 
289     // Make sure our current iterator is valid.
290     if (CurrElementIter == End)
291       --CurrElementIter;
292 
293     // Search from our current iterator, either backwards or forwards,
294     // depending on what element we are looking for.
295     ElementListIter ElementIter = CurrElementIter;
296     if (CurrElementIter->index() == ElementIndex) {
297       return ElementIter;
298     } else if (CurrElementIter->index() > ElementIndex) {
299       while (ElementIter != Begin
300              && ElementIter->index() > ElementIndex)
301         --ElementIter;
302     } else {
303       while (ElementIter != End &&
304              ElementIter->index() < ElementIndex)
305         ++ElementIter;
306     }
307     CurrElementIter = ElementIter;
308     return ElementIter;
309   }
310   ElementListConstIter FindLowerBoundConst(unsigned ElementIndex) const {
311     return FindLowerBoundImpl(ElementIndex);
312   }
313   ElementListIter FindLowerBound(unsigned ElementIndex) {
314     return FindLowerBoundImpl(ElementIndex);
315   }
316 
317   // Iterator to walk set bits in the bitmap.  This iterator is a lot uglier
318   // than it would be, in order to be efficient.
319   class SparseBitVectorIterator {
320   private:
321     bool AtEnd;
322 
323     const SparseBitVector<ElementSize> *BitVector = nullptr;
324 
325     // Current element inside of bitmap.
326     ElementListConstIter Iter;
327 
328     // Current bit number inside of our bitmap.
329     unsigned BitNumber;
330 
331     // Current word number inside of our element.
332     unsigned WordNumber;
333 
334     // Current bits from the element.
335     typename SparseBitVectorElement<ElementSize>::BitWord Bits;
336 
337     // Move our iterator to the first non-zero bit in the bitmap.
338     void AdvanceToFirstNonZero() {
339       if (AtEnd)
340         return;
341       if (BitVector->Elements.empty()) {
342         AtEnd = true;
343         return;
344       }
345       Iter = BitVector->Elements.begin();
346       BitNumber = Iter->index() * ElementSize;
347       unsigned BitPos = Iter->find_first();
348       BitNumber += BitPos;
349       WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
350       Bits = Iter->word(WordNumber);
351       Bits >>= BitPos % BITWORD_SIZE;
352     }
353 
354     // Move our iterator to the next non-zero bit.
355     void AdvanceToNextNonZero() {
356       if (AtEnd)
357         return;
358 
359       while (Bits && !(Bits & 1)) {
360         Bits >>= 1;
361         BitNumber += 1;
362       }
363 
364       // See if we ran out of Bits in this word.
365       if (!Bits) {
366         int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
367         // If we ran out of set bits in this element, move to next element.
368         if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
369           ++Iter;
370           WordNumber = 0;
371 
372           // We may run out of elements in the bitmap.
373           if (Iter == BitVector->Elements.end()) {
374             AtEnd = true;
375             return;
376           }
377           // Set up for next non-zero word in bitmap.
378           BitNumber = Iter->index() * ElementSize;
379           NextSetBitNumber = Iter->find_first();
380           BitNumber += NextSetBitNumber;
381           WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
382           Bits = Iter->word(WordNumber);
383           Bits >>= NextSetBitNumber % BITWORD_SIZE;
384         } else {
385           WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
386           Bits = Iter->word(WordNumber);
387           Bits >>= NextSetBitNumber % BITWORD_SIZE;
388           BitNumber = Iter->index() * ElementSize;
389           BitNumber += NextSetBitNumber;
390         }
391       }
392     }
393 
394   public:
395     SparseBitVectorIterator() = default;
396 
397     SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
398                             bool end = false):BitVector(RHS) {
399       Iter = BitVector->Elements.begin();
400       BitNumber = 0;
401       Bits = 0;
402       WordNumber = ~0;
403       AtEnd = end;
404       AdvanceToFirstNonZero();
405     }
406 
407     // Preincrement.
408     inline SparseBitVectorIterator& operator++() {
409       ++BitNumber;
410       Bits >>= 1;
411       AdvanceToNextNonZero();
412       return *this;
413     }
414 
415     // Postincrement.
416     inline SparseBitVectorIterator operator++(int) {
417       SparseBitVectorIterator tmp = *this;
418       ++*this;
419       return tmp;
420     }
421 
422     // Return the current set bit number.
423     unsigned operator*() const {
424       return BitNumber;
425     }
426 
427     bool operator==(const SparseBitVectorIterator &RHS) const {
428       // If they are both at the end, ignore the rest of the fields.
429       if (AtEnd && RHS.AtEnd)
430         return true;
431       // Otherwise they are the same if they have the same bit number and
432       // bitmap.
433       return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
434     }
435 
436     bool operator!=(const SparseBitVectorIterator &RHS) const {
437       return !(*this == RHS);
438     }
439   };
440 
441 public:
442   using iterator = SparseBitVectorIterator;
443 
444   SparseBitVector() : Elements(), CurrElementIter(Elements.begin()) {}
445 
446   SparseBitVector(const SparseBitVector &RHS)
447       : Elements(RHS.Elements), CurrElementIter(Elements.begin()) {}
448   SparseBitVector(SparseBitVector &&RHS)
449       : Elements(std::move(RHS.Elements)), CurrElementIter(Elements.begin()) {}
450 
451   // Clear.
452   void clear() {
453     Elements.clear();
454   }
455 
456   // Assignment
457   SparseBitVector& operator=(const SparseBitVector& RHS) {
458     if (this == &RHS)
459       return *this;
460 
461     Elements = RHS.Elements;
462     CurrElementIter = Elements.begin();
463     return *this;
464   }
465   SparseBitVector &operator=(SparseBitVector &&RHS) {
466     Elements = std::move(RHS.Elements);
467     CurrElementIter = Elements.begin();
468     return *this;
469   }
470 
471   // Test, Reset, and Set a bit in the bitmap.
472   bool test(unsigned Idx) const {
473     if (Elements.empty())
474       return false;
475 
476     unsigned ElementIndex = Idx / ElementSize;
477     ElementListConstIter ElementIter = FindLowerBoundConst(ElementIndex);
478 
479     // If we can't find an element that is supposed to contain this bit, there
480     // is nothing more to do.
481     if (ElementIter == Elements.end() ||
482         ElementIter->index() != ElementIndex)
483       return false;
484     return ElementIter->test(Idx % ElementSize);
485   }
486 
487   void reset(unsigned Idx) {
488     if (Elements.empty())
489       return;
490 
491     unsigned ElementIndex = Idx / ElementSize;
492     ElementListIter ElementIter = FindLowerBound(ElementIndex);
493 
494     // If we can't find an element that is supposed to contain this bit, there
495     // is nothing more to do.
496     if (ElementIter == Elements.end() ||
497         ElementIter->index() != ElementIndex)
498       return;
499     ElementIter->reset(Idx % ElementSize);
500 
501     // When the element is zeroed out, delete it.
502     if (ElementIter->empty()) {
503       ++CurrElementIter;
504       Elements.erase(ElementIter);
505     }
506   }
507 
508   void set(unsigned Idx) {
509     unsigned ElementIndex = Idx / ElementSize;
510     ElementListIter ElementIter;
511     if (Elements.empty()) {
512       ElementIter = Elements.emplace(Elements.end(), ElementIndex);
513     } else {
514       ElementIter = FindLowerBound(ElementIndex);
515 
516       if (ElementIter == Elements.end() ||
517           ElementIter->index() != ElementIndex) {
518         // We may have hit the beginning of our SparseBitVector, in which case,
519         // we may need to insert right after this element, which requires moving
520         // the current iterator forward one, because insert does insert before.
521         if (ElementIter != Elements.end() &&
522             ElementIter->index() < ElementIndex)
523           ++ElementIter;
524         ElementIter = Elements.emplace(ElementIter, ElementIndex);
525       }
526     }
527     CurrElementIter = ElementIter;
528 
529     ElementIter->set(Idx % ElementSize);
530   }
531 
532   bool test_and_set(unsigned Idx) {
533     bool old = test(Idx);
534     if (!old) {
535       set(Idx);
536       return true;
537     }
538     return false;
539   }
540 
541   bool operator!=(const SparseBitVector &RHS) const {
542     return !(*this == RHS);
543   }
544 
545   bool operator==(const SparseBitVector &RHS) const {
546     ElementListConstIter Iter1 = Elements.begin();
547     ElementListConstIter Iter2 = RHS.Elements.begin();
548 
549     for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
550          ++Iter1, ++Iter2) {
551       if (*Iter1 != *Iter2)
552         return false;
553     }
554     return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
555   }
556 
557   // Union our bitmap with the RHS and return true if we changed.
558   bool operator|=(const SparseBitVector &RHS) {
559     if (this == &RHS)
560       return false;
561 
562     bool changed = false;
563     ElementListIter Iter1 = Elements.begin();
564     ElementListConstIter Iter2 = RHS.Elements.begin();
565 
566     // If RHS is empty, we are done
567     if (RHS.Elements.empty())
568       return false;
569 
570     while (Iter2 != RHS.Elements.end()) {
571       if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
572         Elements.insert(Iter1, *Iter2);
573         ++Iter2;
574         changed = true;
575       } else if (Iter1->index() == Iter2->index()) {
576         changed |= Iter1->unionWith(*Iter2);
577         ++Iter1;
578         ++Iter2;
579       } else {
580         ++Iter1;
581       }
582     }
583     CurrElementIter = Elements.begin();
584     return changed;
585   }
586 
587   // Intersect our bitmap with the RHS and return true if ours changed.
588   bool operator&=(const SparseBitVector &RHS) {
589     if (this == &RHS)
590       return false;
591 
592     bool changed = false;
593     ElementListIter Iter1 = Elements.begin();
594     ElementListConstIter Iter2 = RHS.Elements.begin();
595 
596     // Check if both bitmaps are empty.
597     if (Elements.empty() && RHS.Elements.empty())
598       return false;
599 
600     // Loop through, intersecting as we go, erasing elements when necessary.
601     while (Iter2 != RHS.Elements.end()) {
602       if (Iter1 == Elements.end()) {
603         CurrElementIter = Elements.begin();
604         return changed;
605       }
606 
607       if (Iter1->index() > Iter2->index()) {
608         ++Iter2;
609       } else if (Iter1->index() == Iter2->index()) {
610         bool BecameZero;
611         changed |= Iter1->intersectWith(*Iter2, BecameZero);
612         if (BecameZero) {
613           ElementListIter IterTmp = Iter1;
614           ++Iter1;
615           Elements.erase(IterTmp);
616         } else {
617           ++Iter1;
618         }
619         ++Iter2;
620       } else {
621         ElementListIter IterTmp = Iter1;
622         ++Iter1;
623         Elements.erase(IterTmp);
624         changed = true;
625       }
626     }
627     if (Iter1 != Elements.end()) {
628       Elements.erase(Iter1, Elements.end());
629       changed = true;
630     }
631     CurrElementIter = Elements.begin();
632     return changed;
633   }
634 
635   // Intersect our bitmap with the complement of the RHS and return true
636   // if ours changed.
637   bool intersectWithComplement(const SparseBitVector &RHS) {
638     if (this == &RHS) {
639       if (!empty()) {
640         clear();
641         return true;
642       }
643       return false;
644     }
645 
646     bool changed = false;
647     ElementListIter Iter1 = Elements.begin();
648     ElementListConstIter Iter2 = RHS.Elements.begin();
649 
650     // If either our bitmap or RHS is empty, we are done
651     if (Elements.empty() || RHS.Elements.empty())
652       return false;
653 
654     // Loop through, intersecting as we go, erasing elements when necessary.
655     while (Iter2 != RHS.Elements.end()) {
656       if (Iter1 == Elements.end()) {
657         CurrElementIter = Elements.begin();
658         return changed;
659       }
660 
661       if (Iter1->index() > Iter2->index()) {
662         ++Iter2;
663       } else if (Iter1->index() == Iter2->index()) {
664         bool BecameZero;
665         changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
666         if (BecameZero) {
667           ElementListIter IterTmp = Iter1;
668           ++Iter1;
669           Elements.erase(IterTmp);
670         } else {
671           ++Iter1;
672         }
673         ++Iter2;
674       } else {
675         ++Iter1;
676       }
677     }
678     CurrElementIter = Elements.begin();
679     return changed;
680   }
681 
682   bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
683     return intersectWithComplement(*RHS);
684   }
685 
686   //  Three argument version of intersectWithComplement.
687   //  Result of RHS1 & ~RHS2 is stored into this bitmap.
688   void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
689                                const SparseBitVector<ElementSize> &RHS2)
690   {
691     if (this == &RHS1) {
692       intersectWithComplement(RHS2);
693       return;
694     } else if (this == &RHS2) {
695       SparseBitVector RHS2Copy(RHS2);
696       intersectWithComplement(RHS1, RHS2Copy);
697       return;
698     }
699 
700     Elements.clear();
701     CurrElementIter = Elements.begin();
702     ElementListConstIter Iter1 = RHS1.Elements.begin();
703     ElementListConstIter Iter2 = RHS2.Elements.begin();
704 
705     // If RHS1 is empty, we are done
706     // If RHS2 is empty, we still have to copy RHS1
707     if (RHS1.Elements.empty())
708       return;
709 
710     // Loop through, intersecting as we go, erasing elements when necessary.
711     while (Iter2 != RHS2.Elements.end()) {
712       if (Iter1 == RHS1.Elements.end())
713         return;
714 
715       if (Iter1->index() > Iter2->index()) {
716         ++Iter2;
717       } else if (Iter1->index() == Iter2->index()) {
718         bool BecameZero = false;
719         Elements.emplace_back(Iter1->index());
720         Elements.back().intersectWithComplement(*Iter1, *Iter2, BecameZero);
721         if (BecameZero)
722           Elements.pop_back();
723         ++Iter1;
724         ++Iter2;
725       } else {
726         Elements.push_back(*Iter1++);
727       }
728     }
729 
730     // copy the remaining elements
731     std::copy(Iter1, RHS1.Elements.end(), std::back_inserter(Elements));
732   }
733 
734   void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
735                                const SparseBitVector<ElementSize> *RHS2) {
736     intersectWithComplement(*RHS1, *RHS2);
737   }
738 
739   bool intersects(const SparseBitVector<ElementSize> *RHS) const {
740     return intersects(*RHS);
741   }
742 
743   // Return true if we share any bits in common with RHS
744   bool intersects(const SparseBitVector<ElementSize> &RHS) const {
745     ElementListConstIter Iter1 = Elements.begin();
746     ElementListConstIter Iter2 = RHS.Elements.begin();
747 
748     // Check if both bitmaps are empty.
749     if (Elements.empty() && RHS.Elements.empty())
750       return false;
751 
752     // Loop through, intersecting stopping when we hit bits in common.
753     while (Iter2 != RHS.Elements.end()) {
754       if (Iter1 == Elements.end())
755         return false;
756 
757       if (Iter1->index() > Iter2->index()) {
758         ++Iter2;
759       } else if (Iter1->index() == Iter2->index()) {
760         if (Iter1->intersects(*Iter2))
761           return true;
762         ++Iter1;
763         ++Iter2;
764       } else {
765         ++Iter1;
766       }
767     }
768     return false;
769   }
770 
771   // Return true iff all bits set in this SparseBitVector are
772   // also set in RHS.
773   bool contains(const SparseBitVector<ElementSize> &RHS) const {
774     SparseBitVector<ElementSize> Result(*this);
775     Result &= RHS;
776     return (Result == RHS);
777   }
778 
779   // Return the first set bit in the bitmap.  Return -1 if no bits are set.
780   int find_first() const {
781     if (Elements.empty())
782       return -1;
783     const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
784     return (First.index() * ElementSize) + First.find_first();
785   }
786 
787   // Return the last set bit in the bitmap.  Return -1 if no bits are set.
788   int find_last() const {
789     if (Elements.empty())
790       return -1;
791     const SparseBitVectorElement<ElementSize> &Last = *(Elements.rbegin());
792     return (Last.index() * ElementSize) + Last.find_last();
793   }
794 
795   // Return true if the SparseBitVector is empty
796   bool empty() const {
797     return Elements.empty();
798   }
799 
800   unsigned count() const {
801     unsigned BitCount = 0;
802     for (ElementListConstIter Iter = Elements.begin();
803          Iter != Elements.end();
804          ++Iter)
805       BitCount += Iter->count();
806 
807     return BitCount;
808   }
809 
810   iterator begin() const {
811     return iterator(this);
812   }
813 
814   iterator end() const {
815     return iterator(this, true);
816   }
817 };
818 
819 // Convenience functions to allow Or and And without dereferencing in the user
820 // code.
821 
822 template <unsigned ElementSize>
823 inline bool operator |=(SparseBitVector<ElementSize> &LHS,
824                         const SparseBitVector<ElementSize> *RHS) {
825   return LHS |= *RHS;
826 }
827 
828 template <unsigned ElementSize>
829 inline bool operator |=(SparseBitVector<ElementSize> *LHS,
830                         const SparseBitVector<ElementSize> &RHS) {
831   return LHS->operator|=(RHS);
832 }
833 
834 template <unsigned ElementSize>
835 inline bool operator &=(SparseBitVector<ElementSize> *LHS,
836                         const SparseBitVector<ElementSize> &RHS) {
837   return LHS->operator&=(RHS);
838 }
839 
840 template <unsigned ElementSize>
841 inline bool operator &=(SparseBitVector<ElementSize> &LHS,
842                         const SparseBitVector<ElementSize> *RHS) {
843   return LHS &= *RHS;
844 }
845 
846 // Convenience functions for infix union, intersection, difference operators.
847 
848 template <unsigned ElementSize>
849 inline SparseBitVector<ElementSize>
850 operator|(const SparseBitVector<ElementSize> &LHS,
851           const SparseBitVector<ElementSize> &RHS) {
852   SparseBitVector<ElementSize> Result(LHS);
853   Result |= RHS;
854   return Result;
855 }
856 
857 template <unsigned ElementSize>
858 inline SparseBitVector<ElementSize>
859 operator&(const SparseBitVector<ElementSize> &LHS,
860           const SparseBitVector<ElementSize> &RHS) {
861   SparseBitVector<ElementSize> Result(LHS);
862   Result &= RHS;
863   return Result;
864 }
865 
866 template <unsigned ElementSize>
867 inline SparseBitVector<ElementSize>
868 operator-(const SparseBitVector<ElementSize> &LHS,
869           const SparseBitVector<ElementSize> &RHS) {
870   SparseBitVector<ElementSize> Result;
871   Result.intersectWithComplement(LHS, RHS);
872   return Result;
873 }
874 
875 // Dump a SparseBitVector to a stream
876 template <unsigned ElementSize>
877 void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
878   out << "[";
879 
880   typename SparseBitVector<ElementSize>::iterator bi = LHS.begin(),
881     be = LHS.end();
882   if (bi != be) {
883     out << *bi;
884     for (++bi; bi != be; ++bi) {
885       out << " " << *bi;
886     }
887   }
888   out << "]\n";
889 }
890 
891 } // end namespace llvm
892 
893 #endif // LLVM_ADT_SPARSEBITVECTOR_H
894