SmallBitVector.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. //===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- 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 implements the SmallBitVector class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ADT_SMALLBITVECTOR_H
  14. #define LLVM_ADT_SMALLBITVECTOR_H
  15. #include "llvm/ADT/BitVector.h"
  16. #include "llvm/Support/Compiler.h"
  17. #include "llvm/Support/MathExtras.h"
  18. #include <cassert>
  19. namespace llvm {
  20. /// SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array),
  21. /// optimized for the case when the array is small. It contains one
  22. /// pointer-sized field, which is directly used as a plain collection of bits
  23. /// when possible, or as a pointer to a larger heap-allocated array when
  24. /// necessary. This allows normal "small" cases to be fast without losing
  25. /// generality for large inputs.
  26. ///
  27. class SmallBitVector {
  28. // TODO: In "large" mode, a pointer to a BitVector is used, leading to an
  29. // unnecessary level of indirection. It would be more efficient to use a
  30. // pointer to memory containing size, allocation size, and the array of bits.
  31. uintptr_t X;
  32. enum {
  33. // The number of bits in this class.
  34. NumBaseBits = sizeof(uintptr_t) * CHAR_BIT,
  35. // One bit is used to discriminate between small and large mode. The
  36. // remaining bits are used for the small-mode representation.
  37. SmallNumRawBits = NumBaseBits - 1,
  38. // A few more bits are used to store the size of the bit set in small mode.
  39. // Theoretically this is a ceil-log2. These bits are encoded in the most
  40. // significant bits of the raw bits.
  41. SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
  42. NumBaseBits == 64 ? 6 :
  43. SmallNumRawBits),
  44. // The remaining bits are used to store the actual set in small mode.
  45. SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
  46. };
  47. static_assert(NumBaseBits == 64 || NumBaseBits == 32,
  48. "Unsupported word size");
  49. public:
  50. typedef unsigned size_type;
  51. // Encapsulation of a single bit.
  52. class reference {
  53. SmallBitVector &TheVector;
  54. unsigned BitPos;
  55. public:
  56. reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
  57. reference(const reference&) = default;
  58. reference& operator=(reference t) {
  59. *this = bool(t);
  60. return *this;
  61. }
  62. reference& operator=(bool t) {
  63. if (t)
  64. TheVector.set(BitPos);
  65. else
  66. TheVector.reset(BitPos);
  67. return *this;
  68. }
  69. operator bool() const {
  70. return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos);
  71. }
  72. };
  73. private:
  74. bool isSmall() const {
  75. return X & uintptr_t(1);
  76. }
  77. BitVector *getPointer() const {
  78. assert(!isSmall());
  79. return reinterpret_cast<BitVector *>(X);
  80. }
  81. void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) {
  82. X = 1;
  83. setSmallSize(NewSize);
  84. setSmallBits(NewSmallBits);
  85. }
  86. void switchToLarge(BitVector *BV) {
  87. X = reinterpret_cast<uintptr_t>(BV);
  88. assert(!isSmall() && "Tried to use an unaligned pointer");
  89. }
  90. // Return all the bits used for the "small" representation; this includes
  91. // bits for the size as well as the element bits.
  92. uintptr_t getSmallRawBits() const {
  93. assert(isSmall());
  94. return X >> 1;
  95. }
  96. void setSmallRawBits(uintptr_t NewRawBits) {
  97. assert(isSmall());
  98. X = (NewRawBits << 1) | uintptr_t(1);
  99. }
  100. // Return the size.
  101. size_t getSmallSize() const {
  102. return getSmallRawBits() >> SmallNumDataBits;
  103. }
  104. void setSmallSize(size_t Size) {
  105. setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
  106. }
  107. // Return the element bits.
  108. uintptr_t getSmallBits() const {
  109. return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize());
  110. }
  111. void setSmallBits(uintptr_t NewBits) {
  112. setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) |
  113. (getSmallSize() << SmallNumDataBits));
  114. }
  115. public:
  116. /// SmallBitVector default ctor - Creates an empty bitvector.
  117. SmallBitVector() : X(1) {}
  118. /// SmallBitVector ctor - Creates a bitvector of specified number of bits. All
  119. /// bits are initialized to the specified value.
  120. explicit SmallBitVector(unsigned s, bool t = false) {
  121. if (s <= SmallNumDataBits)
  122. switchToSmall(t ? ~uintptr_t(0) : 0, s);
  123. else
  124. switchToLarge(new BitVector(s, t));
  125. }
  126. /// SmallBitVector copy ctor.
  127. SmallBitVector(const SmallBitVector &RHS) {
  128. if (RHS.isSmall())
  129. X = RHS.X;
  130. else
  131. switchToLarge(new BitVector(*RHS.getPointer()));
  132. }
  133. SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
  134. RHS.X = 1;
  135. }
  136. ~SmallBitVector() {
  137. if (!isSmall())
  138. delete getPointer();
  139. }
  140. /// empty - Tests whether there are no bits in this bitvector.
  141. bool empty() const {
  142. return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
  143. }
  144. /// size - Returns the number of bits in this bitvector.
  145. size_t size() const {
  146. return isSmall() ? getSmallSize() : getPointer()->size();
  147. }
  148. /// count - Returns the number of bits which are set.
  149. size_type count() const {
  150. if (isSmall()) {
  151. uintptr_t Bits = getSmallBits();
  152. return countPopulation(Bits);
  153. }
  154. return getPointer()->count();
  155. }
  156. /// any - Returns true if any bit is set.
  157. bool any() const {
  158. if (isSmall())
  159. return getSmallBits() != 0;
  160. return getPointer()->any();
  161. }
  162. /// all - Returns true if all bits are set.
  163. bool all() const {
  164. if (isSmall())
  165. return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1;
  166. return getPointer()->all();
  167. }
  168. /// none - Returns true if none of the bits are set.
  169. bool none() const {
  170. if (isSmall())
  171. return getSmallBits() == 0;
  172. return getPointer()->none();
  173. }
  174. /// find_first - Returns the index of the first set bit, -1 if none
  175. /// of the bits are set.
  176. int find_first() const {
  177. if (isSmall()) {
  178. uintptr_t Bits = getSmallBits();
  179. if (Bits == 0)
  180. return -1;
  181. return countTrailingZeros(Bits);
  182. }
  183. return getPointer()->find_first();
  184. }
  185. /// find_next - Returns the index of the next set bit following the
  186. /// "Prev" bit. Returns -1 if the next set bit is not found.
  187. int find_next(unsigned Prev) const {
  188. if (isSmall()) {
  189. uintptr_t Bits = getSmallBits();
  190. // Mask off previous bits.
  191. Bits &= ~uintptr_t(0) << (Prev + 1);
  192. if (Bits == 0 || Prev + 1 >= getSmallSize())
  193. return -1;
  194. return countTrailingZeros(Bits);
  195. }
  196. return getPointer()->find_next(Prev);
  197. }
  198. /// clear - Clear all bits.
  199. void clear() {
  200. if (!isSmall())
  201. delete getPointer();
  202. switchToSmall(0, 0);
  203. }
  204. /// resize - Grow or shrink the bitvector.
  205. void resize(unsigned N, bool t = false) {
  206. if (!isSmall()) {
  207. getPointer()->resize(N, t);
  208. } else if (SmallNumDataBits >= N) {
  209. uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0;
  210. setSmallSize(N);
  211. setSmallBits(NewBits | getSmallBits());
  212. } else {
  213. BitVector *BV = new BitVector(N, t);
  214. uintptr_t OldBits = getSmallBits();
  215. for (size_t i = 0, e = getSmallSize(); i != e; ++i)
  216. (*BV)[i] = (OldBits >> i) & 1;
  217. switchToLarge(BV);
  218. }
  219. }
  220. void reserve(unsigned N) {
  221. if (isSmall()) {
  222. if (N > SmallNumDataBits) {
  223. uintptr_t OldBits = getSmallRawBits();
  224. size_t SmallSize = getSmallSize();
  225. BitVector *BV = new BitVector(SmallSize);
  226. for (size_t i = 0; i < SmallSize; ++i)
  227. if ((OldBits >> i) & 1)
  228. BV->set(i);
  229. BV->reserve(N);
  230. switchToLarge(BV);
  231. }
  232. } else {
  233. getPointer()->reserve(N);
  234. }
  235. }
  236. // Set, reset, flip
  237. SmallBitVector &set() {
  238. if (isSmall())
  239. setSmallBits(~uintptr_t(0));
  240. else
  241. getPointer()->set();
  242. return *this;
  243. }
  244. SmallBitVector &set(unsigned Idx) {
  245. if (isSmall()) {
  246. assert(Idx <= static_cast<unsigned>(
  247. std::numeric_limits<uintptr_t>::digits) &&
  248. "undefined behavior");
  249. setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
  250. }
  251. else
  252. getPointer()->set(Idx);
  253. return *this;
  254. }
  255. /// set - Efficiently set a range of bits in [I, E)
  256. SmallBitVector &set(unsigned I, unsigned E) {
  257. assert(I <= E && "Attempted to set backwards range!");
  258. assert(E <= size() && "Attempted to set out-of-bounds range!");
  259. if (I == E) return *this;
  260. if (isSmall()) {
  261. uintptr_t EMask = ((uintptr_t)1) << E;
  262. uintptr_t IMask = ((uintptr_t)1) << I;
  263. uintptr_t Mask = EMask - IMask;
  264. setSmallBits(getSmallBits() | Mask);
  265. } else
  266. getPointer()->set(I, E);
  267. return *this;
  268. }
  269. SmallBitVector &reset() {
  270. if (isSmall())
  271. setSmallBits(0);
  272. else
  273. getPointer()->reset();
  274. return *this;
  275. }
  276. SmallBitVector &reset(unsigned Idx) {
  277. if (isSmall())
  278. setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
  279. else
  280. getPointer()->reset(Idx);
  281. return *this;
  282. }
  283. /// reset - Efficiently reset a range of bits in [I, E)
  284. SmallBitVector &reset(unsigned I, unsigned E) {
  285. assert(I <= E && "Attempted to reset backwards range!");
  286. assert(E <= size() && "Attempted to reset out-of-bounds range!");
  287. if (I == E) return *this;
  288. if (isSmall()) {
  289. uintptr_t EMask = ((uintptr_t)1) << E;
  290. uintptr_t IMask = ((uintptr_t)1) << I;
  291. uintptr_t Mask = EMask - IMask;
  292. setSmallBits(getSmallBits() & ~Mask);
  293. } else
  294. getPointer()->reset(I, E);
  295. return *this;
  296. }
  297. SmallBitVector &flip() {
  298. if (isSmall())
  299. setSmallBits(~getSmallBits());
  300. else
  301. getPointer()->flip();
  302. return *this;
  303. }
  304. SmallBitVector &flip(unsigned Idx) {
  305. if (isSmall())
  306. setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
  307. else
  308. getPointer()->flip(Idx);
  309. return *this;
  310. }
  311. // No argument flip.
  312. SmallBitVector operator~() const {
  313. return SmallBitVector(*this).flip();
  314. }
  315. // Indexing.
  316. reference operator[](unsigned Idx) {
  317. assert(Idx < size() && "Out-of-bounds Bit access.");
  318. return reference(*this, Idx);
  319. }
  320. bool operator[](unsigned Idx) const {
  321. assert(Idx < size() && "Out-of-bounds Bit access.");
  322. if (isSmall())
  323. return ((getSmallBits() >> Idx) & 1) != 0;
  324. return getPointer()->operator[](Idx);
  325. }
  326. bool test(unsigned Idx) const {
  327. return (*this)[Idx];
  328. }
  329. /// Test if any common bits are set.
  330. bool anyCommon(const SmallBitVector &RHS) const {
  331. if (isSmall() && RHS.isSmall())
  332. return (getSmallBits() & RHS.getSmallBits()) != 0;
  333. if (!isSmall() && !RHS.isSmall())
  334. return getPointer()->anyCommon(*RHS.getPointer());
  335. for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
  336. if (test(i) && RHS.test(i))
  337. return true;
  338. return false;
  339. }
  340. // Comparison operators.
  341. bool operator==(const SmallBitVector &RHS) const {
  342. if (size() != RHS.size())
  343. return false;
  344. if (isSmall())
  345. return getSmallBits() == RHS.getSmallBits();
  346. else
  347. return *getPointer() == *RHS.getPointer();
  348. }
  349. bool operator!=(const SmallBitVector &RHS) const {
  350. return !(*this == RHS);
  351. }
  352. // Intersection, union, disjoint union.
  353. SmallBitVector &operator&=(const SmallBitVector &RHS) {
  354. resize(std::max(size(), RHS.size()));
  355. if (isSmall())
  356. setSmallBits(getSmallBits() & RHS.getSmallBits());
  357. else if (!RHS.isSmall())
  358. getPointer()->operator&=(*RHS.getPointer());
  359. else {
  360. SmallBitVector Copy = RHS;
  361. Copy.resize(size());
  362. getPointer()->operator&=(*Copy.getPointer());
  363. }
  364. return *this;
  365. }
  366. /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
  367. SmallBitVector &reset(const SmallBitVector &RHS) {
  368. if (isSmall() && RHS.isSmall())
  369. setSmallBits(getSmallBits() & ~RHS.getSmallBits());
  370. else if (!isSmall() && !RHS.isSmall())
  371. getPointer()->reset(*RHS.getPointer());
  372. else
  373. for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
  374. if (RHS.test(i))
  375. reset(i);
  376. return *this;
  377. }
  378. /// test - Check if (This - RHS) is zero.
  379. /// This is the same as reset(RHS) and any().
  380. bool test(const SmallBitVector &RHS) const {
  381. if (isSmall() && RHS.isSmall())
  382. return (getSmallBits() & ~RHS.getSmallBits()) != 0;
  383. if (!isSmall() && !RHS.isSmall())
  384. return getPointer()->test(*RHS.getPointer());
  385. unsigned i, e;
  386. for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
  387. if (test(i) && !RHS.test(i))
  388. return true;
  389. for (e = size(); i != e; ++i)
  390. if (test(i))
  391. return true;
  392. return false;
  393. }
  394. SmallBitVector &operator|=(const SmallBitVector &RHS) {
  395. resize(std::max(size(), RHS.size()));
  396. if (isSmall())
  397. setSmallBits(getSmallBits() | RHS.getSmallBits());
  398. else if (!RHS.isSmall())
  399. getPointer()->operator|=(*RHS.getPointer());
  400. else {
  401. SmallBitVector Copy = RHS;
  402. Copy.resize(size());
  403. getPointer()->operator|=(*Copy.getPointer());
  404. }
  405. return *this;
  406. }
  407. SmallBitVector &operator^=(const SmallBitVector &RHS) {
  408. resize(std::max(size(), RHS.size()));
  409. if (isSmall())
  410. setSmallBits(getSmallBits() ^ RHS.getSmallBits());
  411. else if (!RHS.isSmall())
  412. getPointer()->operator^=(*RHS.getPointer());
  413. else {
  414. SmallBitVector Copy = RHS;
  415. Copy.resize(size());
  416. getPointer()->operator^=(*Copy.getPointer());
  417. }
  418. return *this;
  419. }
  420. // Assignment operator.
  421. const SmallBitVector &operator=(const SmallBitVector &RHS) {
  422. if (isSmall()) {
  423. if (RHS.isSmall())
  424. X = RHS.X;
  425. else
  426. switchToLarge(new BitVector(*RHS.getPointer()));
  427. } else {
  428. if (!RHS.isSmall())
  429. *getPointer() = *RHS.getPointer();
  430. else {
  431. delete getPointer();
  432. X = RHS.X;
  433. }
  434. }
  435. return *this;
  436. }
  437. const SmallBitVector &operator=(SmallBitVector &&RHS) {
  438. if (this != &RHS) {
  439. clear();
  440. swap(RHS);
  441. }
  442. return *this;
  443. }
  444. void swap(SmallBitVector &RHS) {
  445. std::swap(X, RHS.X);
  446. }
  447. /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
  448. /// This computes "*this |= Mask".
  449. void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
  450. if (isSmall())
  451. applyMask<true, false>(Mask, MaskWords);
  452. else
  453. getPointer()->setBitsInMask(Mask, MaskWords);
  454. }
  455. /// clearBitsInMask - Clear any bits in this vector that are set in Mask.
  456. /// Don't resize. This computes "*this &= ~Mask".
  457. void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
  458. if (isSmall())
  459. applyMask<false, false>(Mask, MaskWords);
  460. else
  461. getPointer()->clearBitsInMask(Mask, MaskWords);
  462. }
  463. /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
  464. /// Don't resize. This computes "*this |= ~Mask".
  465. void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
  466. if (isSmall())
  467. applyMask<true, true>(Mask, MaskWords);
  468. else
  469. getPointer()->setBitsNotInMask(Mask, MaskWords);
  470. }
  471. /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
  472. /// Don't resize. This computes "*this &= Mask".
  473. void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
  474. if (isSmall())
  475. applyMask<false, true>(Mask, MaskWords);
  476. else
  477. getPointer()->clearBitsNotInMask(Mask, MaskWords);
  478. }
  479. private:
  480. template<bool AddBits, bool InvertMask>
  481. void applyMask(const uint32_t *Mask, unsigned MaskWords) {
  482. if (NumBaseBits == 64 && MaskWords >= 2) {
  483. uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32);
  484. if (InvertMask) M = ~M;
  485. if (AddBits) setSmallBits(getSmallBits() | M);
  486. else setSmallBits(getSmallBits() & ~M);
  487. } else {
  488. #pragma warning( push ) // HLSL Change
  489. #pragma warning( disable: 4319 ) // HLSL Change - not a branch in 64-bit - '~': zero extending 'uint32_t' to 'uintptr_t' of greater size
  490. uint32_t M = Mask[0];
  491. if (InvertMask) M = ~M;
  492. if (AddBits) setSmallBits(getSmallBits() | M);
  493. else setSmallBits(getSmallBits() & ~M);
  494. #pragma warning( pop ) // HLSL Change
  495. }
  496. }
  497. };
  498. inline SmallBitVector
  499. operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) {
  500. SmallBitVector Result(LHS);
  501. Result &= RHS;
  502. return Result;
  503. }
  504. inline SmallBitVector
  505. operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) {
  506. SmallBitVector Result(LHS);
  507. Result |= RHS;
  508. return Result;
  509. }
  510. inline SmallBitVector
  511. operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
  512. SmallBitVector Result(LHS);
  513. Result ^= RHS;
  514. return Result;
  515. }
  516. } // End llvm namespace
  517. namespace std {
  518. /// Implement std::swap in terms of BitVector swap.
  519. inline void
  520. swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
  521. LHS.swap(RHS);
  522. }
  523. }
  524. #endif