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