File indexing completed on 2026-05-10 08:43:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_ADT_BITVECTOR_H
0015 #define LLVM_ADT_BITVECTOR_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/DenseMapInfo.h"
0019 #include "llvm/ADT/iterator_range.h"
0020 #include "llvm/Support/MathExtras.h"
0021 #include <algorithm>
0022 #include <cassert>
0023 #include <climits>
0024 #include <cstdint>
0025 #include <cstdlib>
0026 #include <cstring>
0027 #include <iterator>
0028 #include <utility>
0029
0030 namespace llvm {
0031
0032
0033
0034 template <typename BitVectorT> class const_set_bits_iterator_impl {
0035 const BitVectorT &Parent;
0036 int Current = 0;
0037
0038 void advance() {
0039 assert(Current != -1 && "Trying to advance past end.");
0040 Current = Parent.find_next(Current);
0041 }
0042
0043 public:
0044 using iterator_category = std::forward_iterator_tag;
0045 using difference_type = std::ptrdiff_t;
0046 using value_type = int;
0047 using pointer = value_type*;
0048 using reference = value_type&;
0049
0050 const_set_bits_iterator_impl(const BitVectorT &Parent, int Current)
0051 : Parent(Parent), Current(Current) {}
0052 explicit const_set_bits_iterator_impl(const BitVectorT &Parent)
0053 : const_set_bits_iterator_impl(Parent, Parent.find_first()) {}
0054 const_set_bits_iterator_impl(const const_set_bits_iterator_impl &) = default;
0055
0056 const_set_bits_iterator_impl operator++(int) {
0057 auto Prev = *this;
0058 advance();
0059 return Prev;
0060 }
0061
0062 const_set_bits_iterator_impl &operator++() {
0063 advance();
0064 return *this;
0065 }
0066
0067 unsigned operator*() const { return Current; }
0068
0069 bool operator==(const const_set_bits_iterator_impl &Other) const {
0070 assert(&Parent == &Other.Parent &&
0071 "Comparing iterators from different BitVectors");
0072 return Current == Other.Current;
0073 }
0074
0075 bool operator!=(const const_set_bits_iterator_impl &Other) const {
0076 assert(&Parent == &Other.Parent &&
0077 "Comparing iterators from different BitVectors");
0078 return Current != Other.Current;
0079 }
0080 };
0081
0082 class BitVector {
0083 typedef uintptr_t BitWord;
0084
0085 enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
0086
0087 static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32,
0088 "Unsupported word size");
0089
0090 using Storage = SmallVector<BitWord>;
0091
0092 Storage Bits;
0093 unsigned Size = 0;
0094
0095 public:
0096 using size_type = unsigned;
0097
0098
0099 class reference {
0100
0101 BitWord *WordRef;
0102 unsigned BitPos;
0103
0104 public:
0105 reference(BitVector &b, unsigned Idx) {
0106 WordRef = &b.Bits[Idx / BITWORD_SIZE];
0107 BitPos = Idx % BITWORD_SIZE;
0108 }
0109
0110 reference() = delete;
0111 reference(const reference&) = default;
0112
0113 reference &operator=(reference t) {
0114 *this = bool(t);
0115 return *this;
0116 }
0117
0118 reference& operator=(bool t) {
0119 if (t)
0120 *WordRef |= BitWord(1) << BitPos;
0121 else
0122 *WordRef &= ~(BitWord(1) << BitPos);
0123 return *this;
0124 }
0125
0126 operator bool() const {
0127 return ((*WordRef) & (BitWord(1) << BitPos)) != 0;
0128 }
0129 };
0130
0131 typedef const_set_bits_iterator_impl<BitVector> const_set_bits_iterator;
0132 typedef const_set_bits_iterator set_iterator;
0133
0134 const_set_bits_iterator set_bits_begin() const {
0135 return const_set_bits_iterator(*this);
0136 }
0137 const_set_bits_iterator set_bits_end() const {
0138 return const_set_bits_iterator(*this, -1);
0139 }
0140 iterator_range<const_set_bits_iterator> set_bits() const {
0141 return make_range(set_bits_begin(), set_bits_end());
0142 }
0143
0144
0145 BitVector() = default;
0146
0147
0148
0149 explicit BitVector(unsigned s, bool t = false)
0150 : Bits(NumBitWords(s), 0 - (BitWord)t), Size(s) {
0151 if (t)
0152 clear_unused_bits();
0153 }
0154
0155
0156 bool empty() const { return Size == 0; }
0157
0158
0159 size_type size() const { return Size; }
0160
0161
0162 size_type count() const {
0163 unsigned NumBits = 0;
0164 for (auto Bit : Bits)
0165 NumBits += llvm::popcount(Bit);
0166 return NumBits;
0167 }
0168
0169
0170 bool any() const {
0171 return any_of(Bits, [](BitWord Bit) { return Bit != 0; });
0172 }
0173
0174
0175 bool all() const {
0176 for (unsigned i = 0; i < Size / BITWORD_SIZE; ++i)
0177 if (Bits[i] != ~BitWord(0))
0178 return false;
0179
0180
0181 if (unsigned Remainder = Size % BITWORD_SIZE)
0182 return Bits[Size / BITWORD_SIZE] == (BitWord(1) << Remainder) - 1;
0183
0184 return true;
0185 }
0186
0187
0188 bool none() const {
0189 return !any();
0190 }
0191
0192
0193
0194
0195 int find_first_in(unsigned Begin, unsigned End, bool Set = true) const {
0196 assert(Begin <= End && End <= Size);
0197 if (Begin == End)
0198 return -1;
0199
0200 unsigned FirstWord = Begin / BITWORD_SIZE;
0201 unsigned LastWord = (End - 1) / BITWORD_SIZE;
0202
0203
0204
0205
0206
0207
0208 for (unsigned i = FirstWord; i <= LastWord; ++i) {
0209 BitWord Copy = Bits[i];
0210 if (!Set)
0211 Copy = ~Copy;
0212
0213 if (i == FirstWord) {
0214 unsigned FirstBit = Begin % BITWORD_SIZE;
0215 Copy &= maskTrailingZeros<BitWord>(FirstBit);
0216 }
0217
0218 if (i == LastWord) {
0219 unsigned LastBit = (End - 1) % BITWORD_SIZE;
0220 Copy &= maskTrailingOnes<BitWord>(LastBit + 1);
0221 }
0222 if (Copy != 0)
0223 return i * BITWORD_SIZE + llvm::countr_zero(Copy);
0224 }
0225 return -1;
0226 }
0227
0228
0229
0230 int find_last_in(unsigned Begin, unsigned End) const {
0231 assert(Begin <= End && End <= Size);
0232 if (Begin == End)
0233 return -1;
0234
0235 unsigned LastWord = (End - 1) / BITWORD_SIZE;
0236 unsigned FirstWord = Begin / BITWORD_SIZE;
0237
0238 for (unsigned i = LastWord + 1; i >= FirstWord + 1; --i) {
0239 unsigned CurrentWord = i - 1;
0240
0241 BitWord Copy = Bits[CurrentWord];
0242 if (CurrentWord == LastWord) {
0243 unsigned LastBit = (End - 1) % BITWORD_SIZE;
0244 Copy &= maskTrailingOnes<BitWord>(LastBit + 1);
0245 }
0246
0247 if (CurrentWord == FirstWord) {
0248 unsigned FirstBit = Begin % BITWORD_SIZE;
0249 Copy &= maskTrailingZeros<BitWord>(FirstBit);
0250 }
0251
0252 if (Copy != 0)
0253 return (CurrentWord + 1) * BITWORD_SIZE - llvm::countl_zero(Copy) - 1;
0254 }
0255
0256 return -1;
0257 }
0258
0259
0260
0261 int find_first_unset_in(unsigned Begin, unsigned End) const {
0262 return find_first_in(Begin, End, false);
0263 }
0264
0265
0266
0267 int find_last_unset_in(unsigned Begin, unsigned End) const {
0268 assert(Begin <= End && End <= Size);
0269 if (Begin == End)
0270 return -1;
0271
0272 unsigned LastWord = (End - 1) / BITWORD_SIZE;
0273 unsigned FirstWord = Begin / BITWORD_SIZE;
0274
0275 for (unsigned i = LastWord + 1; i >= FirstWord + 1; --i) {
0276 unsigned CurrentWord = i - 1;
0277
0278 BitWord Copy = Bits[CurrentWord];
0279 if (CurrentWord == LastWord) {
0280 unsigned LastBit = (End - 1) % BITWORD_SIZE;
0281 Copy |= maskTrailingZeros<BitWord>(LastBit + 1);
0282 }
0283
0284 if (CurrentWord == FirstWord) {
0285 unsigned FirstBit = Begin % BITWORD_SIZE;
0286 Copy |= maskTrailingOnes<BitWord>(FirstBit);
0287 }
0288
0289 if (Copy != ~BitWord(0)) {
0290 unsigned Result =
0291 (CurrentWord + 1) * BITWORD_SIZE - llvm::countl_one(Copy) - 1;
0292 return Result < Size ? Result : -1;
0293 }
0294 }
0295 return -1;
0296 }
0297
0298
0299
0300 int find_first() const { return find_first_in(0, Size); }
0301
0302
0303
0304 int find_last() const { return find_last_in(0, Size); }
0305
0306
0307
0308 int find_next(unsigned Prev) const { return find_first_in(Prev + 1, Size); }
0309
0310
0311
0312 int find_prev(unsigned PriorTo) const { return find_last_in(0, PriorTo); }
0313
0314
0315
0316 int find_first_unset() const { return find_first_unset_in(0, Size); }
0317
0318
0319
0320 int find_next_unset(unsigned Prev) const {
0321 return find_first_unset_in(Prev + 1, Size);
0322 }
0323
0324
0325
0326 int find_last_unset() const { return find_last_unset_in(0, Size); }
0327
0328
0329
0330 int find_prev_unset(unsigned PriorTo) {
0331 return find_last_unset_in(0, PriorTo);
0332 }
0333
0334
0335 void clear() {
0336 Size = 0;
0337 Bits.clear();
0338 }
0339
0340
0341 void resize(unsigned N, bool t = false) {
0342 set_unused_bits(t);
0343 Size = N;
0344 Bits.resize(NumBitWords(N), 0 - BitWord(t));
0345 clear_unused_bits();
0346 }
0347
0348 void reserve(unsigned N) { Bits.reserve(NumBitWords(N)); }
0349
0350
0351 BitVector &set() {
0352 init_words(true);
0353 clear_unused_bits();
0354 return *this;
0355 }
0356
0357 BitVector &set(unsigned Idx) {
0358 assert(Idx < Size && "access in bound");
0359 Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
0360 return *this;
0361 }
0362
0363
0364 BitVector &set(unsigned I, unsigned E) {
0365 assert(I <= E && "Attempted to set backwards range!");
0366 assert(E <= size() && "Attempted to set out-of-bounds range!");
0367
0368 if (I == E) return *this;
0369
0370 if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
0371 BitWord EMask = BitWord(1) << (E % BITWORD_SIZE);
0372 BitWord IMask = BitWord(1) << (I % BITWORD_SIZE);
0373 BitWord Mask = EMask - IMask;
0374 Bits[I / BITWORD_SIZE] |= Mask;
0375 return *this;
0376 }
0377
0378 BitWord PrefixMask = ~BitWord(0) << (I % BITWORD_SIZE);
0379 Bits[I / BITWORD_SIZE] |= PrefixMask;
0380 I = alignTo(I, BITWORD_SIZE);
0381
0382 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
0383 Bits[I / BITWORD_SIZE] = ~BitWord(0);
0384
0385 BitWord PostfixMask = (BitWord(1) << (E % BITWORD_SIZE)) - 1;
0386 if (I < E)
0387 Bits[I / BITWORD_SIZE] |= PostfixMask;
0388
0389 return *this;
0390 }
0391
0392 BitVector &reset() {
0393 init_words(false);
0394 return *this;
0395 }
0396
0397 BitVector &reset(unsigned Idx) {
0398 Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
0399 return *this;
0400 }
0401
0402
0403 BitVector &reset(unsigned I, unsigned E) {
0404 assert(I <= E && "Attempted to reset backwards range!");
0405 assert(E <= size() && "Attempted to reset out-of-bounds range!");
0406
0407 if (I == E) return *this;
0408
0409 if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
0410 BitWord EMask = BitWord(1) << (E % BITWORD_SIZE);
0411 BitWord IMask = BitWord(1) << (I % BITWORD_SIZE);
0412 BitWord Mask = EMask - IMask;
0413 Bits[I / BITWORD_SIZE] &= ~Mask;
0414 return *this;
0415 }
0416
0417 BitWord PrefixMask = ~BitWord(0) << (I % BITWORD_SIZE);
0418 Bits[I / BITWORD_SIZE] &= ~PrefixMask;
0419 I = alignTo(I, BITWORD_SIZE);
0420
0421 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
0422 Bits[I / BITWORD_SIZE] = BitWord(0);
0423
0424 BitWord PostfixMask = (BitWord(1) << (E % BITWORD_SIZE)) - 1;
0425 if (I < E)
0426 Bits[I / BITWORD_SIZE] &= ~PostfixMask;
0427
0428 return *this;
0429 }
0430
0431 BitVector &flip() {
0432 for (auto &Bit : Bits)
0433 Bit = ~Bit;
0434 clear_unused_bits();
0435 return *this;
0436 }
0437
0438 BitVector &flip(unsigned Idx) {
0439 Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
0440 return *this;
0441 }
0442
0443
0444 reference operator[](unsigned Idx) {
0445 assert (Idx < Size && "Out-of-bounds Bit access.");
0446 return reference(*this, Idx);
0447 }
0448
0449 bool operator[](unsigned Idx) const {
0450 assert (Idx < Size && "Out-of-bounds Bit access.");
0451 BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
0452 return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
0453 }
0454
0455
0456 bool back() const {
0457 assert(!empty() && "Getting last element of empty vector.");
0458 return (*this)[size() - 1];
0459 }
0460
0461 bool test(unsigned Idx) const {
0462 return (*this)[Idx];
0463 }
0464
0465
0466 void push_back(bool Val) {
0467 unsigned OldSize = Size;
0468 unsigned NewSize = Size + 1;
0469
0470
0471
0472 if (NewSize > getBitCapacity())
0473 resize(NewSize, false);
0474 else
0475 Size = NewSize;
0476
0477
0478 if (Val)
0479 set(OldSize);
0480 }
0481
0482
0483 void pop_back() {
0484 assert(!empty() && "Empty vector has no element to pop.");
0485 resize(size() - 1);
0486 }
0487
0488
0489 bool anyCommon(const BitVector &RHS) const {
0490 unsigned ThisWords = Bits.size();
0491 unsigned RHSWords = RHS.Bits.size();
0492 for (unsigned i = 0, e = std::min(ThisWords, RHSWords); i != e; ++i)
0493 if (Bits[i] & RHS.Bits[i])
0494 return true;
0495 return false;
0496 }
0497
0498
0499 bool operator==(const BitVector &RHS) const {
0500 if (size() != RHS.size())
0501 return false;
0502 unsigned NumWords = Bits.size();
0503 return std::equal(Bits.begin(), Bits.begin() + NumWords, RHS.Bits.begin());
0504 }
0505
0506 bool operator!=(const BitVector &RHS) const { return !(*this == RHS); }
0507
0508
0509 BitVector &operator&=(const BitVector &RHS) {
0510 unsigned ThisWords = Bits.size();
0511 unsigned RHSWords = RHS.Bits.size();
0512 unsigned i;
0513 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
0514 Bits[i] &= RHS.Bits[i];
0515
0516
0517
0518
0519 for (; i != ThisWords; ++i)
0520 Bits[i] = 0;
0521
0522 return *this;
0523 }
0524
0525
0526 BitVector &reset(const BitVector &RHS) {
0527 unsigned ThisWords = Bits.size();
0528 unsigned RHSWords = RHS.Bits.size();
0529 for (unsigned i = 0; i != std::min(ThisWords, RHSWords); ++i)
0530 Bits[i] &= ~RHS.Bits[i];
0531 return *this;
0532 }
0533
0534
0535
0536 bool test(const BitVector &RHS) const {
0537 unsigned ThisWords = Bits.size();
0538 unsigned RHSWords = RHS.Bits.size();
0539 unsigned i;
0540 for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
0541 if ((Bits[i] & ~RHS.Bits[i]) != 0)
0542 return true;
0543
0544 for (; i != ThisWords ; ++i)
0545 if (Bits[i] != 0)
0546 return true;
0547
0548 return false;
0549 }
0550
0551 template <class F, class... ArgTys>
0552 static BitVector &apply(F &&f, BitVector &Out, BitVector const &Arg,
0553 ArgTys const &...Args) {
0554 assert(llvm::all_of(
0555 std::initializer_list<unsigned>{Args.size()...},
0556 [&Arg](auto const &BV) { return Arg.size() == BV; }) &&
0557 "consistent sizes");
0558 Out.resize(Arg.size());
0559 for (size_type I = 0, E = Arg.Bits.size(); I != E; ++I)
0560 Out.Bits[I] = f(Arg.Bits[I], Args.Bits[I]...);
0561 Out.clear_unused_bits();
0562 return Out;
0563 }
0564
0565 BitVector &operator|=(const BitVector &RHS) {
0566 if (size() < RHS.size())
0567 resize(RHS.size());
0568 for (size_type I = 0, E = RHS.Bits.size(); I != E; ++I)
0569 Bits[I] |= RHS.Bits[I];
0570 return *this;
0571 }
0572
0573 BitVector &operator^=(const BitVector &RHS) {
0574 if (size() < RHS.size())
0575 resize(RHS.size());
0576 for (size_type I = 0, E = RHS.Bits.size(); I != E; ++I)
0577 Bits[I] ^= RHS.Bits[I];
0578 return *this;
0579 }
0580
0581 BitVector &operator>>=(unsigned N) {
0582 assert(N <= Size);
0583 if (LLVM_UNLIKELY(empty() || N == 0))
0584 return *this;
0585
0586 unsigned NumWords = Bits.size();
0587 assert(NumWords >= 1);
0588
0589 wordShr(N / BITWORD_SIZE);
0590
0591 unsigned BitDistance = N % BITWORD_SIZE;
0592 if (BitDistance == 0)
0593 return *this;
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617 const BitWord Mask = maskTrailingOnes<BitWord>(BitDistance);
0618 const unsigned LSH = BITWORD_SIZE - BitDistance;
0619
0620 for (unsigned I = 0; I < NumWords - 1; ++I) {
0621 Bits[I] >>= BitDistance;
0622 Bits[I] |= (Bits[I + 1] & Mask) << LSH;
0623 }
0624
0625 Bits[NumWords - 1] >>= BitDistance;
0626
0627 return *this;
0628 }
0629
0630 BitVector &operator<<=(unsigned N) {
0631 assert(N <= Size);
0632 if (LLVM_UNLIKELY(empty() || N == 0))
0633 return *this;
0634
0635 unsigned NumWords = Bits.size();
0636 assert(NumWords >= 1);
0637
0638 wordShl(N / BITWORD_SIZE);
0639
0640 unsigned BitDistance = N % BITWORD_SIZE;
0641 if (BitDistance == 0)
0642 return *this;
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667 const BitWord Mask = maskLeadingOnes<BitWord>(BitDistance);
0668 const unsigned RSH = BITWORD_SIZE - BitDistance;
0669
0670 for (int I = NumWords - 1; I > 0; --I) {
0671 Bits[I] <<= BitDistance;
0672 Bits[I] |= (Bits[I - 1] & Mask) >> RSH;
0673 }
0674 Bits[0] <<= BitDistance;
0675 clear_unused_bits();
0676
0677 return *this;
0678 }
0679
0680 void swap(BitVector &RHS) {
0681 std::swap(Bits, RHS.Bits);
0682 std::swap(Size, RHS.Size);
0683 }
0684
0685 void invalid() {
0686 assert(!Size && Bits.empty());
0687 Size = (unsigned)-1;
0688 }
0689 bool isInvalid() const { return Size == (unsigned)-1; }
0690
0691 ArrayRef<BitWord> getData() const { return {Bits.data(), Bits.size()}; }
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
0708 applyMask<true, false>(Mask, MaskWords);
0709 }
0710
0711
0712
0713 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
0714 applyMask<false, false>(Mask, MaskWords);
0715 }
0716
0717
0718
0719 void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
0720 applyMask<true, true>(Mask, MaskWords);
0721 }
0722
0723
0724
0725 void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
0726 applyMask<false, true>(Mask, MaskWords);
0727 }
0728
0729 private:
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744 void wordShl(uint32_t Count) {
0745 if (Count == 0)
0746 return;
0747
0748 uint32_t NumWords = Bits.size();
0749
0750
0751
0752
0753 std::copy(Bits.begin(), Bits.begin() + NumWords - Count,
0754 Bits.begin() + Count);
0755 std::fill(Bits.begin(), Bits.begin() + Count, 0);
0756 clear_unused_bits();
0757 }
0758
0759
0760
0761
0762 void wordShr(uint32_t Count) {
0763 if (Count == 0)
0764 return;
0765
0766 uint32_t NumWords = Bits.size();
0767
0768 std::copy(Bits.begin() + Count, Bits.begin() + NumWords, Bits.begin());
0769 std::fill(Bits.begin() + NumWords - Count, Bits.begin() + NumWords, 0);
0770 }
0771
0772 int next_unset_in_word(int WordIndex, BitWord Word) const {
0773 unsigned Result = WordIndex * BITWORD_SIZE + llvm::countr_one(Word);
0774 return Result < size() ? Result : -1;
0775 }
0776
0777 unsigned NumBitWords(unsigned S) const {
0778 return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
0779 }
0780
0781
0782 void set_unused_bits(bool t = true) {
0783
0784 if (unsigned ExtraBits = Size % BITWORD_SIZE) {
0785 BitWord ExtraBitMask = ~BitWord(0) << ExtraBits;
0786 if (t)
0787 Bits.back() |= ExtraBitMask;
0788 else
0789 Bits.back() &= ~ExtraBitMask;
0790 }
0791 }
0792
0793
0794 void clear_unused_bits() {
0795 set_unused_bits(false);
0796 }
0797
0798 void init_words(bool t) {
0799 std::fill(Bits.begin(), Bits.end(), 0 - (BitWord)t);
0800 }
0801
0802 template<bool AddBits, bool InvertMask>
0803 void applyMask(const uint32_t *Mask, unsigned MaskWords) {
0804 static_assert(BITWORD_SIZE % 32 == 0, "Unsupported BitWord size.");
0805 MaskWords = std::min(MaskWords, (size() + 31) / 32);
0806 const unsigned Scale = BITWORD_SIZE / 32;
0807 unsigned i;
0808 for (i = 0; MaskWords >= Scale; ++i, MaskWords -= Scale) {
0809 BitWord BW = Bits[i];
0810
0811 for (unsigned b = 0; b != BITWORD_SIZE; b += 32) {
0812 uint32_t M = *Mask++;
0813 if (InvertMask) M = ~M;
0814 if (AddBits) BW |= BitWord(M) << b;
0815 else BW &= ~(BitWord(M) << b);
0816 }
0817 Bits[i] = BW;
0818 }
0819 for (unsigned b = 0; MaskWords; b += 32, --MaskWords) {
0820 uint32_t M = *Mask++;
0821 if (InvertMask) M = ~M;
0822 if (AddBits) Bits[i] |= BitWord(M) << b;
0823 else Bits[i] &= ~(BitWord(M) << b);
0824 }
0825 if (AddBits)
0826 clear_unused_bits();
0827 }
0828
0829 public:
0830
0831 size_type getMemorySize() const { return Bits.size() * sizeof(BitWord); }
0832 size_type getBitCapacity() const { return Bits.size() * BITWORD_SIZE; }
0833 };
0834
0835 inline BitVector::size_type capacity_in_bytes(const BitVector &X) {
0836 return X.getMemorySize();
0837 }
0838
0839 template <> struct DenseMapInfo<BitVector> {
0840 static inline BitVector getEmptyKey() { return {}; }
0841 static inline BitVector getTombstoneKey() {
0842 BitVector V;
0843 V.invalid();
0844 return V;
0845 }
0846 static unsigned getHashValue(const BitVector &V) {
0847 return DenseMapInfo<std::pair<BitVector::size_type, ArrayRef<uintptr_t>>>::
0848 getHashValue(std::make_pair(V.size(), V.getData()));
0849 }
0850 static bool isEqual(const BitVector &LHS, const BitVector &RHS) {
0851 if (LHS.isInvalid() || RHS.isInvalid())
0852 return LHS.isInvalid() == RHS.isInvalid();
0853 return LHS == RHS;
0854 }
0855 };
0856 }
0857
0858 namespace std {
0859
0860 inline void swap(llvm::BitVector &LHS, llvm::BitVector &RHS) { LHS.swap(RHS); }
0861 }
0862
0863 #endif