• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the BitVector class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_ADT_BITVECTOR_H
15 #define LLVM_ADT_BITVECTOR_H
16 
17 #include "llvm/Support/MathExtras.h"
18 #include <algorithm>
19 #include <cassert>
20 #include <climits>
21 #include <cstdlib>
22 #include <cstring>
23 
24 namespace llvm {
25 
26 class BitVector {
27   typedef unsigned long BitWord;
28 
29   enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
30 
31   BitWord  *Bits;        // Actual bits.
32   unsigned Size;         // Size of bitvector in bits.
33   unsigned Capacity;     // Size of allocated memory in BitWord.
34 
35 public:
36   // Encapsulation of a single bit.
37   class reference {
38     friend class BitVector;
39 
40     BitWord *WordRef;
41     unsigned BitPos;
42 
43     reference();  // Undefined
44 
45   public:
reference(BitVector & b,unsigned Idx)46     reference(BitVector &b, unsigned Idx) {
47       WordRef = &b.Bits[Idx / BITWORD_SIZE];
48       BitPos = Idx % BITWORD_SIZE;
49     }
50 
~reference()51     ~reference() {}
52 
53     reference &operator=(reference t) {
54       *this = bool(t);
55       return *this;
56     }
57 
58     reference& operator=(bool t) {
59       if (t)
60         *WordRef |= 1L << BitPos;
61       else
62         *WordRef &= ~(1L << BitPos);
63       return *this;
64     }
65 
66     operator bool() const {
67       return ((*WordRef) & (1L << BitPos)) ? true : false;
68     }
69   };
70 
71 
72   /// BitVector default ctor - Creates an empty bitvector.
BitVector()73   BitVector() : Size(0), Capacity(0) {
74     Bits = 0;
75   }
76 
77   /// BitVector ctor - Creates a bitvector of specified number of bits. All
78   /// bits are initialized to the specified value.
Size(s)79   explicit BitVector(unsigned s, bool t = false) : Size(s) {
80     Capacity = NumBitWords(s);
81     Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
82     init_words(Bits, Capacity, t);
83     if (t)
84       clear_unused_bits();
85   }
86 
87   /// BitVector copy ctor.
BitVector(const BitVector & RHS)88   BitVector(const BitVector &RHS) : Size(RHS.size()) {
89     if (Size == 0) {
90       Bits = 0;
91       Capacity = 0;
92       return;
93     }
94 
95     Capacity = NumBitWords(RHS.size());
96     Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
97     std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
98   }
99 
~BitVector()100   ~BitVector() {
101     std::free(Bits);
102   }
103 
104   /// empty - Tests whether there are no bits in this bitvector.
empty()105   bool empty() const { return Size == 0; }
106 
107   /// size - Returns the number of bits in this bitvector.
size()108   unsigned size() const { return Size; }
109 
110   /// count - Returns the number of bits which are set.
count()111   unsigned count() const {
112     unsigned NumBits = 0;
113     for (unsigned i = 0; i < NumBitWords(size()); ++i)
114       if (sizeof(BitWord) == 4)
115         NumBits += CountPopulation_32((uint32_t)Bits[i]);
116       else if (sizeof(BitWord) == 8)
117         NumBits += CountPopulation_64(Bits[i]);
118       else
119         assert(0 && "Unsupported!");
120     return NumBits;
121   }
122 
123   /// any - Returns true if any bit is set.
any()124   bool any() const {
125     for (unsigned i = 0; i < NumBitWords(size()); ++i)
126       if (Bits[i] != 0)
127         return true;
128     return false;
129   }
130 
131   /// all - Returns true if all bits are set.
all()132   bool all() const {
133     // TODO: Optimize this.
134     return count() == size();
135   }
136 
137   /// none - Returns true if none of the bits are set.
none()138   bool none() const {
139     return !any();
140   }
141 
142   /// find_first - Returns the index of the first set bit, -1 if none
143   /// of the bits are set.
find_first()144   int find_first() const {
145     for (unsigned i = 0; i < NumBitWords(size()); ++i)
146       if (Bits[i] != 0) {
147         if (sizeof(BitWord) == 4)
148           return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
149         else if (sizeof(BitWord) == 8)
150           return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
151         else
152           assert(0 && "Unsupported!");
153       }
154     return -1;
155   }
156 
157   /// find_next - Returns the index of the next set bit following the
158   /// "Prev" bit. Returns -1 if the next set bit is not found.
find_next(unsigned Prev)159   int find_next(unsigned Prev) const {
160     ++Prev;
161     if (Prev >= Size)
162       return -1;
163 
164     unsigned WordPos = Prev / BITWORD_SIZE;
165     unsigned BitPos = Prev % BITWORD_SIZE;
166     BitWord Copy = Bits[WordPos];
167     // Mask off previous bits.
168     Copy &= ~0L << BitPos;
169 
170     if (Copy != 0) {
171       if (sizeof(BitWord) == 4)
172         return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy);
173       else if (sizeof(BitWord) == 8)
174         return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
175       else
176         assert(0 && "Unsupported!");
177     }
178 
179     // Check subsequent words.
180     for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
181       if (Bits[i] != 0) {
182         if (sizeof(BitWord) == 4)
183           return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
184         else if (sizeof(BitWord) == 8)
185           return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
186         else
187           assert(0 && "Unsupported!");
188       }
189     return -1;
190   }
191 
192   /// clear - Clear all bits.
clear()193   void clear() {
194     Size = 0;
195   }
196 
197   /// resize - Grow or shrink the bitvector.
198   void resize(unsigned N, bool t = false) {
199     if (N > Capacity * BITWORD_SIZE) {
200       unsigned OldCapacity = Capacity;
201       grow(N);
202       init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
203     }
204 
205     // Set any old unused bits that are now included in the BitVector. This
206     // may set bits that are not included in the new vector, but we will clear
207     // them back out below.
208     if (N > Size)
209       set_unused_bits(t);
210 
211     // Update the size, and clear out any bits that are now unused
212     unsigned OldSize = Size;
213     Size = N;
214     if (t || N < OldSize)
215       clear_unused_bits();
216   }
217 
reserve(unsigned N)218   void reserve(unsigned N) {
219     if (N > Capacity * BITWORD_SIZE)
220       grow(N);
221   }
222 
223   // Set, reset, flip
set()224   BitVector &set() {
225     init_words(Bits, Capacity, true);
226     clear_unused_bits();
227     return *this;
228   }
229 
set(unsigned Idx)230   BitVector &set(unsigned Idx) {
231     Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
232     return *this;
233   }
234 
reset()235   BitVector &reset() {
236     init_words(Bits, Capacity, false);
237     return *this;
238   }
239 
reset(unsigned Idx)240   BitVector &reset(unsigned Idx) {
241     Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
242     return *this;
243   }
244 
flip()245   BitVector &flip() {
246     for (unsigned i = 0; i < NumBitWords(size()); ++i)
247       Bits[i] = ~Bits[i];
248     clear_unused_bits();
249     return *this;
250   }
251 
flip(unsigned Idx)252   BitVector &flip(unsigned Idx) {
253     Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
254     return *this;
255   }
256 
257   // No argument flip.
258   BitVector operator~() const {
259     return BitVector(*this).flip();
260   }
261 
262   // Indexing.
263   reference operator[](unsigned Idx) {
264     assert (Idx < Size && "Out-of-bounds Bit access.");
265     return reference(*this, Idx);
266   }
267 
268   bool operator[](unsigned Idx) const {
269     assert (Idx < Size && "Out-of-bounds Bit access.");
270     BitWord Mask = 1L << (Idx % BITWORD_SIZE);
271     return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
272   }
273 
test(unsigned Idx)274   bool test(unsigned Idx) const {
275     return (*this)[Idx];
276   }
277 
278   // Comparison operators.
279   bool operator==(const BitVector &RHS) const {
280     unsigned ThisWords = NumBitWords(size());
281     unsigned RHSWords  = NumBitWords(RHS.size());
282     unsigned i;
283     for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
284       if (Bits[i] != RHS.Bits[i])
285         return false;
286 
287     // Verify that any extra words are all zeros.
288     if (i != ThisWords) {
289       for (; i != ThisWords; ++i)
290         if (Bits[i])
291           return false;
292     } else if (i != RHSWords) {
293       for (; i != RHSWords; ++i)
294         if (RHS.Bits[i])
295           return false;
296     }
297     return true;
298   }
299 
300   bool operator!=(const BitVector &RHS) const {
301     return !(*this == RHS);
302   }
303 
304   // Intersection, union, disjoint union.
305   BitVector &operator&=(const BitVector &RHS) {
306     unsigned ThisWords = NumBitWords(size());
307     unsigned RHSWords  = NumBitWords(RHS.size());
308     unsigned i;
309     for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
310       Bits[i] &= RHS.Bits[i];
311 
312     // Any bits that are just in this bitvector become zero, because they aren't
313     // in the RHS bit vector.  Any words only in RHS are ignored because they
314     // are already zero in the LHS.
315     for (; i != ThisWords; ++i)
316       Bits[i] = 0;
317 
318     return *this;
319   }
320 
321   BitVector &operator|=(const BitVector &RHS) {
322     if (size() < RHS.size())
323       resize(RHS.size());
324     for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
325       Bits[i] |= RHS.Bits[i];
326     return *this;
327   }
328 
329   BitVector &operator^=(const BitVector &RHS) {
330     if (size() < RHS.size())
331       resize(RHS.size());
332     for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
333       Bits[i] ^= RHS.Bits[i];
334     return *this;
335   }
336 
337   // Assignment operator.
338   const BitVector &operator=(const BitVector &RHS) {
339     if (this == &RHS) return *this;
340 
341     Size = RHS.size();
342     unsigned RHSWords = NumBitWords(Size);
343     if (Size <= Capacity * BITWORD_SIZE) {
344       if (Size)
345         std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
346       clear_unused_bits();
347       return *this;
348     }
349 
350     // Grow the bitvector to have enough elements.
351     Capacity = RHSWords;
352     BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
353     std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
354 
355     // Destroy the old bits.
356     std::free(Bits);
357     Bits = NewBits;
358 
359     return *this;
360   }
361 
swap(BitVector & RHS)362   void swap(BitVector &RHS) {
363     std::swap(Bits, RHS.Bits);
364     std::swap(Size, RHS.Size);
365     std::swap(Capacity, RHS.Capacity);
366   }
367 
368 private:
NumBitWords(unsigned S)369   unsigned NumBitWords(unsigned S) const {
370     return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
371   }
372 
373   // Set the unused bits in the high words.
374   void set_unused_bits(bool t = true) {
375     //  Set high words first.
376     unsigned UsedWords = NumBitWords(Size);
377     if (Capacity > UsedWords)
378       init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
379 
380     //  Then set any stray high bits of the last used word.
381     unsigned ExtraBits = Size % BITWORD_SIZE;
382     if (ExtraBits) {
383       Bits[UsedWords-1] &= ~(~0L << ExtraBits);
384       Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
385     }
386   }
387 
388   // Clear the unused bits in the high words.
clear_unused_bits()389   void clear_unused_bits() {
390     set_unused_bits(false);
391   }
392 
grow(unsigned NewSize)393   void grow(unsigned NewSize) {
394     Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
395     Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
396 
397     clear_unused_bits();
398   }
399 
init_words(BitWord * B,unsigned NumWords,bool t)400   void init_words(BitWord *B, unsigned NumWords, bool t) {
401     memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
402   }
403 };
404 
405 inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
406   BitVector Result(LHS);
407   Result &= RHS;
408   return Result;
409 }
410 
411 inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) {
412   BitVector Result(LHS);
413   Result |= RHS;
414   return Result;
415 }
416 
417 inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
418   BitVector Result(LHS);
419   Result ^= RHS;
420   return Result;
421 }
422 
423 } // End llvm namespace
424 
425 namespace std {
426   /// Implement std::swap in terms of BitVector swap.
427   inline void
swap(llvm::BitVector & LHS,llvm::BitVector & RHS)428   swap(llvm::BitVector &LHS, llvm::BitVector &RHS) {
429     LHS.swap(RHS);
430   }
431 }
432 
433 #endif
434