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