1 //===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the SmallBitVector class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_ADT_SMALLBITVECTOR_H
14 #define LLVM_ADT_SMALLBITVECTOR_H
16 #include "llvm/ADT/BitVector.h"
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/Support/MathExtras.h"
29 /// This is a 'bitvector' (really, a variable-sized bit array), optimized for
30 /// the case when the array is small. It contains one pointer-sized field, which
31 /// is directly used as a plain collection of bits when possible, or as a
32 /// pointer to a larger heap-allocated array when necessary. This allows normal
33 /// "small" cases to be fast without losing generality for large inputs.
34 class SmallBitVector
{
35 // TODO: In "large" mode, a pointer to a BitVector is used, leading to an
36 // unnecessary level of indirection. It would be more efficient to use a
37 // pointer to memory containing size, allocation size, and the array of bits.
41 // The number of bits in this class.
42 NumBaseBits
= sizeof(uintptr_t) * CHAR_BIT
,
44 // One bit is used to discriminate between small and large mode. The
45 // remaining bits are used for the small-mode representation.
46 SmallNumRawBits
= NumBaseBits
- 1,
48 // A few more bits are used to store the size of the bit set in small mode.
49 // Theoretically this is a ceil-log2. These bits are encoded in the most
50 // significant bits of the raw bits.
51 SmallNumSizeBits
= (NumBaseBits
== 32 ? 5 :
52 NumBaseBits
== 64 ? 6 :
55 // The remaining bits are used to store the actual set in small mode.
56 SmallNumDataBits
= SmallNumRawBits
- SmallNumSizeBits
59 static_assert(NumBaseBits
== 64 || NumBaseBits
== 32,
60 "Unsupported word size");
63 using size_type
= unsigned;
65 // Encapsulation of a single bit.
67 SmallBitVector
&TheVector
;
71 reference(SmallBitVector
&b
, unsigned Idx
) : TheVector(b
), BitPos(Idx
) {}
73 reference(const reference
&) = default;
75 reference
& operator=(reference t
) {
80 reference
& operator=(bool t
) {
82 TheVector
.set(BitPos
);
84 TheVector
.reset(BitPos
);
88 operator bool() const {
89 return const_cast<const SmallBitVector
&>(TheVector
).operator[](BitPos
);
94 BitVector
*getPointer() const {
96 return reinterpret_cast<BitVector
*>(X
);
99 void switchToSmall(uintptr_t NewSmallBits
, size_t NewSize
) {
101 setSmallSize(NewSize
);
102 setSmallBits(NewSmallBits
);
105 void switchToLarge(BitVector
*BV
) {
106 X
= reinterpret_cast<uintptr_t>(BV
);
107 assert(!isSmall() && "Tried to use an unaligned pointer");
110 // Return all the bits used for the "small" representation; this includes
111 // bits for the size as well as the element bits.
112 uintptr_t getSmallRawBits() const {
117 void setSmallRawBits(uintptr_t NewRawBits
) {
119 X
= (NewRawBits
<< 1) | uintptr_t(1);
123 size_t getSmallSize() const { return getSmallRawBits() >> SmallNumDataBits
; }
125 void setSmallSize(size_t Size
) {
126 setSmallRawBits(getSmallBits() | (Size
<< SmallNumDataBits
));
129 // Return the element bits.
130 uintptr_t getSmallBits() const {
131 return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize());
134 void setSmallBits(uintptr_t NewBits
) {
135 setSmallRawBits((NewBits
& ~(~uintptr_t(0) << getSmallSize())) |
136 (getSmallSize() << SmallNumDataBits
));
140 /// Creates an empty bitvector.
141 SmallBitVector() = default;
143 /// Creates a bitvector of specified number of bits. All bits are initialized
144 /// to the specified value.
145 explicit SmallBitVector(unsigned s
, bool t
= false) {
146 if (s
<= SmallNumDataBits
)
147 switchToSmall(t
? ~uintptr_t(0) : 0, s
);
149 switchToLarge(new BitVector(s
, t
));
152 /// SmallBitVector copy ctor.
153 SmallBitVector(const SmallBitVector
&RHS
) {
157 switchToLarge(new BitVector(*RHS
.getPointer()));
160 SmallBitVector(SmallBitVector
&&RHS
) : X(RHS
.X
) {
169 using const_set_bits_iterator
= const_set_bits_iterator_impl
<SmallBitVector
>;
170 using set_iterator
= const_set_bits_iterator
;
172 const_set_bits_iterator
set_bits_begin() const {
173 return const_set_bits_iterator(*this);
176 const_set_bits_iterator
set_bits_end() const {
177 return const_set_bits_iterator(*this, -1);
180 iterator_range
<const_set_bits_iterator
> set_bits() const {
181 return make_range(set_bits_begin(), set_bits_end());
184 bool isSmall() const { return X
& uintptr_t(1); }
186 /// Tests whether there are no bits in this bitvector.
188 return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
191 /// Returns the number of bits in this bitvector.
192 size_t size() const {
193 return isSmall() ? getSmallSize() : getPointer()->size();
196 /// Returns the number of bits which are set.
197 size_type
count() const {
199 uintptr_t Bits
= getSmallBits();
200 return countPopulation(Bits
);
202 return getPointer()->count();
205 /// Returns true if any bit is set.
208 return getSmallBits() != 0;
209 return getPointer()->any();
212 /// Returns true if all bits are set.
215 return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1;
216 return getPointer()->all();
219 /// Returns true if none of the bits are set.
222 return getSmallBits() == 0;
223 return getPointer()->none();
226 /// Returns the index of the first set bit, -1 if none of the bits are set.
227 int find_first() const {
229 uintptr_t Bits
= getSmallBits();
232 return countTrailingZeros(Bits
);
234 return getPointer()->find_first();
237 int find_last() const {
239 uintptr_t Bits
= getSmallBits();
242 return NumBaseBits
- countLeadingZeros(Bits
) - 1;
244 return getPointer()->find_last();
247 /// Returns the index of the first unset bit, -1 if all of the bits are set.
248 int find_first_unset() const {
250 if (count() == getSmallSize())
253 uintptr_t Bits
= getSmallBits();
254 return countTrailingOnes(Bits
);
256 return getPointer()->find_first_unset();
259 int find_last_unset() const {
261 if (count() == getSmallSize())
264 uintptr_t Bits
= getSmallBits();
266 Bits
|= ~uintptr_t(0) << getSmallSize();
267 return NumBaseBits
- countLeadingOnes(Bits
) - 1;
269 return getPointer()->find_last_unset();
272 /// Returns the index of the next set bit following the "Prev" bit.
273 /// Returns -1 if the next set bit is not found.
274 int find_next(unsigned Prev
) const {
276 uintptr_t Bits
= getSmallBits();
277 // Mask off previous bits.
278 Bits
&= ~uintptr_t(0) << (Prev
+ 1);
279 if (Bits
== 0 || Prev
+ 1 >= getSmallSize())
281 return countTrailingZeros(Bits
);
283 return getPointer()->find_next(Prev
);
286 /// Returns the index of the next unset bit following the "Prev" bit.
287 /// Returns -1 if the next unset bit is not found.
288 int find_next_unset(unsigned Prev
) const {
291 uintptr_t Bits
= getSmallBits();
292 // Mask in previous bits.
293 uintptr_t Mask
= (uintptr_t(1) << Prev
) - 1;
296 if (Bits
== ~uintptr_t(0) || Prev
+ 1 >= getSmallSize())
298 return countTrailingOnes(Bits
);
300 return getPointer()->find_next_unset(Prev
);
303 /// find_prev - Returns the index of the first set bit that precedes the
304 /// the bit at \p PriorTo. Returns -1 if all previous bits are unset.
305 int find_prev(unsigned PriorTo
) const {
311 uintptr_t Bits
= getSmallBits();
312 Bits
&= maskTrailingOnes
<uintptr_t>(PriorTo
+ 1);
316 return NumBaseBits
- countLeadingZeros(Bits
) - 1;
318 return getPointer()->find_prev(PriorTo
);
328 /// Grow or shrink the bitvector.
329 void resize(unsigned N
, bool t
= false) {
331 getPointer()->resize(N
, t
);
332 } else if (SmallNumDataBits
>= N
) {
333 uintptr_t NewBits
= t
? ~uintptr_t(0) << getSmallSize() : 0;
335 setSmallBits(NewBits
| getSmallBits());
337 BitVector
*BV
= new BitVector(N
, t
);
338 uintptr_t OldBits
= getSmallBits();
339 for (size_t i
= 0, e
= getSmallSize(); i
!= e
; ++i
)
340 (*BV
)[i
] = (OldBits
>> i
) & 1;
345 void reserve(unsigned N
) {
347 if (N
> SmallNumDataBits
) {
348 uintptr_t OldBits
= getSmallRawBits();
349 size_t SmallSize
= getSmallSize();
350 BitVector
*BV
= new BitVector(SmallSize
);
351 for (size_t i
= 0; i
< SmallSize
; ++i
)
352 if ((OldBits
>> i
) & 1)
358 getPointer()->reserve(N
);
363 SmallBitVector
&set() {
365 setSmallBits(~uintptr_t(0));
371 SmallBitVector
&set(unsigned Idx
) {
373 assert(Idx
<= static_cast<unsigned>(
374 std::numeric_limits
<uintptr_t>::digits
) &&
375 "undefined behavior");
376 setSmallBits(getSmallBits() | (uintptr_t(1) << Idx
));
379 getPointer()->set(Idx
);
383 /// Efficiently set a range of bits in [I, E)
384 SmallBitVector
&set(unsigned I
, unsigned E
) {
385 assert(I
<= E
&& "Attempted to set backwards range!");
386 assert(E
<= size() && "Attempted to set out-of-bounds range!");
387 if (I
== E
) return *this;
389 uintptr_t EMask
= ((uintptr_t)1) << E
;
390 uintptr_t IMask
= ((uintptr_t)1) << I
;
391 uintptr_t Mask
= EMask
- IMask
;
392 setSmallBits(getSmallBits() | Mask
);
394 getPointer()->set(I
, E
);
398 SmallBitVector
&reset() {
402 getPointer()->reset();
406 SmallBitVector
&reset(unsigned Idx
) {
408 setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx
));
410 getPointer()->reset(Idx
);
414 /// Efficiently reset a range of bits in [I, E)
415 SmallBitVector
&reset(unsigned I
, unsigned E
) {
416 assert(I
<= E
&& "Attempted to reset backwards range!");
417 assert(E
<= size() && "Attempted to reset out-of-bounds range!");
418 if (I
== E
) return *this;
420 uintptr_t EMask
= ((uintptr_t)1) << E
;
421 uintptr_t IMask
= ((uintptr_t)1) << I
;
422 uintptr_t Mask
= EMask
- IMask
;
423 setSmallBits(getSmallBits() & ~Mask
);
425 getPointer()->reset(I
, E
);
429 SmallBitVector
&flip() {
431 setSmallBits(~getSmallBits());
433 getPointer()->flip();
437 SmallBitVector
&flip(unsigned Idx
) {
439 setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx
));
441 getPointer()->flip(Idx
);
446 SmallBitVector
operator~() const {
447 return SmallBitVector(*this).flip();
451 reference
operator[](unsigned Idx
) {
452 assert(Idx
< size() && "Out-of-bounds Bit access.");
453 return reference(*this, Idx
);
456 bool operator[](unsigned Idx
) const {
457 assert(Idx
< size() && "Out-of-bounds Bit access.");
459 return ((getSmallBits() >> Idx
) & 1) != 0;
460 return getPointer()->operator[](Idx
);
463 bool test(unsigned Idx
) const {
467 // Push single bit to end of vector.
468 void push_back(bool Val
) {
469 resize(size() + 1, Val
);
472 /// Test if any common bits are set.
473 bool anyCommon(const SmallBitVector
&RHS
) const {
474 if (isSmall() && RHS
.isSmall())
475 return (getSmallBits() & RHS
.getSmallBits()) != 0;
476 if (!isSmall() && !RHS
.isSmall())
477 return getPointer()->anyCommon(*RHS
.getPointer());
479 for (unsigned i
= 0, e
= std::min(size(), RHS
.size()); i
!= e
; ++i
)
480 if (test(i
) && RHS
.test(i
))
485 // Comparison operators.
486 bool operator==(const SmallBitVector
&RHS
) const {
487 if (size() != RHS
.size())
489 if (isSmall() && RHS
.isSmall())
490 return getSmallBits() == RHS
.getSmallBits();
491 else if (!isSmall() && !RHS
.isSmall())
492 return *getPointer() == *RHS
.getPointer();
494 for (size_t i
= 0, e
= size(); i
!= e
; ++i
) {
495 if ((*this)[i
] != RHS
[i
])
502 bool operator!=(const SmallBitVector
&RHS
) const {
503 return !(*this == RHS
);
506 // Intersection, union, disjoint union.
507 // FIXME BitVector::operator&= does not resize the LHS but this does
508 SmallBitVector
&operator&=(const SmallBitVector
&RHS
) {
509 resize(std::max(size(), RHS
.size()));
510 if (isSmall() && RHS
.isSmall())
511 setSmallBits(getSmallBits() & RHS
.getSmallBits());
512 else if (!isSmall() && !RHS
.isSmall())
513 getPointer()->operator&=(*RHS
.getPointer());
516 for (i
= 0, e
= std::min(size(), RHS
.size()); i
!= e
; ++i
)
517 (*this)[i
] = test(i
) && RHS
.test(i
);
518 for (e
= size(); i
!= e
; ++i
)
524 /// Reset bits that are set in RHS. Same as *this &= ~RHS.
525 SmallBitVector
&reset(const SmallBitVector
&RHS
) {
526 if (isSmall() && RHS
.isSmall())
527 setSmallBits(getSmallBits() & ~RHS
.getSmallBits());
528 else if (!isSmall() && !RHS
.isSmall())
529 getPointer()->reset(*RHS
.getPointer());
531 for (unsigned i
= 0, e
= std::min(size(), RHS
.size()); i
!= e
; ++i
)
538 /// Check if (This - RHS) is zero. This is the same as reset(RHS) and any().
539 bool test(const SmallBitVector
&RHS
) const {
540 if (isSmall() && RHS
.isSmall())
541 return (getSmallBits() & ~RHS
.getSmallBits()) != 0;
542 if (!isSmall() && !RHS
.isSmall())
543 return getPointer()->test(*RHS
.getPointer());
546 for (i
= 0, e
= std::min(size(), RHS
.size()); i
!= e
; ++i
)
547 if (test(i
) && !RHS
.test(i
))
550 for (e
= size(); i
!= e
; ++i
)
557 SmallBitVector
&operator|=(const SmallBitVector
&RHS
) {
558 resize(std::max(size(), RHS
.size()));
559 if (isSmall() && RHS
.isSmall())
560 setSmallBits(getSmallBits() | RHS
.getSmallBits());
561 else if (!isSmall() && !RHS
.isSmall())
562 getPointer()->operator|=(*RHS
.getPointer());
564 for (size_t i
= 0, e
= RHS
.size(); i
!= e
; ++i
)
565 (*this)[i
] = test(i
) || RHS
.test(i
);
570 SmallBitVector
&operator^=(const SmallBitVector
&RHS
) {
571 resize(std::max(size(), RHS
.size()));
572 if (isSmall() && RHS
.isSmall())
573 setSmallBits(getSmallBits() ^ RHS
.getSmallBits());
574 else if (!isSmall() && !RHS
.isSmall())
575 getPointer()->operator^=(*RHS
.getPointer());
577 for (size_t i
= 0, e
= RHS
.size(); i
!= e
; ++i
)
578 (*this)[i
] = test(i
) != RHS
.test(i
);
583 SmallBitVector
&operator<<=(unsigned N
) {
585 setSmallBits(getSmallBits() << N
);
587 getPointer()->operator<<=(N
);
591 SmallBitVector
&operator>>=(unsigned N
) {
593 setSmallBits(getSmallBits() >> N
);
595 getPointer()->operator>>=(N
);
599 // Assignment operator.
600 const SmallBitVector
&operator=(const SmallBitVector
&RHS
) {
605 switchToLarge(new BitVector(*RHS
.getPointer()));
608 *getPointer() = *RHS
.getPointer();
617 const SmallBitVector
&operator=(SmallBitVector
&&RHS
) {
625 void swap(SmallBitVector
&RHS
) {
629 /// Add '1' bits from Mask to this vector. Don't resize.
630 /// This computes "*this |= Mask".
631 void setBitsInMask(const uint32_t *Mask
, unsigned MaskWords
= ~0u) {
633 applyMask
<true, false>(Mask
, MaskWords
);
635 getPointer()->setBitsInMask(Mask
, MaskWords
);
638 /// Clear any bits in this vector that are set in Mask. Don't resize.
639 /// This computes "*this &= ~Mask".
640 void clearBitsInMask(const uint32_t *Mask
, unsigned MaskWords
= ~0u) {
642 applyMask
<false, false>(Mask
, MaskWords
);
644 getPointer()->clearBitsInMask(Mask
, MaskWords
);
647 /// Add a bit to this vector for every '0' bit in Mask. Don't resize.
648 /// This computes "*this |= ~Mask".
649 void setBitsNotInMask(const uint32_t *Mask
, unsigned MaskWords
= ~0u) {
651 applyMask
<true, true>(Mask
, MaskWords
);
653 getPointer()->setBitsNotInMask(Mask
, MaskWords
);
656 /// Clear a bit in this vector for every '0' bit in Mask. Don't resize.
657 /// This computes "*this &= Mask".
658 void clearBitsNotInMask(const uint32_t *Mask
, unsigned MaskWords
= ~0u) {
660 applyMask
<false, true>(Mask
, MaskWords
);
662 getPointer()->clearBitsNotInMask(Mask
, MaskWords
);
666 template <bool AddBits
, bool InvertMask
>
667 void applyMask(const uint32_t *Mask
, unsigned MaskWords
) {
668 assert(MaskWords
<= sizeof(uintptr_t) && "Mask is larger than base!");
669 uintptr_t M
= Mask
[0];
670 if (NumBaseBits
== 64)
671 M
|= uint64_t(Mask
[1]) << 32;
675 setSmallBits(getSmallBits() | M
);
677 setSmallBits(getSmallBits() & ~M
);
681 inline SmallBitVector
682 operator&(const SmallBitVector
&LHS
, const SmallBitVector
&RHS
) {
683 SmallBitVector
Result(LHS
);
688 inline SmallBitVector
689 operator|(const SmallBitVector
&LHS
, const SmallBitVector
&RHS
) {
690 SmallBitVector
Result(LHS
);
695 inline SmallBitVector
696 operator^(const SmallBitVector
&LHS
, const SmallBitVector
&RHS
) {
697 SmallBitVector
Result(LHS
);
702 } // end namespace llvm
706 /// Implement std::swap in terms of BitVector swap.
708 swap(llvm::SmallBitVector
&LHS
, llvm::SmallBitVector
&RHS
) {
712 } // end namespace std
714 #endif // LLVM_ADT_SMALLBITVECTOR_H