SparseBitVector.h 26 KB

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