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 // Encapsulation of a single bit. 00058 class reference { 00059 SmallBitVector &TheVector; 00060 unsigned BitPos; 00061 00062 public: 00063 reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {} 00064 00065 reference& operator=(reference t) { 00066 *this = bool(t); 00067 return *this; 00068 } 00069 00070 reference& operator=(bool t) { 00071 if (t) 00072 TheVector.set(BitPos); 00073 else 00074 TheVector.reset(BitPos); 00075 return *this; 00076 } 00077 00078 operator bool() const { 00079 return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos); 00080 } 00081 }; 00082 00083 private: 00084 bool isSmall() const { 00085 return X & uintptr_t(1); 00086 } 00087 00088 BitVector *getPointer() const { 00089 assert(!isSmall()); 00090 return reinterpret_cast<BitVector *>(X); 00091 } 00092 00093 void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) { 00094 X = 1; 00095 setSmallSize(NewSize); 00096 setSmallBits(NewSmallBits); 00097 } 00098 00099 void switchToLarge(BitVector *BV) { 00100 X = reinterpret_cast<uintptr_t>(BV); 00101 assert(!isSmall() && "Tried to use an unaligned pointer"); 00102 } 00103 00104 // Return all the bits used for the "small" representation; this includes 00105 // bits for the size as well as the element bits. 00106 uintptr_t getSmallRawBits() const { 00107 assert(isSmall()); 00108 return X >> 1; 00109 } 00110 00111 void setSmallRawBits(uintptr_t NewRawBits) { 00112 assert(isSmall()); 00113 X = (NewRawBits << 1) | uintptr_t(1); 00114 } 00115 00116 // Return the size. 00117 size_t getSmallSize() const { 00118 return getSmallRawBits() >> SmallNumDataBits; 00119 } 00120 00121 void setSmallSize(size_t Size) { 00122 setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits)); 00123 } 00124 00125 // Return the element bits. 00126 uintptr_t getSmallBits() const { 00127 return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize()); 00128 } 00129 00130 void setSmallBits(uintptr_t NewBits) { 00131 setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) | 00132 (getSmallSize() << SmallNumDataBits)); 00133 } 00134 00135 public: 00136 /// SmallBitVector default ctor - Creates an empty bitvector. 00137 SmallBitVector() : X(1) {} 00138 00139 /// SmallBitVector ctor - Creates a bitvector of specified number of bits. All 00140 /// bits are initialized to the specified value. 00141 explicit SmallBitVector(unsigned s, bool t = false) { 00142 if (s <= SmallNumDataBits) 00143 switchToSmall(t ? ~uintptr_t(0) : 0, s); 00144 else 00145 switchToLarge(new BitVector(s, t)); 00146 } 00147 00148 /// SmallBitVector copy ctor. 00149 SmallBitVector(const SmallBitVector &RHS) { 00150 if (RHS.isSmall()) 00151 X = RHS.X; 00152 else 00153 switchToLarge(new BitVector(*RHS.getPointer())); 00154 } 00155 00156 #if LLVM_HAS_RVALUE_REFERENCES 00157 SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { 00158 RHS.X = 1; 00159 } 00160 #endif 00161 00162 ~SmallBitVector() { 00163 if (!isSmall()) 00164 delete getPointer(); 00165 } 00166 00167 /// empty - Tests whether there are no bits in this bitvector. 00168 bool empty() const { 00169 return isSmall() ? getSmallSize() == 0 : getPointer()->empty(); 00170 } 00171 00172 /// size - Returns the number of bits in this bitvector. 00173 size_t size() const { 00174 return isSmall() ? getSmallSize() : getPointer()->size(); 00175 } 00176 00177 /// count - Returns the number of bits which are set. 00178 unsigned count() const { 00179 if (isSmall()) { 00180 uintptr_t Bits = getSmallBits(); 00181 if (NumBaseBits == 32) 00182 return CountPopulation_32(Bits); 00183 if (NumBaseBits == 64) 00184 return CountPopulation_64(Bits); 00185 llvm_unreachable("Unsupported!"); 00186 } 00187 return getPointer()->count(); 00188 } 00189 00190 /// any - Returns true if any bit is set. 00191 bool any() const { 00192 if (isSmall()) 00193 return getSmallBits() != 0; 00194 return getPointer()->any(); 00195 } 00196 00197 /// all - Returns true if all bits are set. 00198 bool all() const { 00199 if (isSmall()) 00200 return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1; 00201 return getPointer()->all(); 00202 } 00203 00204 /// none - Returns true if none of the bits are set. 00205 bool none() const { 00206 if (isSmall()) 00207 return getSmallBits() == 0; 00208 return getPointer()->none(); 00209 } 00210 00211 /// find_first - Returns the index of the first set bit, -1 if none 00212 /// of the bits are set. 00213 int find_first() const { 00214 if (isSmall()) { 00215 uintptr_t Bits = getSmallBits(); 00216 if (Bits == 0) 00217 return -1; 00218 if (NumBaseBits == 32) 00219 return CountTrailingZeros_32(Bits); 00220 if (NumBaseBits == 64) 00221 return CountTrailingZeros_64(Bits); 00222 llvm_unreachable("Unsupported!"); 00223 } 00224 return getPointer()->find_first(); 00225 } 00226 00227 /// find_next - Returns the index of the next set bit following the 00228 /// "Prev" bit. Returns -1 if the next set bit is not found. 00229 int find_next(unsigned Prev) const { 00230 if (isSmall()) { 00231 uintptr_t Bits = getSmallBits(); 00232 // Mask off previous bits. 00233 Bits &= ~uintptr_t(0) << (Prev + 1); 00234 if (Bits == 0 || Prev + 1 >= getSmallSize()) 00235 return -1; 00236 if (NumBaseBits == 32) 00237 return CountTrailingZeros_32(Bits); 00238 if (NumBaseBits == 64) 00239 return CountTrailingZeros_64(Bits); 00240 llvm_unreachable("Unsupported!"); 00241 } 00242 return getPointer()->find_next(Prev); 00243 } 00244 00245 /// clear - Clear all bits. 00246 void clear() { 00247 if (!isSmall()) 00248 delete getPointer(); 00249 switchToSmall(0, 0); 00250 } 00251 00252 /// resize - Grow or shrink the bitvector. 00253 void resize(unsigned N, bool t = false) { 00254 if (!isSmall()) { 00255 getPointer()->resize(N, t); 00256 } else if (SmallNumDataBits >= N) { 00257 uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0; 00258 setSmallSize(N); 00259 setSmallBits(NewBits | getSmallBits()); 00260 } else { 00261 BitVector *BV = new BitVector(N, t); 00262 uintptr_t OldBits = getSmallBits(); 00263 for (size_t i = 0, e = getSmallSize(); i != e; ++i) 00264 (*BV)[i] = (OldBits >> i) & 1; 00265 switchToLarge(BV); 00266 } 00267 } 00268 00269 void reserve(unsigned N) { 00270 if (isSmall()) { 00271 if (N > SmallNumDataBits) { 00272 uintptr_t OldBits = getSmallRawBits(); 00273 size_t SmallSize = getSmallSize(); 00274 BitVector *BV = new BitVector(SmallSize); 00275 for (size_t i = 0; i < SmallSize; ++i) 00276 if ((OldBits >> i) & 1) 00277 BV->set(i); 00278 BV->reserve(N); 00279 switchToLarge(BV); 00280 } 00281 } else { 00282 getPointer()->reserve(N); 00283 } 00284 } 00285 00286 // Set, reset, flip 00287 SmallBitVector &set() { 00288 if (isSmall()) 00289 setSmallBits(~uintptr_t(0)); 00290 else 00291 getPointer()->set(); 00292 return *this; 00293 } 00294 00295 SmallBitVector &set(unsigned Idx) { 00296 if (isSmall()) 00297 setSmallBits(getSmallBits() | (uintptr_t(1) << Idx)); 00298 else 00299 getPointer()->set(Idx); 00300 return *this; 00301 } 00302 00303 /// set - Efficiently set a range of bits in [I, E) 00304 SmallBitVector &set(unsigned I, unsigned E) { 00305 assert(I <= E && "Attempted to set backwards range!"); 00306 assert(E <= size() && "Attempted to set out-of-bounds range!"); 00307 if (I == E) return *this; 00308 if (isSmall()) { 00309 uintptr_t EMask = ((uintptr_t)1) << E; 00310 uintptr_t IMask = ((uintptr_t)1) << I; 00311 uintptr_t Mask = EMask - IMask; 00312 setSmallBits(getSmallBits() | Mask); 00313 } else 00314 getPointer()->set(I, E); 00315 return *this; 00316 } 00317 00318 SmallBitVector &reset() { 00319 if (isSmall()) 00320 setSmallBits(0); 00321 else 00322 getPointer()->reset(); 00323 return *this; 00324 } 00325 00326 SmallBitVector &reset(unsigned Idx) { 00327 if (isSmall()) 00328 setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx)); 00329 else 00330 getPointer()->reset(Idx); 00331 return *this; 00332 } 00333 00334 /// reset - Efficiently reset a range of bits in [I, E) 00335 SmallBitVector &reset(unsigned I, unsigned E) { 00336 assert(I <= E && "Attempted to reset backwards range!"); 00337 assert(E <= size() && "Attempted to reset out-of-bounds range!"); 00338 if (I == E) return *this; 00339 if (isSmall()) { 00340 uintptr_t EMask = ((uintptr_t)1) << E; 00341 uintptr_t IMask = ((uintptr_t)1) << I; 00342 uintptr_t Mask = EMask - IMask; 00343 setSmallBits(getSmallBits() & ~Mask); 00344 } else 00345 getPointer()->reset(I, E); 00346 return *this; 00347 } 00348 00349 SmallBitVector &flip() { 00350 if (isSmall()) 00351 setSmallBits(~getSmallBits()); 00352 else 00353 getPointer()->flip(); 00354 return *this; 00355 } 00356 00357 SmallBitVector &flip(unsigned Idx) { 00358 if (isSmall()) 00359 setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx)); 00360 else 00361 getPointer()->flip(Idx); 00362 return *this; 00363 } 00364 00365 // No argument flip. 00366 SmallBitVector operator~() const { 00367 return SmallBitVector(*this).flip(); 00368 } 00369 00370 // Indexing. 00371 reference operator[](unsigned Idx) { 00372 assert(Idx < size() && "Out-of-bounds Bit access."); 00373 return reference(*this, Idx); 00374 } 00375 00376 bool operator[](unsigned Idx) const { 00377 assert(Idx < size() && "Out-of-bounds Bit access."); 00378 if (isSmall()) 00379 return ((getSmallBits() >> Idx) & 1) != 0; 00380 return getPointer()->operator[](Idx); 00381 } 00382 00383 bool test(unsigned Idx) const { 00384 return (*this)[Idx]; 00385 } 00386 00387 /// Test if any common bits are set. 00388 bool anyCommon(const SmallBitVector &RHS) const { 00389 if (isSmall() && RHS.isSmall()) 00390 return (getSmallBits() & RHS.getSmallBits()) != 0; 00391 if (!isSmall() && !RHS.isSmall()) 00392 return getPointer()->anyCommon(*RHS.getPointer()); 00393 00394 for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i) 00395 if (test(i) && RHS.test(i)) 00396 return true; 00397 return false; 00398 } 00399 00400 // Comparison operators. 00401 bool operator==(const SmallBitVector &RHS) const { 00402 if (size() != RHS.size()) 00403 return false; 00404 if (isSmall()) 00405 return getSmallBits() == RHS.getSmallBits(); 00406 else 00407 return *getPointer() == *RHS.getPointer(); 00408 } 00409 00410 bool operator!=(const SmallBitVector &RHS) const { 00411 return !(*this == RHS); 00412 } 00413 00414 // Intersection, union, disjoint union. 00415 SmallBitVector &operator&=(const SmallBitVector &RHS) { 00416 resize(std::max(size(), RHS.size())); 00417 if (isSmall()) 00418 setSmallBits(getSmallBits() & RHS.getSmallBits()); 00419 else if (!RHS.isSmall()) 00420 getPointer()->operator&=(*RHS.getPointer()); 00421 else { 00422 SmallBitVector Copy = RHS; 00423 Copy.resize(size()); 00424 getPointer()->operator&=(*Copy.getPointer()); 00425 } 00426 return *this; 00427 } 00428 00429 SmallBitVector &operator|=(const SmallBitVector &RHS) { 00430 resize(std::max(size(), RHS.size())); 00431 if (isSmall()) 00432 setSmallBits(getSmallBits() | RHS.getSmallBits()); 00433 else if (!RHS.isSmall()) 00434 getPointer()->operator|=(*RHS.getPointer()); 00435 else { 00436 SmallBitVector Copy = RHS; 00437 Copy.resize(size()); 00438 getPointer()->operator|=(*Copy.getPointer()); 00439 } 00440 return *this; 00441 } 00442 00443 SmallBitVector &operator^=(const SmallBitVector &RHS) { 00444 resize(std::max(size(), RHS.size())); 00445 if (isSmall()) 00446 setSmallBits(getSmallBits() ^ RHS.getSmallBits()); 00447 else if (!RHS.isSmall()) 00448 getPointer()->operator^=(*RHS.getPointer()); 00449 else { 00450 SmallBitVector Copy = RHS; 00451 Copy.resize(size()); 00452 getPointer()->operator^=(*Copy.getPointer()); 00453 } 00454 return *this; 00455 } 00456 00457 // Assignment operator. 00458 const SmallBitVector &operator=(const SmallBitVector &RHS) { 00459 if (isSmall()) { 00460 if (RHS.isSmall()) 00461 X = RHS.X; 00462 else 00463 switchToLarge(new BitVector(*RHS.getPointer())); 00464 } else { 00465 if (!RHS.isSmall()) 00466 *getPointer() = *RHS.getPointer(); 00467 else { 00468 delete getPointer(); 00469 X = RHS.X; 00470 } 00471 } 00472 return *this; 00473 } 00474 00475 #if LLVM_HAS_RVALUE_REFERENCES 00476 const SmallBitVector &operator=(SmallBitVector &&RHS) { 00477 if (this != &RHS) { 00478 clear(); 00479 swap(RHS); 00480 } 00481 return *this; 00482 } 00483 #endif 00484 00485 void swap(SmallBitVector &RHS) { 00486 std::swap(X, RHS.X); 00487 } 00488 00489 /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize. 00490 /// This computes "*this |= Mask". 00491 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00492 if (isSmall()) 00493 applyMask<true, false>(Mask, MaskWords); 00494 else 00495 getPointer()->setBitsInMask(Mask, MaskWords); 00496 } 00497 00498 /// clearBitsInMask - Clear any bits in this vector that are set in Mask. 00499 /// Don't resize. This computes "*this &= ~Mask". 00500 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00501 if (isSmall()) 00502 applyMask<false, false>(Mask, MaskWords); 00503 else 00504 getPointer()->clearBitsInMask(Mask, MaskWords); 00505 } 00506 00507 /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask. 00508 /// Don't resize. This computes "*this |= ~Mask". 00509 void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00510 if (isSmall()) 00511 applyMask<true, true>(Mask, MaskWords); 00512 else 00513 getPointer()->setBitsNotInMask(Mask, MaskWords); 00514 } 00515 00516 /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask. 00517 /// Don't resize. This computes "*this &= Mask". 00518 void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { 00519 if (isSmall()) 00520 applyMask<false, true>(Mask, MaskWords); 00521 else 00522 getPointer()->clearBitsNotInMask(Mask, MaskWords); 00523 } 00524 00525 private: 00526 template<bool AddBits, bool InvertMask> 00527 void applyMask(const uint32_t *Mask, unsigned MaskWords) { 00528 assert((NumBaseBits == 64 || NumBaseBits == 32) && "Unsupported word size"); 00529 if (NumBaseBits == 64 && MaskWords >= 2) { 00530 uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32); 00531 if (InvertMask) M = ~M; 00532 if (AddBits) setSmallBits(getSmallBits() | M); 00533 else setSmallBits(getSmallBits() & ~M); 00534 } else { 00535 uint32_t M = Mask[0]; 00536 if (InvertMask) M = ~M; 00537 if (AddBits) setSmallBits(getSmallBits() | M); 00538 else setSmallBits(getSmallBits() & ~M); 00539 } 00540 } 00541 }; 00542 00543 inline SmallBitVector 00544 operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) { 00545 SmallBitVector Result(LHS); 00546 Result &= RHS; 00547 return Result; 00548 } 00549 00550 inline SmallBitVector 00551 operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) { 00552 SmallBitVector Result(LHS); 00553 Result |= RHS; 00554 return Result; 00555 } 00556 00557 inline SmallBitVector 00558 operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) { 00559 SmallBitVector Result(LHS); 00560 Result ^= RHS; 00561 return Result; 00562 } 00563 00564 } // End llvm namespace 00565 00566 namespace std { 00567 /// Implement std::swap in terms of BitVector swap. 00568 inline void 00569 swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) { 00570 LHS.swap(RHS); 00571 } 00572 } 00573 00574 #endif