LLVM API Documentation
00001 //===- llvm/ADT/BitVector.h - 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 BitVector class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_BITVECTOR_H 00015 #define LLVM_ADT_BITVECTOR_H 00016 00017 #include "llvm/Support/MathExtras.h" 00018 #include <algorithm> 00019 #include <cassert> 00020 #include <cstring> 00021 00022 namespace llvm { 00023 00024 class BitVector { 00025 typedef unsigned long BitWord; 00026 00027 enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * 8 }; 00028 00029 BitWord *Bits; // Actual bits. 00030 unsigned Size; // Size of bitvector in bits. 00031 unsigned Capacity; // Size of allocated memory in BitWord. 00032 00033 public: 00034 // Encapsulation of a single bit. 00035 class reference { 00036 friend class BitVector; 00037 00038 BitWord *WordRef; 00039 unsigned BitPos; 00040 00041 reference(); // Undefined 00042 00043 public: 00044 reference(BitVector &b, unsigned Idx) { 00045 WordRef = &b.Bits[Idx / BITWORD_SIZE]; 00046 BitPos = Idx % BITWORD_SIZE; 00047 } 00048 00049 ~reference() {} 00050 00051 reference& operator=(bool t) { 00052 if (t) 00053 *WordRef |= 1L << BitPos; 00054 else 00055 *WordRef &= ~(1L << BitPos); 00056 return *this; 00057 } 00058 00059 operator bool() const { 00060 return ((*WordRef) & (1L << BitPos)) ? true : false; 00061 } 00062 }; 00063 00064 00065 /// BitVector default ctor - Creates an empty bitvector. 00066 BitVector() : Size(0), Capacity(0) { 00067 Bits = 0; 00068 } 00069 00070 /// BitVector ctor - Creates a bitvector of specified number of bits. All 00071 /// bits are initialized to the specified value. 00072 explicit BitVector(unsigned s, bool t = false) : Size(s) { 00073 Capacity = NumBitWords(s); 00074 Bits = new BitWord[Capacity]; 00075 init_words(Bits, Capacity, t); 00076 if (t) 00077 clear_unused_bits(); 00078 } 00079 00080 /// BitVector copy ctor. 00081 BitVector(const BitVector &RHS) : Size(RHS.size()) { 00082 if (Size == 0) { 00083 Bits = 0; 00084 Capacity = 0; 00085 return; 00086 } 00087 00088 Capacity = NumBitWords(RHS.size()); 00089 Bits = new BitWord[Capacity]; 00090 std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits); 00091 } 00092 00093 ~BitVector() { 00094 delete[] Bits; 00095 } 00096 00097 /// size - Returns the number of bits in this bitvector. 00098 unsigned size() const { return Size; } 00099 00100 /// count - Returns the number of bits which are set. 00101 unsigned count() const { 00102 unsigned NumBits = 0; 00103 for (unsigned i = 0; i < NumBitWords(size()); ++i) 00104 if (sizeof(BitWord) == 4) 00105 NumBits += CountPopulation_32((uint32_t)Bits[i]); 00106 else if (sizeof(BitWord) == 8) 00107 NumBits += CountPopulation_64(Bits[i]); 00108 else 00109 assert(0 && "Unsupported!"); 00110 return NumBits; 00111 } 00112 00113 /// any - Returns true if any bit is set. 00114 bool any() const { 00115 for (unsigned i = 0; i < NumBitWords(size()); ++i) 00116 if (Bits[i] != 0) 00117 return true; 00118 return false; 00119 } 00120 00121 /// none - Returns true if none of the bits are set. 00122 bool none() const { 00123 return !any(); 00124 } 00125 00126 /// find_first - Returns the index of the first set bit, -1 if none 00127 /// of the bits are set. 00128 int find_first() const { 00129 for (unsigned i = 0; i < NumBitWords(size()); ++i) 00130 if (Bits[i] != 0) { 00131 if (sizeof(BitWord) == 4) 00132 return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); 00133 else if (sizeof(BitWord) == 8) 00134 return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); 00135 else 00136 assert(0 && "Unsupported!"); 00137 } 00138 return -1; 00139 } 00140 00141 /// find_next - Returns the index of the next set bit following the 00142 /// "Prev" bit. Returns -1 if the next set bit is not found. 00143 int find_next(unsigned Prev) const { 00144 ++Prev; 00145 if (Prev >= Size) 00146 return -1; 00147 00148 unsigned WordPos = Prev / BITWORD_SIZE; 00149 unsigned BitPos = Prev % BITWORD_SIZE; 00150 BitWord Copy = Bits[WordPos]; 00151 // Mask off previous bits. 00152 Copy &= ~0L << BitPos; 00153 00154 if (Copy != 0) { 00155 if (sizeof(BitWord) == 4) 00156 return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy); 00157 else if (sizeof(BitWord) == 8) 00158 return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy); 00159 else 00160 assert(0 && "Unsupported!"); 00161 } 00162 00163 // Check subsequent words. 00164 for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i) 00165 if (Bits[i] != 0) { 00166 if (sizeof(BitWord) == 4) 00167 return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); 00168 else if (sizeof(BitWord) == 8) 00169 return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); 00170 else 00171 assert(0 && "Unsupported!"); 00172 } 00173 return -1; 00174 } 00175 00176 /// clear - Clear all bits. 00177 void clear() { 00178 Size = 0; 00179 } 00180 00181 /// resize - Grow or shrink the bitvector. 00182 void resize(unsigned N, bool t = false) { 00183 if (N > Capacity * BITWORD_SIZE) { 00184 unsigned OldCapacity = Capacity; 00185 grow(N); 00186 init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t); 00187 } 00188 00189 // Set any old unused bits that are now included in the BitVector. This 00190 // may set bits that are not included in the new vector, but we will clear 00191 // them back out below. 00192 if (N > Size) 00193 set_unused_bits(t); 00194 00195 // Update the size, and clear out any bits that are now unused 00196 unsigned OldSize = Size; 00197 Size = N; 00198 if (t || N < OldSize) 00199 clear_unused_bits(); 00200 } 00201 00202 void reserve(unsigned N) { 00203 if (N > Capacity * BITWORD_SIZE) 00204 grow(N); 00205 } 00206 00207 // Set, reset, flip 00208 BitVector &set() { 00209 init_words(Bits, Capacity, true); 00210 clear_unused_bits(); 00211 return *this; 00212 } 00213 00214 BitVector &set(unsigned Idx) { 00215 Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE); 00216 return *this; 00217 } 00218 00219 BitVector &reset() { 00220 init_words(Bits, Capacity, false); 00221 return *this; 00222 } 00223 00224 BitVector &reset(unsigned Idx) { 00225 Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE)); 00226 return *this; 00227 } 00228 00229 BitVector &flip() { 00230 for (unsigned i = 0; i < NumBitWords(size()); ++i) 00231 Bits[i] = ~Bits[i]; 00232 clear_unused_bits(); 00233 return *this; 00234 } 00235 00236 BitVector &flip(unsigned Idx) { 00237 Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE); 00238 return *this; 00239 } 00240 00241 // No argument flip. 00242 BitVector operator~() const { 00243 return BitVector(*this).flip(); 00244 } 00245 00246 // Indexing. 00247 reference operator[](unsigned Idx) { 00248 assert (Idx < Size && "Out-of-bounds Bit access."); 00249 return reference(*this, Idx); 00250 } 00251 00252 bool operator[](unsigned Idx) const { 00253 assert (Idx < Size && "Out-of-bounds Bit access."); 00254 BitWord Mask = 1L << (Idx % BITWORD_SIZE); 00255 return (Bits[Idx / BITWORD_SIZE] & Mask) != 0; 00256 } 00257 00258 bool test(unsigned Idx) const { 00259 return (*this)[Idx]; 00260 } 00261 00262 // Comparison operators. 00263 bool operator==(const BitVector &RHS) const { 00264 unsigned ThisWords = NumBitWords(size()); 00265 unsigned RHSWords = NumBitWords(RHS.size()); 00266 unsigned i; 00267 for (i = 0; i != std::min(ThisWords, RHSWords); ++i) 00268 if (Bits[i] != RHS.Bits[i]) 00269 return false; 00270 00271 // Verify that any extra words are all zeros. 00272 if (i != ThisWords) { 00273 for (; i != ThisWords; ++i) 00274 if (Bits[i]) 00275 return false; 00276 } else if (i != RHSWords) { 00277 for (; i != RHSWords; ++i) 00278 if (RHS.Bits[i]) 00279 return false; 00280 } 00281 return true; 00282 } 00283 00284 bool operator!=(const BitVector &RHS) const { 00285 return !(*this == RHS); 00286 } 00287 00288 // Intersection, union, disjoint union. 00289 BitVector operator&=(const BitVector &RHS) { 00290 unsigned ThisWords = NumBitWords(size()); 00291 unsigned RHSWords = NumBitWords(RHS.size()); 00292 unsigned i; 00293 for (i = 0; i != std::min(ThisWords, RHSWords); ++i) 00294 Bits[i] &= RHS.Bits[i]; 00295 00296 // Any bits that are just in this bitvector become zero, because they aren't 00297 // in the RHS bit vector. Any words only in RHS are ignored because they 00298 // are already zero in the LHS. 00299 for (; i != ThisWords; ++i) 00300 Bits[i] = 0; 00301 00302 return *this; 00303 } 00304 00305 BitVector operator|=(const BitVector &RHS) { 00306 assert(Size == RHS.Size && "Illegal operation!"); 00307 for (unsigned i = 0; i < NumBitWords(size()); ++i) 00308 Bits[i] |= RHS.Bits[i]; 00309 return *this; 00310 } 00311 00312 BitVector operator^=(const BitVector &RHS) { 00313 assert(Size == RHS.Size && "Illegal operation!"); 00314 for (unsigned i = 0; i < NumBitWords(size()); ++i) 00315 Bits[i] ^= RHS.Bits[i]; 00316 return *this; 00317 } 00318 00319 // Assignment operator. 00320 const BitVector &operator=(const BitVector &RHS) { 00321 if (this == &RHS) return *this; 00322 00323 Size = RHS.size(); 00324 unsigned RHSWords = NumBitWords(Size); 00325 if (Size <= Capacity * BITWORD_SIZE) { 00326 std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits); 00327 clear_unused_bits(); 00328 return *this; 00329 } 00330 00331 // Grow the bitvector to have enough elements. 00332 Capacity = RHSWords; 00333 BitWord *NewBits = new BitWord[Capacity]; 00334 std::copy(RHS.Bits, &RHS.Bits[RHSWords], NewBits); 00335 00336 // Destroy the old bits. 00337 delete[] Bits; 00338 Bits = NewBits; 00339 00340 return *this; 00341 } 00342 00343 private: 00344 unsigned NumBitWords(unsigned S) const { 00345 return (S + BITWORD_SIZE-1) / BITWORD_SIZE; 00346 } 00347 00348 // Set the unused bits in the high words. 00349 void set_unused_bits(bool t = true) { 00350 // Set high words first. 00351 unsigned UsedWords = NumBitWords(Size); 00352 if (Capacity > UsedWords) 00353 init_words(&Bits[UsedWords], (Capacity-UsedWords), t); 00354 00355 // Then set any stray high bits of the last used word. 00356 unsigned ExtraBits = Size % BITWORD_SIZE; 00357 if (ExtraBits) { 00358 Bits[UsedWords-1] &= ~(~0L << ExtraBits); 00359 Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits; 00360 } 00361 } 00362 00363 // Clear the unused bits in the high words. 00364 void clear_unused_bits() { 00365 set_unused_bits(false); 00366 } 00367 00368 void grow(unsigned NewSize) { 00369 unsigned OldCapacity = Capacity; 00370 Capacity = NumBitWords(NewSize); 00371 BitWord *NewBits = new BitWord[Capacity]; 00372 00373 // Copy the old bits over. 00374 if (OldCapacity != 0) 00375 std::copy(Bits, &Bits[OldCapacity], NewBits); 00376 00377 // Destroy the old bits. 00378 delete[] Bits; 00379 Bits = NewBits; 00380 00381 clear_unused_bits(); 00382 } 00383 00384 void init_words(BitWord *B, unsigned NumWords, bool t) { 00385 memset(B, 0 - (int)t, NumWords*sizeof(BitWord)); 00386 } 00387 }; 00388 00389 inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) { 00390 BitVector Result(LHS); 00391 Result &= RHS; 00392 return Result; 00393 } 00394 00395 inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) { 00396 BitVector Result(LHS); 00397 Result |= RHS; 00398 return Result; 00399 } 00400 00401 inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) { 00402 BitVector Result(LHS); 00403 Result ^= RHS; 00404 return Result; 00405 } 00406 00407 } // End llvm namespace 00408 #endif
This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.