LLVM API Documentation
00001 //===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the SmallBitVector class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_SMALLBITVECTOR_H 00015 #define LLVM_ADT_SMALLBITVECTOR_H 00016 00017 #include "llvm/ADT/BitVector.h" 00018 #include "llvm/Support/Compiler.h" 00019 #include "llvm/Support/MathExtras.h" 00020 #include <cassert> 00021 00022 namespace llvm { 00023 00024 /// SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array), 00025 /// optimized for the case when the array is small. It contains one 00026 /// pointer-sized field, which is directly used as a plain collection of bits 00027 /// when possible, or as a pointer to a larger heap-allocated array when 00028 /// necessary. This allows normal "small" cases to be fast without losing 00029 /// generality for large inputs. 00030 /// 00031 class SmallBitVector { 00032 // TODO: In "large" mode, a pointer to a BitVector is used, leading to an 00033 // unnecessary level of indirection. It would be more efficient to use a 00034 // pointer to memory containing size, allocation size, and the array of bits. 00035 uintptr_t X; 00036 00037 enum { 00038 // The number of bits in this class. 00039 NumBaseBits = sizeof(uintptr_t) * CHAR_BIT, 00040 00041 // One bit is used to discriminate between small and large mode. The 00042 // remaining bits are used for the small-mode representation. 00043 SmallNumRawBits = NumBaseBits - 1, 00044 00045 // A few more bits are used to store the size of the bit set in small mode. 00046 // Theoretically this is a ceil-log2. These bits are encoded in the most 00047 // significant bits of the raw bits. 00048 SmallNumSizeBits = (NumBaseBits == 32 ? 5 : 00049 NumBaseBits == 64 ? 6 : 00050 SmallNumRawBits), 00051 00052 // The remaining bits are used to store the actual set in small mode. 00053 SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits 00054 }; 00055 00056 public: 00057 typedef unsigned size_type; 00058 // Encapsulation of a single bit. 00059 class reference { 00060 SmallBitVector &TheVector; 00061 unsigned BitPos; 00062 00063 public: 00064 reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {} 00065 00066 reference& operator=(reference t) { 00067 *this = bool(t); 00068 return *this; 00069 } 00070 00071 reference& operator=(bool t) { 00072 if (t) 00073 TheVector.set(BitPos); 00074 else 00075 TheVector.reset(BitPos); 00076 return *this; 00077 } 00078 00079 operator bool() const { 00080 return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos); 00081 } 00082 }; 00083 00084 private: 00085 bool isSmall() const { 00086 return X & uintptr_t(1); 00087 } 00088 00089 BitVector *getPointer() const { 00090 assert(!isSmall()); 00091 return reinterpret_cast<BitVector *>(X); 00092 } 00093 00094 void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) { 00095 X = 1; 00096 setSmallSize(NewSize); 00097 setSmallBits(NewSmallBits); 00098 } 00099 00100 void switchToLarge(BitVector *BV) { 00101 X = reinterpret_cast<uintptr_t>(BV); 00102 assert(!isSmall() && "Tried to use an unaligned pointer"); 00103 } 00104 00105 // Return all the bits used for the "small" representation; this includes 00106 // bits for the size as well as the element bits. 00107 uintptr_t getSmallRawBits() const { 00108 assert(isSmall()); 00109 return X >> 1; 00110 } 00111 00112 void setSmallRawBits(uintptr_t NewRawBits) { 00113 assert(isSmall()); 00114 X = (NewRawBits << 1) | uintptr_t(1); 00115 } 00116 00117 // Return the size. 00118 size_t getSmallSize() const { 00119 return getSmallRawBits() >> SmallNumDataBits; 00120 } 00121 00122 void setSmallSize(size_t Size) { 00123 setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits)); 00124 } 00125 00126 // Return the element bits. 00127 uintptr_t getSmallBits() const { 00128 return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize()); 00129 } 00130 00131 void setSmallBits(uintptr_t NewBits) { 00132 setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) | 00133 (getSmallSize() << SmallNumDataBits)); 00134 } 00135 00136 public: 00137 /// SmallBitVector default ctor - Creates an empty bitvector. 00138 SmallBitVector() : X(1) {} 00139 00140 /// SmallBitVector ctor - Creates a bitvector of specified number of bits. All 00141 /// bits are initialized to the specified value. 00142 explicit SmallBitVector(unsigned s, bool t = false) { 00143 if (s <= SmallNumDataBits) 00144 switchToSmall(t ? ~uintptr_t(0) : 0, s); 00145 else 00146 switchToLarge(new BitVector(s, t)); 00147 } 00148 00149 /// SmallBitVector copy ctor. 00150 SmallBitVector(const SmallBitVector &RHS) { 00151 if (RHS.isSmall()) 00152 X = RHS.X; 00153 else 00154 switchToLarge(new BitVector(*RHS.getPointer())); 00155 } 00156 00157 SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { 00158 RHS.X = 1; 00159 } 00160 00161 ~SmallBitVector() { 00162 if (!isSmall()) 00163 delete getPointer(); 00164 } 00165 00166 /// empty - Tests whether there are no bits in this bitvector. 00167 bool empty() const { 00168 return isSmall() ? getSmallSize() == 0 : getPointer()->empty(); 00169 } 00170 00171 /// size - Returns the number of bits in this bitvector. 00172 size_t size() const { 00173 return isSmall() ? getSmallSize() : getPointer()->size(); 00174 } 00175 00176 /// count - Returns the number of bits which are set. 00177 size_type count() const { 00178 if (isSmall()) { 00179 uintptr_t Bits = getSmallBits(); 00180 if (NumBaseBits == 32) 00181 return CountPopulation_32(Bits); 00182 if (NumBaseBits == 64) 00183 return CountPopulation_64(Bits); 00184 llvm_unreachable("Unsupported!"); 00185 } 00186 return getPointer()->count(); 00187 } 00188 00189 /// any - Returns true if any bit is set. 00190 bool any() const { 00191 if (isSmall()) 00192 return getSmallBits() != 0; 00193 return getPointer()->any(); 00194 } 00195 00196 /// all - Returns true if all bits are set. 00197 bool all() const { 00198 if (isSmall()) 00199 return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1; 00200 return getPointer()->all(); 00201 } 00202 00203 /// none - Returns true if none of the bits are set. 00204 bool none() const { 00205 if (isSmall()) 00206 return getSmallBits() == 0; 00207 return getPointer()->none(); 00208 } 00209 00210 /// find_first - Returns the index of the first set bit, -1 if none 00211 /// of the bits are set. 00212 int find_first() const { 00213 if (isSmall()) { 00214 uintptr_t Bits = getSmallBits(); 00215 if (Bits == 0) 00216 return -1; 00217 if (NumBaseBits == 32) 00218 return countTrailingZeros(Bits); 00219 if (NumBaseBits == 64) 00220 return countTrailingZeros(Bits); 00221 llvm_unreachable("Unsupported!"); 00222 } 00223 return getPointer()->find_first(); 00224 } 00225 00226 /// find_next - Returns the index of the next set bit following the 00227 /// "Prev" bit. Returns -1 if the next set bit is not found. 00228 int find_next(unsigned Prev) const { 00229 if (isSmall()) { 00230 uintptr_t Bits = getSmallBits(); 00231 // Mask off previous bits. 00232 Bits &= ~uintptr_t(0) << (Prev + 1); 00233 if (Bits == 0 || Prev + 1 >= getSmallSize()) 00234 return -1; 00235 if (NumBaseBits == 32) 00236 return countTrailingZeros(Bits); 00237 if (NumBaseBits == 64) 00238 return countTrailingZeros(Bits); 00239 llvm_unreachable("Unsupported!"); 00240 } 00241 return getPointer()->find_next(Prev); 00242 } 00243 00244 /// clear - Clear all bits. 00245 void clear() { 00246 if (!isSmall()) 00247 delete getPointer(); 00248 switchToSmall(0, 0); 00249 } 00250 00251 /// resize - Grow or shrink the bitvector. 00252 void resize(unsigned N, bool t = false) { 00253 if (!isSmall()) { 00254 getPointer()->resize(N, t); 00255 } else if (SmallNumDataBits >= N) { 00256 uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0; 00257 setSmallSize(N); 00258 setSmallBits(NewBits | getSmallBits()); 00259 } else { 00260 BitVector *BV = new BitVector(N, t); 00261 uintptr_t OldBits = getSmallBits(); 00262 for (size_t i = 0, e = getSmallSize(); i != e; ++i) 00263 (*BV)[i] = (OldBits >> i) & 1; 00264 switchToLarge(BV); 00265 } 00266 } 00267 00268 void reserve(unsigned N) { 00269 if (isSmall()) { 00270 if (N > SmallNumDataBits) { 00271 uintptr_t OldBits = getSmallRawBits(); 00272 size_t SmallSize = getSmallSize(); 00273 BitVector *BV = new BitVector(SmallSize); 00274 for (size_t i = 0; i < SmallSize; ++i) 00275 if ((OldBits >> i) & 1) 00276 BV->set(i); 00277 BV->reserve(N); 00278 switchToLarge(BV); 00279 } 00280 } else { 00281 getPointer()->reserve(N); 00282 } 00283 } 00284 00285 // Set, reset, flip 00286 SmallBitVector &set() { 00287 if (isSmall()) 00288 setSmallBits(~uintptr_t(0)); 00289 else 00290 getPointer()->set(); 00291 return *this; 00292 } 00293 00294 SmallBitVector &set(unsigned Idx) { 00295 if (isSmall()) 00296 setSmallBits(getSmallBits() | (uintptr_t(1) << Idx)); 00297 else 00298 getPointer()->set(Idx); 00299 return *this; 00300 } 00301 00302 /// set - Efficiently set a range of bits in [I, E) 00303 SmallBitVector &set(unsigned I, unsigned E) { 00304 assert(I <= E && "Attempted to set backwards range!"); 00305 assert(E <= size() && "Attempted to set out-of-bounds range!"); 00306 if (I == E) return *this; 00307 if (isSmall()) { 00308 uintptr_t EMask = ((uintptr_t)1) << E; 00309 uintptr_t IMask = ((uintptr_t)1) << I; 00310 uintptr_t Mask = EMask - IMask; 00311 setSmallBits(getSmallBits() | Mask); 00312 } else 00313 getPointer()->set(I, E); 00314 return *this; 00315 } 00316 00317 SmallBitVector &reset() { 00318 if (isSmall()) 00319 setSmallBits(0); 00320 else 00321 getPointer()->reset(); 00322 return *this; 00323 } 00324 00325 SmallBitVector &reset(unsigned Idx) { 00326 if (isSmall()) 00327 setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx)); 00328 else 00329 getPointer()->reset(Idx); 00330 return *this; 00331 } 00332 00333 /// reset - Efficiently reset a range of bits in [I, E) 00334 SmallBitVector &reset(unsigned I, unsigned E) { 00335 assert(I <= E && "Attempted to reset backwards range!"); 00336 assert(E <= size() && "Attempted to reset out-of-bounds range!"); 00337 if (I == E) return *this; 00338 if (isSmall()) { 00339 uintptr_t EMask = ((uintptr_t)1) << E; 00340 uintptr_t IMask = ((uintptr_t)1) << I; 00341 uintptr_t Mask = EMask - IMask; 00342 setSmallBits(getSmallBits() & ~Mask); 00343 } else 00344 getPointer()->reset(I, E); 00345 return *this; 00346 } 00347 00348 SmallBitVector &flip() { 00349 if (isSmall()) 00350 setSmallBits(~getSmallBits()); 00351 else 00352 getPointer()->flip(); 00353 return *this; 00354 } 00355 00356 SmallBitVector &flip(unsigned Idx) { 00357 if (isSmall()) 00358 setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx)); 00359 else 00360 getPointer()->flip(Idx); 00361 return *this; 00362 } 00363 00364 // No argument flip. 00365 SmallBitVector operator~() const { 00366 return SmallBitVector(*this).flip(); 00367 } 00368 00369 // Indexing. 00370 reference operator[](unsigned Idx) { 00371 assert(Idx < size() && "Out-of-bounds Bit access."); 00372 return reference(*this, Idx); 00373 } 00374 00375 bool operator[](unsigned Idx) const { 00376 assert(Idx < size() && "Out-of-bounds Bit access."); 00377 if (isSmall()) 00378 return ((getSmallBits() >> Idx) & 1) != 0; 00379 return getPointer()->operator[](Idx); 00380 } 00381 00382 bool test(unsigned Idx) const { 00383 return (*this)[Idx]; 00384 } 00385 00386 /// Test if any common bits are set. 00387 bool anyCommon(const SmallBitVector &RHS) const { 00388 if (isSmall() && RHS.isSmall()) 00389 return (getSmallBits() & RHS.getSmallBits()) != 0; 00390 if (!isSmall() && !RHS.isSmall()) 00391 return getPointer()->anyCommon(*RHS.getPointer()); 00392 00393 for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i) 00394 if (test(i) && RHS.test(i)) 00395 return true; 00396 return false; 00397 } 00398 00399 // Comparison operators. 00400 bool operator==(const SmallBitVector &RHS) const { 00401 if (size() != RHS.size()) 00402 return false; 00403 if (isSmall()) 00404 return getSmallBits() == RHS.getSmallBits(); 00405 else 00406 return *getPointer() == *RHS.getPointer(); 00407 } 00408 00409 bool operator!=(const SmallBitVector &RHS) const { 00410 return !(*this == RHS); 00411 } 00412 00413 // Intersection, union, disjoint union. 00414 SmallBitVector &operator&=(const SmallBitVector &RHS) { 00415 resize(std::max(size(), RHS.size())); 00416 if (isSmall()) 00417 setSmallBits(getSmallBits() & RHS.getSmallBits()); 00418 else if (!RHS.isSmall()) 00419 getPointer()->operator&=(*RHS.getPointer()); 00420 else { 00421 SmallBitVector Copy = RHS; 00422 Copy.resize(size()); 00423 getPointer()->operator&=(*Copy.getPointer()); 00424 } 00425 return *this; 00426 } 00427 00428 /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS. 00429 SmallBitVector &reset(const SmallBitVector &RHS) { 00430 if (isSmall() && RHS.isSmall()) 00431 setSmallBits(getSmallBits() & ~RHS.getSmallBits()); 00432 else if (!isSmall() && !RHS.isSmall()) 00433 getPointer()->reset(*RHS.getPointer()); 00434 else 00435 for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i) 00436 if (RHS.test(i)) 00437 reset(i); 00438 00439 return *this; 00440 } 00441 00442 /// test - Check if (This - RHS) is zero. 00443 /// This is the same as reset(RHS) and any(). 00444 bool test(const SmallBitVector &RHS) const { 00445 if (isSmall() && RHS.isSmall()) 00446 return (getSmallBits() & ~RHS.getSmallBits()) != 0; 00447 if (!isSmall() && !RHS.isSmall()) 00448 return getPointer()->test(*RHS.getPointer()); 00449 00450 unsigned i, e; 00451 for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i) 00452 if (test(i) && !RHS.test(i)) 00453 return true; 00454 00455 for (e = size(); i != e; ++i) 00456 if (test(i)) 00457 return true; 00458 00459 return false; 00460 } 00461 00462 SmallBitVector &operator|=(const SmallBitVector &RHS) { 00463 resize(std::max(size(), RHS.size())); 00464 if (isSmall()) 00465 setSmallBits(getSmallBits() | RHS.getSmallBits()); 00466 else if (!RHS.isSmall()) 00467 getPointer()->operator|=(*RHS.getPointer()); 00468 else { 00469 SmallBitVector Copy = RHS; 00470 Copy.resize(size()); 00471 getPointer()->operator|=(*Copy.getPointer()); 00472 } 00473 return *this; 00474 } 00475 00476 SmallBitVector &operator^=(const SmallBitVector &RHS) { 00477 resize(std::max(size(), RHS.size())); 00478 if (isSmall()) 00479 setSmallBits(getSmallBits() ^ RHS.getSmallBits()); 00480 else if (!RHS.isSmall()) 00481 getPointer()->operator^=(*RHS.getPointer()); 00482 else { 00483 SmallBitVector Copy = RHS; 00484 Copy.resize(size()); 00485 getPointer()->operator^=(*Copy.getPointer()); 00486 } 00487 return *this; 00488 } 00489 00490 // Assignment operator. 00491 const SmallBitVector &operator=(const SmallBitVector &RHS) { 00492 if (isSmall()) { 00493 if (RHS.isSmall()) 00494 X = RHS.X; 00495 else 00496 switchToLarge(new BitVector(*RHS.getPointer())); 00497 } else { 00498 if (!RHS.isSmall()) 00499 *getPointer() = *RHS.getPointer(); 00500 else { 00501 delete getPointer(); 00502 X = RHS.X; 00503 } 00504 } 00505 return *this; 00506 } 00507 00508 const SmallBitVector &operator=(SmallBitVector &&RHS) { 00509 if (this != &RHS) { 00510 clear(); 00511 swap(RHS); 00512 } 00513 return *this; 00514 } 00515 00516 void swap(SmallBitVector &RHS) { 00517 std::swap(X, RHS.X); 00518 } 00519 00520 /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize. 00521 /// This computes "*this |= Mask". 00522 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00523 if (isSmall()) 00524 applyMask<true, false>(Mask, MaskWords); 00525 else 00526 getPointer()->setBitsInMask(Mask, MaskWords); 00527 } 00528 00529 /// clearBitsInMask - Clear any bits in this vector that are set in Mask. 00530 /// Don't resize. This computes "*this &= ~Mask". 00531 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00532 if (isSmall()) 00533 applyMask<false, false>(Mask, MaskWords); 00534 else 00535 getPointer()->clearBitsInMask(Mask, MaskWords); 00536 } 00537 00538 /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask. 00539 /// Don't resize. This computes "*this |= ~Mask". 00540 void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00541 if (isSmall()) 00542 applyMask<true, true>(Mask, MaskWords); 00543 else 00544 getPointer()->setBitsNotInMask(Mask, MaskWords); 00545 } 00546 00547 /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask. 00548 /// Don't resize. This computes "*this &= Mask". 00549 void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00550 if (isSmall()) 00551 applyMask<false, true>(Mask, MaskWords); 00552 else 00553 getPointer()->clearBitsNotInMask(Mask, MaskWords); 00554 } 00555 00556 private: 00557 template<bool AddBits, bool InvertMask> 00558 void applyMask(const uint32_t *Mask, unsigned MaskWords) { 00559 assert((NumBaseBits == 64 || NumBaseBits == 32) && "Unsupported word size"); 00560 if (NumBaseBits == 64 && MaskWords >= 2) { 00561 uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32); 00562 if (InvertMask) M = ~M; 00563 if (AddBits) setSmallBits(getSmallBits() | M); 00564 else setSmallBits(getSmallBits() & ~M); 00565 } else { 00566 uint32_t M = Mask[0]; 00567 if (InvertMask) M = ~M; 00568 if (AddBits) setSmallBits(getSmallBits() | M); 00569 else setSmallBits(getSmallBits() & ~M); 00570 } 00571 } 00572 }; 00573 00574 inline SmallBitVector 00575 operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) { 00576 SmallBitVector Result(LHS); 00577 Result &= RHS; 00578 return Result; 00579 } 00580 00581 inline SmallBitVector 00582 operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) { 00583 SmallBitVector Result(LHS); 00584 Result |= RHS; 00585 return Result; 00586 } 00587 00588 inline SmallBitVector 00589 operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) { 00590 SmallBitVector Result(LHS); 00591 Result ^= RHS; 00592 return Result; 00593 } 00594 00595 } // End llvm namespace 00596 00597 namespace std { 00598 /// Implement std::swap in terms of BitVector swap. 00599 inline void 00600 swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) { 00601 LHS.swap(RHS); 00602 } 00603 } 00604 00605 #endif