LLVM: include/llvm/ADT/SmallBitVector.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef LLVM_ADT_SMALLBITVECTOR_H
15#define LLVM_ADT_SMALLBITVECTOR_H
16
20#include
21#include
22#include
23#include
24#include
25#include
26#include
27
28namespace llvm {
29
30
31
32
33
34
36
37
38
39 uintptr_t X = 1;
40
41 enum {
42
43 NumBaseBits = sizeof(uintptr_t) * CHAR_BIT,
44
45
46
47 SmallNumRawBits = NumBaseBits - 1,
48
49
50
51
52 SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
53 NumBaseBits == 64 ? 6 :
54 SmallNumRawBits),
55
56
57 SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
58 };
59
60 static_assert(NumBaseBits == 64 || NumBaseBits == 32,
61 "Unsupported word size");
62
63public:
65
66
69 unsigned BitPos;
70
71 public:
73
75
77 *this = bool(t);
78 return *this;
79 }
80
82 if (t)
83 TheVector.set(BitPos);
84 else
85 TheVector.reset(BitPos);
86 return *this;
87 }
88
90 return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos);
91 }
92 };
93
94private:
97 return reinterpret_cast<BitVector *>(X);
98 }
99
100 void switchToSmall(uintptr_t NewSmallBits, size_type NewSize) {
101 X = 1;
102 setSmallSize(NewSize);
103 setSmallBits(NewSmallBits);
104 }
105
106 void switchToLarge(BitVector *BV) {
107 X = reinterpret_cast<uintptr_t>(BV);
108 assert(() && "Tried to use an unaligned pointer");
109 }
110
111
112
113 uintptr_t getSmallRawBits() const {
115 return X >> 1;
116 }
117
118 void setSmallRawBits(uintptr_t NewRawBits) {
120 X = (NewRawBits << 1) | uintptr_t(1);
121 }
122
123
125 return getSmallRawBits() >> SmallNumDataBits;
126 }
127
129 setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
130 }
131
132
133 uintptr_t getSmallBits() const {
134 return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize());
135 }
136
137 void setSmallBits(uintptr_t NewBits) {
138 setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) |
139 (getSmallSize() << SmallNumDataBits));
140 }
141
142public:
143
145
146
147
149 if (s <= SmallNumDataBits)
150 switchToSmall(t ? ~uintptr_t(0) : 0, s);
151 else
152 switchToLarge(new BitVector(s, t));
153 }
154
155
157 if (RHS.isSmall())
158 X = RHS.X;
159 else
160 switchToLarge(new BitVector(*RHS.getPointer()));
161 }
162
166
169 delete getPointer();
170 }
171
174
178
182
186
187 bool isSmall() const { return X & uintptr_t(1); }
188
189
191 return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
192 }
193
194
196 return isSmall() ? getSmallSize() : getPointer()->size();
197 }
198
199
202 uintptr_t Bits = getSmallBits();
204 }
205 return getPointer()->count();
206 }
207
208
211 return getSmallBits() != 0;
212 return getPointer()->any();
213 }
214
215
218 return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1;
219 return getPointer()->all();
220 }
221
222
225 return getSmallBits() == 0;
226 return getPointer()->none();
227 }
228
229
232 uintptr_t Bits = getSmallBits();
233 if (Bits == 0)
234 return -1;
236 }
237 return getPointer()->find_first();
238 }
239
242 uintptr_t Bits = getSmallBits();
243 if (Bits == 0)
244 return -1;
246 }
247 return getPointer()->find_last();
248 }
249
250
253 if (count() == getSmallSize())
254 return -1;
255
256 uintptr_t Bits = getSmallBits();
258 }
259 return getPointer()->find_first_unset();
260 }
261
264 if (count() == getSmallSize())
265 return -1;
266
267 uintptr_t Bits = getSmallBits();
268
269 Bits |= ~uintptr_t(0) << getSmallSize();
271 }
272 return getPointer()->find_last_unset();
273 }
274
275
276
279 uintptr_t Bits = getSmallBits();
280
281 Bits &= ~uintptr_t(0) << (Prev + 1);
282 if (Bits == 0 || Prev + 1 >= getSmallSize())
283 return -1;
285 }
286 return getPointer()->find_next(Prev);
287 }
288
289
290
293 uintptr_t Bits = getSmallBits();
294
295 Bits |= (uintptr_t(1) << (Prev + 1)) - 1;
296
297 Bits |= ~uintptr_t(0) << getSmallSize();
298
299 if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize())
300 return -1;
302 }
303 return getPointer()->find_next_unset(Prev);
304 }
305
306
307
310 if (PriorTo == 0)
311 return -1;
312
313 --PriorTo;
314 uintptr_t Bits = getSmallBits();
316 if (Bits == 0)
317 return -1;
318
320 }
321 return getPointer()->find_prev(PriorTo);
322 }
323
324
327 delete getPointer();
328 switchToSmall(0, 0);
329 }
330
331
332 void resize(unsigned N, bool t = false) {
334 getPointer()->resize(N, t);
335 } else if (SmallNumDataBits >= N) {
336 uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0;
337 setSmallSize(N);
338 setSmallBits(NewBits | getSmallBits());
339 } else {
341 uintptr_t OldBits = getSmallBits();
342 for (size_type I = 0, E = getSmallSize(); I != E; ++I)
343 (*BV)[I] = (OldBits >> I) & 1;
344 switchToLarge(BV);
345 }
346 }
347
350 if (N > SmallNumDataBits) {
351 uintptr_t OldBits = getSmallRawBits();
352 size_type SmallSize = getSmallSize();
355 if ((OldBits >> I) & 1)
358 switchToLarge(BV);
359 }
360 } else {
361 getPointer()->reserve(N);
362 }
363 }
364
365
368 setSmallBits(~uintptr_t(0));
369 else
370 getPointer()->set();
371 return *this;
372 }
373
376 assert(Idx <= static_cast<unsigned>(
377 std::numeric_limits<uintptr_t>::digits) &&
378 "undefined behavior");
379 setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
380 }
381 else
382 getPointer()->set(Idx);
383 return *this;
384 }
385
386
388 assert(I <= E && "Attempted to set backwards range!");
389 assert(E <= size() && "Attempted to set out-of-bounds range!");
392 uintptr_t EMask = ((uintptr_t)1) << E;
393 uintptr_t IMask = ((uintptr_t)1) << I;
394 uintptr_t Mask = EMask - IMask;
395 setSmallBits(getSmallBits() | Mask);
396 } else {
398 }
399 return *this;
400 }
401
404 setSmallBits(0);
405 else
406 getPointer()->reset();
407 return *this;
408 }
409
412 setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
413 else
414 getPointer()->reset(Idx);
415 return *this;
416 }
417
418
420 assert(I <= E && "Attempted to reset backwards range!");
421 assert(E <= size() && "Attempted to reset out-of-bounds range!");
424 uintptr_t EMask = ((uintptr_t)1) << E;
425 uintptr_t IMask = ((uintptr_t)1) << I;
426 uintptr_t Mask = EMask - IMask;
427 setSmallBits(getSmallBits() & ~Mask);
428 } else {
429 getPointer()->reset(I, E);
430 }
431 return *this;
432 }
433
436 setSmallBits(~getSmallBits());
437 else
438 getPointer()->flip();
439 return *this;
440 }
441
444 setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
445 else
446 getPointer()->flip(Idx);
447 return *this;
448 }
449
450
454
455
457 assert(Idx < size() && "Out-of-bounds Bit access.");
459 }
460
462 assert(Idx < size() && "Out-of-bounds Bit access.");
464 return ((getSmallBits() >> Idx) & 1) != 0;
465 return getPointer()->operator[](Idx);
466 }
467
468
470 assert(() && "Getting last element of empty vector.");
471 return (*this)[size() - 1];
472 }
473
474 bool test(unsigned Idx) const {
475 return (*this)[Idx];
476 }
477
478
482
483
485 assert(() && "Empty vector has no element to pop.");
487 }
488
489
492 return (getSmallBits() & RHS.getSmallBits()) != 0;
494 return getPointer()->anyCommon(*RHS.getPointer());
495
496 for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
497 if (test(i) && RHS.test(i))
498 return true;
499 return false;
500 }
501
502
505 return false;
507 return getSmallBits() == RHS.getSmallBits();
508 else if (() &&
.isSmall())
509 return *getPointer() == *RHS.getPointer();
510 else {
513 return false;
514 }
515 return true;
516 }
517 }
518
520 return !(*this == RHS);
521 }
522
523
524
528 setSmallBits(getSmallBits() & RHS.getSmallBits());
529 else if (() &&
.isSmall())
530 getPointer()->operator&=(*RHS.getPointer());
531 else {
533 for (I = 0, E = std::min(size(), RHS.size()); I != E; ++I)
535 for (E = size(); I != E; ++I)
537 }
538 return *this;
539 }
540
541
544 setSmallBits(getSmallBits() & ~RHS.getSmallBits());
545 else if (() &&
.isSmall())
546 getPointer()->reset(*RHS.getPointer());
547 else
548 for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
549 if (RHS.test(i))
551
552 return *this;
553 }
554
555
556
559 return (getSmallBits() & ~RHS.getSmallBits()) != 0;
561 return getPointer()->test(*RHS.getPointer());
562
563 unsigned i, e;
564 for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
565 if (test(i) && .test(i))
566 return true;
567
568 for (e = size(); i != e; ++i)
570 return true;
571
572 return false;
573 }
574
575
577
581 setSmallBits(getSmallBits() | RHS.getSmallBits());
582 else if (() &&
.isSmall())
583 getPointer()->operator|=(*RHS.getPointer());
584 else {
587 }
588 return *this;
589 }
590
594 setSmallBits(getSmallBits() ^ RHS.getSmallBits());
595 else if (() &&
.isSmall())
596 getPointer()->operator^=(*RHS.getPointer());
597 else {
600 }
601 return *this;
602 }
603
606 setSmallBits(getSmallBits() << N);
607 else
608 getPointer()->operator<<=(N);
609 return *this;
610 }
611
614 setSmallBits(getSmallBits() >> N);
615 else
616 getPointer()->operator>>=(N);
617 return *this;
618 }
619
620
623 if (RHS.isSmall())
624 X = RHS.X;
625 else
626 switchToLarge(new BitVector(*RHS.getPointer()));
627 } else {
628 if (.isSmall())
629 *getPointer() = *RHS.getPointer();
630 else {
631 delete getPointer();
632 X = RHS.X;
633 }
634 }
635 return *this;
636 }
637
639 if (this != &RHS) {
642 }
643 return *this;
644 }
645
649
650
651
654 applyMask<true, false>(Mask, MaskWords);
655 else
656 getPointer()->setBitsInMask(Mask, MaskWords);
657 }
658
659
660
663 applyMask<false, false>(Mask, MaskWords);
664 else
665 getPointer()->clearBitsInMask(Mask, MaskWords);
666 }
667
668
669
672 applyMask<true, true>(Mask, MaskWords);
673 else
674 getPointer()->setBitsNotInMask(Mask, MaskWords);
675 }
676
677
678
681 applyMask<false, true>(Mask, MaskWords);
682 else
683 getPointer()->clearBitsNotInMask(Mask, MaskWords);
684 }
685
688 X = (uintptr_t)-1;
689 }
690 bool isInvalid() const { return X == (uintptr_t)-1; }
691
694 return getPointer()->getData();
695 Store = getSmallBits();
696 return Store;
697 }
698
699private:
700 template <bool AddBits, bool InvertMask>
701 void applyMask(const uint32_t *Mask, unsigned MaskWords) {
702 assert(MaskWords <= sizeof(uintptr_t) && "Mask is larger than base!");
703 uintptr_t M = Mask[0];
704 if (NumBaseBits == 64)
705 M |= uint64_t(Mask[1]) << 32;
706 if (InvertMask)
707 M = ~M;
708 if (AddBits)
709 setSmallBits(getSmallBits() | M);
710 else
711 setSmallBits(getSmallBits() & ~M);
712 }
713};
714
718 Result &= RHS;
719 return Result;
720}
721
722inline SmallBitVector
725 Result |= RHS;
726 return Result;
727}
728
729inline SmallBitVector
732 Result ^= RHS;
733 return Result;
734}
735
744 uintptr_t Store;
746 std::pair<SmallBitVector::size_type, ArrayRef<uintptr_t>>>::
747 getHashValue(std::make_pair(V.size(), V.getData(Store)));
748 }
750 if (LHS.isInvalid() || RHS.isInvalid())
751 return LHS.isInvalid() == RHS.isInvalid();
753 }
754};
755}
756
757namespace std {
758
759
760inline void
764
765}
766
767#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Value * getPointer(Value *Ptr)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition SmallBitVector.h:67
reference(SmallBitVector &b, unsigned Idx)
Definition SmallBitVector.h:72
reference & operator=(bool t)
Definition SmallBitVector.h:81
reference & operator=(reference t)
Definition SmallBitVector.h:76
reference(const reference &)=default
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
Definition SmallBitVector.h:35
SmallBitVector & flip()
Definition SmallBitVector.h:434
reference operator[](unsigned Idx)
Definition SmallBitVector.h:456
int find_last_unset() const
Definition SmallBitVector.h:262
bool operator[](unsigned Idx) const
Definition SmallBitVector.h:461
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
Definition SmallBitVector.h:230
void push_back(bool Val)
Definition SmallBitVector.h:479
SmallBitVector & set()
Definition SmallBitVector.h:366
int find_last() const
Definition SmallBitVector.h:240
void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
Clear any bits in this vector that are set in Mask.
Definition SmallBitVector.h:661
bool test(const SmallBitVector &RHS) const
Check if (This - RHS) is non-zero.
Definition SmallBitVector.h:557
SmallBitVector & reset(unsigned I, unsigned E)
Efficiently reset a range of bits in [I, E)
Definition SmallBitVector.h:419
void invalid()
Definition SmallBitVector.h:686
void swap(SmallBitVector &RHS)
Definition SmallBitVector.h:646
void reserve(unsigned N)
Definition SmallBitVector.h:348
int find_prev(unsigned PriorTo) const
find_prev - Returns the index of the first set bit that precedes the the bit at PriorTo.
Definition SmallBitVector.h:308
SmallBitVector & set(unsigned I, unsigned E)
Efficiently set a range of bits in [I, E)
Definition SmallBitVector.h:387
SmallBitVector(SmallBitVector &&RHS)
Definition SmallBitVector.h:163
const_set_bits_iterator set_iterator
Definition SmallBitVector.h:173
bool test(unsigned Idx) const
Definition SmallBitVector.h:474
SmallBitVector()=default
Creates an empty bitvector.
SmallBitVector & operator&=(const SmallBitVector &RHS)
Definition SmallBitVector.h:525
void setBitsInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
Add '1' bits from Mask to this vector.
Definition SmallBitVector.h:652
bool back() const
Return the last element in the vector.
Definition SmallBitVector.h:469
const SmallBitVector & operator=(SmallBitVector &&RHS)
Definition SmallBitVector.h:638
SmallBitVector(unsigned s, bool t=false)
Creates a bitvector of specified number of bits.
Definition SmallBitVector.h:148
iterator_range< const_set_bits_iterator > set_bits() const
Definition SmallBitVector.h:183
SmallBitVector(const SmallBitVector &RHS)
SmallBitVector copy ctor.
Definition SmallBitVector.h:156
void clear()
Clear all bits.
Definition SmallBitVector.h:325
bool subsetOf(const SmallBitVector &RHS) const
Check if This is a subset of RHS.
Definition SmallBitVector.h:576
SmallBitVector & operator<<=(unsigned N)
Definition SmallBitVector.h:604
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
Definition SmallBitVector.h:277
SmallBitVector & reset(const SmallBitVector &RHS)
Reset bits that are set in RHS. Same as *this &= ~RHS.
Definition SmallBitVector.h:542
SmallBitVector & reset(unsigned Idx)
Definition SmallBitVector.h:410
uintptr_t size_type
Definition SmallBitVector.h:64
const SmallBitVector & operator=(const SmallBitVector &RHS)
Definition SmallBitVector.h:621
const_set_bits_iterator_impl< SmallBitVector > const_set_bits_iterator
Definition SmallBitVector.h:172
bool all() const
Returns true if all bits are set.
Definition SmallBitVector.h:216
bool operator==(const SmallBitVector &RHS) const
Definition SmallBitVector.h:503
ArrayRef< uintptr_t > getData(uintptr_t &Store) const
Definition SmallBitVector.h:692
SmallBitVector & operator>>=(unsigned N)
Definition SmallBitVector.h:612
int find_first_unset() const
Returns the index of the first unset bit, -1 if all of the bits are set.
Definition SmallBitVector.h:251
size_type size() const
Returns the number of bits in this bitvector.
Definition SmallBitVector.h:195
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
Definition SmallBitVector.h:332
bool any() const
Returns true if any bit is set.
Definition SmallBitVector.h:209
void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
Add a bit to this vector for every '0' bit in Mask.
Definition SmallBitVector.h:670
bool empty() const
Tests whether there are no bits in this bitvector.
Definition SmallBitVector.h:190
~SmallBitVector()
Definition SmallBitVector.h:167
bool isInvalid() const
Definition SmallBitVector.h:690
const_set_bits_iterator set_bits_end() const
Definition SmallBitVector.h:179
bool isSmall() const
Definition SmallBitVector.h:187
SmallBitVector & flip(unsigned Idx)
Definition SmallBitVector.h:442
void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
Clear a bit in this vector for every '0' bit in Mask.
Definition SmallBitVector.h:679
SmallBitVector & operator|=(const SmallBitVector &RHS)
Definition SmallBitVector.h:578
size_type count() const
Returns the number of bits which are set.
Definition SmallBitVector.h:200
bool anyCommon(const SmallBitVector &RHS) const
Test if any common bits are set.
Definition SmallBitVector.h:490
int find_next_unset(unsigned Prev) const
Returns the index of the next unset bit following the "Prev" bit.
Definition SmallBitVector.h:291
const_set_bits_iterator set_bits_begin() const
Definition SmallBitVector.h:175
void pop_back()
Pop one bit from the end of the vector.
Definition SmallBitVector.h:484
SmallBitVector & set(unsigned Idx)
Definition SmallBitVector.h:374
SmallBitVector & reset()
Definition SmallBitVector.h:402
SmallBitVector operator~() const
Definition SmallBitVector.h:451
bool none() const
Returns true if none of the bits are set.
Definition SmallBitVector.h:223
SmallBitVector & operator^=(const SmallBitVector &RHS)
Definition SmallBitVector.h:591
bool operator!=(const SmallBitVector &RHS) const
Definition SmallBitVector.h:519
ForwardIterator for the bits that are set.
A range adaptor for a pair of iterators.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This is an optimization pass for GlobalISel generic memory operations.
APInt operator&(APInt a, const APInt &b)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
APInt operator^(APInt a, const APInt &b)
int countl_one(T Value)
Count the number of ones from the most significant bit to the first zero bit.
APInt operator|(APInt a, const APInt &b)
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static SmallBitVector getTombstoneKey()
Definition SmallBitVector.h:738
static SmallBitVector getEmptyKey()
Definition SmallBitVector.h:737
static unsigned getHashValue(const SmallBitVector &V)
Definition SmallBitVector.h:743
static bool isEqual(const SmallBitVector &LHS, const SmallBitVector &RHS)
Definition SmallBitVector.h:749
An information struct used to provide DenseMap with the various necessary components for a given valu...