1 //===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements the SmallBitVector class. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_ADT_SMALLBITVECTOR_H 15 #define LLVM_ADT_SMALLBITVECTOR_H 16 17 #include "llvm/ADT/BitVector.h" 18 #include "llvm/ADT/iterator_range.h" 19 #include "llvm/Support/MathExtras.h" 20 #include <algorithm> 21 #include <cassert> 22 #include <climits> 23 #include <cstddef> 24 #include <cstdint> 25 #include <limits> 26 #include <utility> 27 28 namespace llvm { 29 30 /// This is a 'bitvector' (really, a variable-sized bit array), optimized for 31 /// the case when the array is small. It contains one pointer-sized field, which 32 /// is directly used as a plain collection of bits when possible, or as a 33 /// pointer to a larger heap-allocated array when necessary. This allows normal 34 /// "small" cases to be fast without losing generality for large inputs. 35 class SmallBitVector { 36 // TODO: In "large" mode, a pointer to a BitVector is used, leading to an 37 // unnecessary level of indirection. It would be more efficient to use a 38 // pointer to memory containing size, allocation size, and the array of bits. 39 uintptr_t X = 1; 40 41 enum { 42 // The number of bits in this class. 43 NumBaseBits = sizeof(uintptr_t) * CHAR_BIT, 44 45 // One bit is used to discriminate between small and large mode. The 46 // remaining bits are used for the small-mode representation. 47 SmallNumRawBits = NumBaseBits - 1, 48 49 // A few more bits are used to store the size of the bit set in small mode. 50 // Theoretically this is a ceil-log2. These bits are encoded in the most 51 // significant bits of the raw bits. 52 SmallNumSizeBits = (NumBaseBits == 32 ? 5 : 53 NumBaseBits == 64 ? 6 : 54 SmallNumRawBits), 55 56 // The remaining bits are used to store the actual set in small mode. 57 SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits 58 }; 59 60 static_assert(NumBaseBits == 64 || NumBaseBits == 32, 61 "Unsupported word size"); 62 63 public: 64 using size_type = uintptr_t; 65 66 // Encapsulation of a single bit. 67 class reference { 68 SmallBitVector &TheVector; 69 unsigned BitPos; 70 71 public: reference(SmallBitVector & b,unsigned Idx)72 reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {} 73 74 reference(const reference&) = default; 75 76 reference& operator=(reference t) { 77 *this = bool(t); 78 return *this; 79 } 80 81 reference& operator=(bool t) { 82 if (t) 83 TheVector.set(BitPos); 84 else 85 TheVector.reset(BitPos); 86 return *this; 87 } 88 89 operator bool() const { 90 return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos); 91 } 92 }; 93 94 private: getPointer()95 BitVector *getPointer() const { 96 assert(!isSmall()); 97 return reinterpret_cast<BitVector *>(X); 98 } 99 switchToSmall(uintptr_t NewSmallBits,size_type NewSize)100 void switchToSmall(uintptr_t NewSmallBits, size_type NewSize) { 101 X = 1; 102 setSmallSize(NewSize); 103 setSmallBits(NewSmallBits); 104 } 105 switchToLarge(BitVector * BV)106 void switchToLarge(BitVector *BV) { 107 X = reinterpret_cast<uintptr_t>(BV); 108 assert(!isSmall() && "Tried to use an unaligned pointer"); 109 } 110 111 // Return all the bits used for the "small" representation; this includes 112 // bits for the size as well as the element bits. getSmallRawBits()113 uintptr_t getSmallRawBits() const { 114 assert(isSmall()); 115 return X >> 1; 116 } 117 setSmallRawBits(uintptr_t NewRawBits)118 void setSmallRawBits(uintptr_t NewRawBits) { 119 assert(isSmall()); 120 X = (NewRawBits << 1) | uintptr_t(1); 121 } 122 123 // Return the size. getSmallSize()124 size_type getSmallSize() const { 125 return getSmallRawBits() >> SmallNumDataBits; 126 } 127 setSmallSize(size_type Size)128 void setSmallSize(size_type Size) { 129 setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits)); 130 } 131 132 // Return the element bits. getSmallBits()133 uintptr_t getSmallBits() const { 134 return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize()); 135 } 136 setSmallBits(uintptr_t NewBits)137 void setSmallBits(uintptr_t NewBits) { 138 setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) | 139 (getSmallSize() << SmallNumDataBits)); 140 } 141 142 public: 143 /// Creates an empty bitvector. 144 SmallBitVector() = default; 145 146 /// Creates a bitvector of specified number of bits. All bits are initialized 147 /// to the specified value. 148 explicit SmallBitVector(unsigned s, bool t = false) { 149 if (s <= SmallNumDataBits) 150 switchToSmall(t ? ~uintptr_t(0) : 0, s); 151 else 152 switchToLarge(new BitVector(s, t)); 153 } 154 155 /// SmallBitVector copy ctor. SmallBitVector(const SmallBitVector & RHS)156 SmallBitVector(const SmallBitVector &RHS) { 157 if (RHS.isSmall()) 158 X = RHS.X; 159 else 160 switchToLarge(new BitVector(*RHS.getPointer())); 161 } 162 SmallBitVector(SmallBitVector && RHS)163 SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { 164 RHS.X = 1; 165 } 166 ~SmallBitVector()167 ~SmallBitVector() { 168 if (!isSmall()) 169 delete getPointer(); 170 } 171 172 using const_set_bits_iterator = const_set_bits_iterator_impl<SmallBitVector>; 173 using set_iterator = const_set_bits_iterator; 174 set_bits_begin()175 const_set_bits_iterator set_bits_begin() const { 176 return const_set_bits_iterator(*this); 177 } 178 set_bits_end()179 const_set_bits_iterator set_bits_end() const { 180 return const_set_bits_iterator(*this, -1); 181 } 182 set_bits()183 iterator_range<const_set_bits_iterator> set_bits() const { 184 return make_range(set_bits_begin(), set_bits_end()); 185 } 186 isSmall()187 bool isSmall() const { return X & uintptr_t(1); } 188 189 /// Tests whether there are no bits in this bitvector. empty()190 bool empty() const { 191 return isSmall() ? getSmallSize() == 0 : getPointer()->empty(); 192 } 193 194 /// Returns the number of bits in this bitvector. size()195 size_type size() const { 196 return isSmall() ? getSmallSize() : getPointer()->size(); 197 } 198 199 /// Returns the number of bits which are set. count()200 size_type count() const { 201 if (isSmall()) { 202 uintptr_t Bits = getSmallBits(); 203 return llvm::popcount(Bits); 204 } 205 return getPointer()->count(); 206 } 207 208 /// Returns true if any bit is set. any()209 bool any() const { 210 if (isSmall()) 211 return getSmallBits() != 0; 212 return getPointer()->any(); 213 } 214 215 /// Returns true if all bits are set. all()216 bool all() const { 217 if (isSmall()) 218 return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1; 219 return getPointer()->all(); 220 } 221 222 /// Returns true if none of the bits are set. none()223 bool none() const { 224 if (isSmall()) 225 return getSmallBits() == 0; 226 return getPointer()->none(); 227 } 228 229 /// Returns the index of the first set bit, -1 if none of the bits are set. find_first()230 int find_first() const { 231 if (isSmall()) { 232 uintptr_t Bits = getSmallBits(); 233 if (Bits == 0) 234 return -1; 235 return llvm::countr_zero(Bits); 236 } 237 return getPointer()->find_first(); 238 } 239 find_last()240 int find_last() const { 241 if (isSmall()) { 242 uintptr_t Bits = getSmallBits(); 243 if (Bits == 0) 244 return -1; 245 return NumBaseBits - llvm::countl_zero(Bits) - 1; 246 } 247 return getPointer()->find_last(); 248 } 249 250 /// Returns the index of the first unset bit, -1 if all of the bits are set. find_first_unset()251 int find_first_unset() const { 252 if (isSmall()) { 253 if (count() == getSmallSize()) 254 return -1; 255 256 uintptr_t Bits = getSmallBits(); 257 return llvm::countr_one(Bits); 258 } 259 return getPointer()->find_first_unset(); 260 } 261 find_last_unset()262 int find_last_unset() const { 263 if (isSmall()) { 264 if (count() == getSmallSize()) 265 return -1; 266 267 uintptr_t Bits = getSmallBits(); 268 // Set unused bits. 269 Bits |= ~uintptr_t(0) << getSmallSize(); 270 return NumBaseBits - llvm::countl_one(Bits) - 1; 271 } 272 return getPointer()->find_last_unset(); 273 } 274 275 /// Returns the index of the next set bit following the "Prev" bit. 276 /// Returns -1 if the next set bit is not found. find_next(unsigned Prev)277 int find_next(unsigned Prev) const { 278 if (isSmall()) { 279 uintptr_t Bits = getSmallBits(); 280 // Mask off previous bits. 281 Bits &= ~uintptr_t(0) << (Prev + 1); 282 if (Bits == 0 || Prev + 1 >= getSmallSize()) 283 return -1; 284 return llvm::countr_zero(Bits); 285 } 286 return getPointer()->find_next(Prev); 287 } 288 289 /// Returns the index of the next unset bit following the "Prev" bit. 290 /// Returns -1 if the next unset bit is not found. find_next_unset(unsigned Prev)291 int find_next_unset(unsigned Prev) const { 292 if (isSmall()) { 293 uintptr_t Bits = getSmallBits(); 294 // Mask in previous bits. 295 Bits |= (uintptr_t(1) << (Prev + 1)) - 1; 296 // Mask in unused bits. 297 Bits |= ~uintptr_t(0) << getSmallSize(); 298 299 if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize()) 300 return -1; 301 return llvm::countr_one(Bits); 302 } 303 return getPointer()->find_next_unset(Prev); 304 } 305 306 /// find_prev - Returns the index of the first set bit that precedes the 307 /// the bit at \p PriorTo. Returns -1 if all previous bits are unset. find_prev(unsigned PriorTo)308 int find_prev(unsigned PriorTo) const { 309 if (isSmall()) { 310 if (PriorTo == 0) 311 return -1; 312 313 --PriorTo; 314 uintptr_t Bits = getSmallBits(); 315 Bits &= maskTrailingOnes<uintptr_t>(PriorTo + 1); 316 if (Bits == 0) 317 return -1; 318 319 return NumBaseBits - llvm::countl_zero(Bits) - 1; 320 } 321 return getPointer()->find_prev(PriorTo); 322 } 323 324 /// Clear all bits. clear()325 void clear() { 326 if (!isSmall()) 327 delete getPointer(); 328 switchToSmall(0, 0); 329 } 330 331 /// Grow or shrink the bitvector. 332 void resize(unsigned N, bool t = false) { 333 if (!isSmall()) { 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 { 340 BitVector *BV = new BitVector(N, t); 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 reserve(unsigned N)348 void reserve(unsigned N) { 349 if (isSmall()) { 350 if (N > SmallNumDataBits) { 351 uintptr_t OldBits = getSmallRawBits(); 352 size_type SmallSize = getSmallSize(); 353 BitVector *BV = new BitVector(SmallSize); 354 for (size_type I = 0; I < SmallSize; ++I) 355 if ((OldBits >> I) & 1) 356 BV->set(I); 357 BV->reserve(N); 358 switchToLarge(BV); 359 } 360 } else { 361 getPointer()->reserve(N); 362 } 363 } 364 365 // Set, reset, flip set()366 SmallBitVector &set() { 367 if (isSmall()) 368 setSmallBits(~uintptr_t(0)); 369 else 370 getPointer()->set(); 371 return *this; 372 } 373 set(unsigned Idx)374 SmallBitVector &set(unsigned Idx) { 375 if (isSmall()) { 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 /// Efficiently set a range of bits in [I, E) set(unsigned I,unsigned E)387 SmallBitVector &set(unsigned I, unsigned E) { 388 assert(I <= E && "Attempted to set backwards range!"); 389 assert(E <= size() && "Attempted to set out-of-bounds range!"); 390 if (I == E) return *this; 391 if (isSmall()) { 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 { 397 getPointer()->set(I, E); 398 } 399 return *this; 400 } 401 reset()402 SmallBitVector &reset() { 403 if (isSmall()) 404 setSmallBits(0); 405 else 406 getPointer()->reset(); 407 return *this; 408 } 409 reset(unsigned Idx)410 SmallBitVector &reset(unsigned Idx) { 411 if (isSmall()) 412 setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx)); 413 else 414 getPointer()->reset(Idx); 415 return *this; 416 } 417 418 /// Efficiently reset a range of bits in [I, E) reset(unsigned I,unsigned E)419 SmallBitVector &reset(unsigned I, unsigned E) { 420 assert(I <= E && "Attempted to reset backwards range!"); 421 assert(E <= size() && "Attempted to reset out-of-bounds range!"); 422 if (I == E) return *this; 423 if (isSmall()) { 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 flip()434 SmallBitVector &flip() { 435 if (isSmall()) 436 setSmallBits(~getSmallBits()); 437 else 438 getPointer()->flip(); 439 return *this; 440 } 441 flip(unsigned Idx)442 SmallBitVector &flip(unsigned Idx) { 443 if (isSmall()) 444 setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx)); 445 else 446 getPointer()->flip(Idx); 447 return *this; 448 } 449 450 // No argument flip. 451 SmallBitVector operator~() const { 452 return SmallBitVector(*this).flip(); 453 } 454 455 // Indexing. 456 reference operator[](unsigned Idx) { 457 assert(Idx < size() && "Out-of-bounds Bit access."); 458 return reference(*this, Idx); 459 } 460 461 bool operator[](unsigned Idx) const { 462 assert(Idx < size() && "Out-of-bounds Bit access."); 463 if (isSmall()) 464 return ((getSmallBits() >> Idx) & 1) != 0; 465 return getPointer()->operator[](Idx); 466 } 467 468 /// Return the last element in the vector. back()469 bool back() const { 470 assert(!empty() && "Getting last element of empty vector."); 471 return (*this)[size() - 1]; 472 } 473 test(unsigned Idx)474 bool test(unsigned Idx) const { 475 return (*this)[Idx]; 476 } 477 478 // Push single bit to end of vector. push_back(bool Val)479 void push_back(bool Val) { 480 resize(size() + 1, Val); 481 } 482 483 /// Pop one bit from the end of the vector. pop_back()484 void pop_back() { 485 assert(!empty() && "Empty vector has no element to pop."); 486 resize(size() - 1); 487 } 488 489 /// Test if any common bits are set. anyCommon(const SmallBitVector & RHS)490 bool anyCommon(const SmallBitVector &RHS) const { 491 if (isSmall() && RHS.isSmall()) 492 return (getSmallBits() & RHS.getSmallBits()) != 0; 493 if (!isSmall() && !RHS.isSmall()) 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 // Comparison operators. 503 bool operator==(const SmallBitVector &RHS) const { 504 if (size() != RHS.size()) 505 return false; 506 if (isSmall() && RHS.isSmall()) 507 return getSmallBits() == RHS.getSmallBits(); 508 else if (!isSmall() && !RHS.isSmall()) 509 return *getPointer() == *RHS.getPointer(); 510 else { 511 for (size_type I = 0, E = size(); I != E; ++I) { 512 if ((*this)[I] != RHS[I]) 513 return false; 514 } 515 return true; 516 } 517 } 518 519 bool operator!=(const SmallBitVector &RHS) const { 520 return !(*this == RHS); 521 } 522 523 // Intersection, union, disjoint union. 524 // FIXME BitVector::operator&= does not resize the LHS but this does 525 SmallBitVector &operator&=(const SmallBitVector &RHS) { 526 resize(std::max(size(), RHS.size())); 527 if (isSmall() && RHS.isSmall()) 528 setSmallBits(getSmallBits() & RHS.getSmallBits()); 529 else if (!isSmall() && !RHS.isSmall()) 530 getPointer()->operator&=(*RHS.getPointer()); 531 else { 532 size_type I, E; 533 for (I = 0, E = std::min(size(), RHS.size()); I != E; ++I) 534 (*this)[I] = test(I) && RHS.test(I); 535 for (E = size(); I != E; ++I) 536 reset(I); 537 } 538 return *this; 539 } 540 541 /// Reset bits that are set in RHS. Same as *this &= ~RHS. reset(const SmallBitVector & RHS)542 SmallBitVector &reset(const SmallBitVector &RHS) { 543 if (isSmall() && RHS.isSmall()) 544 setSmallBits(getSmallBits() & ~RHS.getSmallBits()); 545 else if (!isSmall() && !RHS.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)) 550 reset(i); 551 552 return *this; 553 } 554 555 /// Check if (This - RHS) is zero. This is the same as reset(RHS) and any(). test(const SmallBitVector & RHS)556 bool test(const SmallBitVector &RHS) const { 557 if (isSmall() && RHS.isSmall()) 558 return (getSmallBits() & ~RHS.getSmallBits()) != 0; 559 if (!isSmall() && !RHS.isSmall()) 560 return getPointer()->test(*RHS.getPointer()); 561 562 unsigned i, e; 563 for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i) 564 if (test(i) && !RHS.test(i)) 565 return true; 566 567 for (e = size(); i != e; ++i) 568 if (test(i)) 569 return true; 570 571 return false; 572 } 573 574 SmallBitVector &operator|=(const SmallBitVector &RHS) { 575 resize(std::max(size(), RHS.size())); 576 if (isSmall() && RHS.isSmall()) 577 setSmallBits(getSmallBits() | RHS.getSmallBits()); 578 else if (!isSmall() && !RHS.isSmall()) 579 getPointer()->operator|=(*RHS.getPointer()); 580 else { 581 for (size_type I = 0, E = RHS.size(); I != E; ++I) 582 (*this)[I] = test(I) || RHS.test(I); 583 } 584 return *this; 585 } 586 587 SmallBitVector &operator^=(const SmallBitVector &RHS) { 588 resize(std::max(size(), RHS.size())); 589 if (isSmall() && RHS.isSmall()) 590 setSmallBits(getSmallBits() ^ RHS.getSmallBits()); 591 else if (!isSmall() && !RHS.isSmall()) 592 getPointer()->operator^=(*RHS.getPointer()); 593 else { 594 for (size_type I = 0, E = RHS.size(); I != E; ++I) 595 (*this)[I] = test(I) != RHS.test(I); 596 } 597 return *this; 598 } 599 600 SmallBitVector &operator<<=(unsigned N) { 601 if (isSmall()) 602 setSmallBits(getSmallBits() << N); 603 else 604 getPointer()->operator<<=(N); 605 return *this; 606 } 607 608 SmallBitVector &operator>>=(unsigned N) { 609 if (isSmall()) 610 setSmallBits(getSmallBits() >> N); 611 else 612 getPointer()->operator>>=(N); 613 return *this; 614 } 615 616 // Assignment operator. 617 const SmallBitVector &operator=(const SmallBitVector &RHS) { 618 if (isSmall()) { 619 if (RHS.isSmall()) 620 X = RHS.X; 621 else 622 switchToLarge(new BitVector(*RHS.getPointer())); 623 } else { 624 if (!RHS.isSmall()) 625 *getPointer() = *RHS.getPointer(); 626 else { 627 delete getPointer(); 628 X = RHS.X; 629 } 630 } 631 return *this; 632 } 633 634 const SmallBitVector &operator=(SmallBitVector &&RHS) { 635 if (this != &RHS) { 636 clear(); 637 swap(RHS); 638 } 639 return *this; 640 } 641 swap(SmallBitVector & RHS)642 void swap(SmallBitVector &RHS) { 643 std::swap(X, RHS.X); 644 } 645 646 /// Add '1' bits from Mask to this vector. Don't resize. 647 /// This computes "*this |= Mask". 648 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 649 if (isSmall()) 650 applyMask<true, false>(Mask, MaskWords); 651 else 652 getPointer()->setBitsInMask(Mask, MaskWords); 653 } 654 655 /// Clear any bits in this vector that are set in Mask. Don't resize. 656 /// This computes "*this &= ~Mask". 657 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 658 if (isSmall()) 659 applyMask<false, false>(Mask, MaskWords); 660 else 661 getPointer()->clearBitsInMask(Mask, MaskWords); 662 } 663 664 /// Add a bit to this vector for every '0' bit in Mask. Don't resize. 665 /// This computes "*this |= ~Mask". 666 void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 667 if (isSmall()) 668 applyMask<true, true>(Mask, MaskWords); 669 else 670 getPointer()->setBitsNotInMask(Mask, MaskWords); 671 } 672 673 /// Clear a bit in this vector for every '0' bit in Mask. Don't resize. 674 /// This computes "*this &= Mask". 675 void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 676 if (isSmall()) 677 applyMask<false, true>(Mask, MaskWords); 678 else 679 getPointer()->clearBitsNotInMask(Mask, MaskWords); 680 } 681 invalid()682 void invalid() { 683 assert(empty()); 684 X = (uintptr_t)-1; 685 } isInvalid()686 bool isInvalid() const { return X == (uintptr_t)-1; } 687 getData(uintptr_t & Store)688 ArrayRef<uintptr_t> getData(uintptr_t &Store) const { 689 if (!isSmall()) 690 return getPointer()->getData(); 691 Store = getSmallBits(); 692 return Store; 693 } 694 695 private: 696 template <bool AddBits, bool InvertMask> applyMask(const uint32_t * Mask,unsigned MaskWords)697 void applyMask(const uint32_t *Mask, unsigned MaskWords) { 698 assert(MaskWords <= sizeof(uintptr_t) && "Mask is larger than base!"); 699 uintptr_t M = Mask[0]; 700 if (NumBaseBits == 64) 701 M |= uint64_t(Mask[1]) << 32; 702 if (InvertMask) 703 M = ~M; 704 if (AddBits) 705 setSmallBits(getSmallBits() | M); 706 else 707 setSmallBits(getSmallBits() & ~M); 708 } 709 }; 710 711 inline SmallBitVector 712 operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) { 713 SmallBitVector Result(LHS); 714 Result &= RHS; 715 return Result; 716 } 717 718 inline SmallBitVector 719 operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) { 720 SmallBitVector Result(LHS); 721 Result |= RHS; 722 return Result; 723 } 724 725 inline SmallBitVector 726 operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) { 727 SmallBitVector Result(LHS); 728 Result ^= RHS; 729 return Result; 730 } 731 732 template <> struct DenseMapInfo<SmallBitVector> { 733 static inline SmallBitVector getEmptyKey() { return SmallBitVector(); } 734 static inline SmallBitVector getTombstoneKey() { 735 SmallBitVector V; 736 V.invalid(); 737 return V; 738 } 739 static unsigned getHashValue(const SmallBitVector &V) { 740 uintptr_t Store; 741 return DenseMapInfo< 742 std::pair<SmallBitVector::size_type, ArrayRef<uintptr_t>>>:: 743 getHashValue(std::make_pair(V.size(), V.getData(Store))); 744 } 745 static bool isEqual(const SmallBitVector &LHS, const SmallBitVector &RHS) { 746 if (LHS.isInvalid() || RHS.isInvalid()) 747 return LHS.isInvalid() == RHS.isInvalid(); 748 return LHS == RHS; 749 } 750 }; 751 } // end namespace llvm 752 753 namespace std { 754 755 /// Implement std::swap in terms of BitVector swap. 756 inline void 757 swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) { 758 LHS.swap(RHS); 759 } 760 761 } // end namespace std 762 763 #endif // LLVM_ADT_SMALLBITVECTOR_H 764