|  | //===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file implements the BitVector class. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_ADT_BITVECTOR_H | 
|  | #define LLVM_ADT_BITVECTOR_H | 
|  |  | 
|  | #include "llvm/Support/MathExtras.h" | 
|  | #include <algorithm> | 
|  | #include <cassert> | 
|  | #include <climits> | 
|  | #include <cstdlib> | 
|  | #include <cstring> | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | class BitVector { | 
|  | typedef unsigned long BitWord; | 
|  |  | 
|  | enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT }; | 
|  |  | 
|  | BitWord  *Bits;        // Actual bits. | 
|  | unsigned Size;         // Size of bitvector in bits. | 
|  | unsigned Capacity;     // Size of allocated memory in BitWord. | 
|  |  | 
|  | public: | 
|  | // Encapsulation of a single bit. | 
|  | class reference { | 
|  | friend class BitVector; | 
|  |  | 
|  | BitWord *WordRef; | 
|  | unsigned BitPos; | 
|  |  | 
|  | reference();  // Undefined | 
|  |  | 
|  | public: | 
|  | reference(BitVector &b, unsigned Idx) { | 
|  | WordRef = &b.Bits[Idx / BITWORD_SIZE]; | 
|  | BitPos = Idx % BITWORD_SIZE; | 
|  | } | 
|  |  | 
|  | ~reference() {} | 
|  |  | 
|  | reference &operator=(reference t) { | 
|  | *this = bool(t); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | reference& operator=(bool t) { | 
|  | if (t) | 
|  | *WordRef |= 1L << BitPos; | 
|  | else | 
|  | *WordRef &= ~(1L << BitPos); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | operator bool() const { | 
|  | return ((*WordRef) & (1L << BitPos)) ? true : false; | 
|  | } | 
|  | }; | 
|  |  | 
|  |  | 
|  | /// BitVector default ctor - Creates an empty bitvector. | 
|  | BitVector() : Size(0), Capacity(0) { | 
|  | Bits = 0; | 
|  | } | 
|  |  | 
|  | /// BitVector ctor - Creates a bitvector of specified number of bits. All | 
|  | /// bits are initialized to the specified value. | 
|  | explicit BitVector(unsigned s, bool t = false) : Size(s) { | 
|  | Capacity = NumBitWords(s); | 
|  | Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); | 
|  | init_words(Bits, Capacity, t); | 
|  | if (t) | 
|  | clear_unused_bits(); | 
|  | } | 
|  |  | 
|  | /// BitVector copy ctor. | 
|  | BitVector(const BitVector &RHS) : Size(RHS.size()) { | 
|  | if (Size == 0) { | 
|  | Bits = 0; | 
|  | Capacity = 0; | 
|  | return; | 
|  | } | 
|  |  | 
|  | Capacity = NumBitWords(RHS.size()); | 
|  | Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); | 
|  | std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); | 
|  | } | 
|  |  | 
|  | ~BitVector() { | 
|  | std::free(Bits); | 
|  | } | 
|  |  | 
|  | /// empty - Tests whether there are no bits in this bitvector. | 
|  | bool empty() const { return Size == 0; } | 
|  |  | 
|  | /// size - Returns the number of bits in this bitvector. | 
|  | unsigned size() const { return Size; } | 
|  |  | 
|  | /// count - Returns the number of bits which are set. | 
|  | unsigned count() const { | 
|  | unsigned NumBits = 0; | 
|  | for (unsigned i = 0; i < NumBitWords(size()); ++i) | 
|  | if (sizeof(BitWord) == 4) | 
|  | NumBits += CountPopulation_32((uint32_t)Bits[i]); | 
|  | else if (sizeof(BitWord) == 8) | 
|  | NumBits += CountPopulation_64(Bits[i]); | 
|  | else | 
|  | assert(0 && "Unsupported!"); | 
|  | return NumBits; | 
|  | } | 
|  |  | 
|  | /// any - Returns true if any bit is set. | 
|  | bool any() const { | 
|  | for (unsigned i = 0; i < NumBitWords(size()); ++i) | 
|  | if (Bits[i] != 0) | 
|  | return true; | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// all - Returns true if all bits are set. | 
|  | bool all() const { | 
|  | // TODO: Optimize this. | 
|  | return count() == size(); | 
|  | } | 
|  |  | 
|  | /// none - Returns true if none of the bits are set. | 
|  | bool none() const { | 
|  | return !any(); | 
|  | } | 
|  |  | 
|  | /// find_first - Returns the index of the first set bit, -1 if none | 
|  | /// of the bits are set. | 
|  | int find_first() const { | 
|  | for (unsigned i = 0; i < NumBitWords(size()); ++i) | 
|  | if (Bits[i] != 0) { | 
|  | if (sizeof(BitWord) == 4) | 
|  | return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); | 
|  | else if (sizeof(BitWord) == 8) | 
|  | return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); | 
|  | else | 
|  | assert(0 && "Unsupported!"); | 
|  | } | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | /// find_next - Returns the index of the next set bit following the | 
|  | /// "Prev" bit. Returns -1 if the next set bit is not found. | 
|  | int find_next(unsigned Prev) const { | 
|  | ++Prev; | 
|  | if (Prev >= Size) | 
|  | return -1; | 
|  |  | 
|  | unsigned WordPos = Prev / BITWORD_SIZE; | 
|  | unsigned BitPos = Prev % BITWORD_SIZE; | 
|  | BitWord Copy = Bits[WordPos]; | 
|  | // Mask off previous bits. | 
|  | Copy &= ~0L << BitPos; | 
|  |  | 
|  | if (Copy != 0) { | 
|  | if (sizeof(BitWord) == 4) | 
|  | return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy); | 
|  | else if (sizeof(BitWord) == 8) | 
|  | return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy); | 
|  | else | 
|  | assert(0 && "Unsupported!"); | 
|  | } | 
|  |  | 
|  | // Check subsequent words. | 
|  | for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i) | 
|  | if (Bits[i] != 0) { | 
|  | if (sizeof(BitWord) == 4) | 
|  | return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); | 
|  | else if (sizeof(BitWord) == 8) | 
|  | return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); | 
|  | else | 
|  | assert(0 && "Unsupported!"); | 
|  | } | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | /// clear - Clear all bits. | 
|  | void clear() { | 
|  | Size = 0; | 
|  | } | 
|  |  | 
|  | /// resize - Grow or shrink the bitvector. | 
|  | void resize(unsigned N, bool t = false) { | 
|  | if (N > Capacity * BITWORD_SIZE) { | 
|  | unsigned OldCapacity = Capacity; | 
|  | grow(N); | 
|  | init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t); | 
|  | } | 
|  |  | 
|  | // Set any old unused bits that are now included in the BitVector. This | 
|  | // may set bits that are not included in the new vector, but we will clear | 
|  | // them back out below. | 
|  | if (N > Size) | 
|  | set_unused_bits(t); | 
|  |  | 
|  | // Update the size, and clear out any bits that are now unused | 
|  | unsigned OldSize = Size; | 
|  | Size = N; | 
|  | if (t || N < OldSize) | 
|  | clear_unused_bits(); | 
|  | } | 
|  |  | 
|  | void reserve(unsigned N) { | 
|  | if (N > Capacity * BITWORD_SIZE) | 
|  | grow(N); | 
|  | } | 
|  |  | 
|  | // Set, reset, flip | 
|  | BitVector &set() { | 
|  | init_words(Bits, Capacity, true); | 
|  | clear_unused_bits(); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | BitVector &set(unsigned Idx) { | 
|  | Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | BitVector &reset() { | 
|  | init_words(Bits, Capacity, false); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | BitVector &reset(unsigned Idx) { | 
|  | Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE)); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | BitVector &flip() { | 
|  | for (unsigned i = 0; i < NumBitWords(size()); ++i) | 
|  | Bits[i] = ~Bits[i]; | 
|  | clear_unused_bits(); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | BitVector &flip(unsigned Idx) { | 
|  | Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | // No argument flip. | 
|  | BitVector operator~() const { | 
|  | return BitVector(*this).flip(); | 
|  | } | 
|  |  | 
|  | // Indexing. | 
|  | reference operator[](unsigned Idx) { | 
|  | assert (Idx < Size && "Out-of-bounds Bit access."); | 
|  | return reference(*this, Idx); | 
|  | } | 
|  |  | 
|  | bool operator[](unsigned Idx) const { | 
|  | assert (Idx < Size && "Out-of-bounds Bit access."); | 
|  | BitWord Mask = 1L << (Idx % BITWORD_SIZE); | 
|  | return (Bits[Idx / BITWORD_SIZE] & Mask) != 0; | 
|  | } | 
|  |  | 
|  | bool test(unsigned Idx) const { | 
|  | return (*this)[Idx]; | 
|  | } | 
|  |  | 
|  | // Comparison operators. | 
|  | bool operator==(const BitVector &RHS) const { | 
|  | unsigned ThisWords = NumBitWords(size()); | 
|  | unsigned RHSWords  = NumBitWords(RHS.size()); | 
|  | unsigned i; | 
|  | for (i = 0; i != std::min(ThisWords, RHSWords); ++i) | 
|  | if (Bits[i] != RHS.Bits[i]) | 
|  | return false; | 
|  |  | 
|  | // Verify that any extra words are all zeros. | 
|  | if (i != ThisWords) { | 
|  | for (; i != ThisWords; ++i) | 
|  | if (Bits[i]) | 
|  | return false; | 
|  | } else if (i != RHSWords) { | 
|  | for (; i != RHSWords; ++i) | 
|  | if (RHS.Bits[i]) | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool operator!=(const BitVector &RHS) const { | 
|  | return !(*this == RHS); | 
|  | } | 
|  |  | 
|  | // Intersection, union, disjoint union. | 
|  | BitVector &operator&=(const BitVector &RHS) { | 
|  | unsigned ThisWords = NumBitWords(size()); | 
|  | unsigned RHSWords  = NumBitWords(RHS.size()); | 
|  | unsigned i; | 
|  | for (i = 0; i != std::min(ThisWords, RHSWords); ++i) | 
|  | Bits[i] &= RHS.Bits[i]; | 
|  |  | 
|  | // Any bits that are just in this bitvector become zero, because they aren't | 
|  | // in the RHS bit vector.  Any words only in RHS are ignored because they | 
|  | // are already zero in the LHS. | 
|  | for (; i != ThisWords; ++i) | 
|  | Bits[i] = 0; | 
|  |  | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | BitVector &operator|=(const BitVector &RHS) { | 
|  | if (size() < RHS.size()) | 
|  | resize(RHS.size()); | 
|  | for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i) | 
|  | Bits[i] |= RHS.Bits[i]; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | BitVector &operator^=(const BitVector &RHS) { | 
|  | if (size() < RHS.size()) | 
|  | resize(RHS.size()); | 
|  | for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i) | 
|  | Bits[i] ^= RHS.Bits[i]; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | // Assignment operator. | 
|  | const BitVector &operator=(const BitVector &RHS) { | 
|  | if (this == &RHS) return *this; | 
|  |  | 
|  | Size = RHS.size(); | 
|  | unsigned RHSWords = NumBitWords(Size); | 
|  | if (Size <= Capacity * BITWORD_SIZE) { | 
|  | if (Size) | 
|  | std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord)); | 
|  | clear_unused_bits(); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | // Grow the bitvector to have enough elements. | 
|  | Capacity = RHSWords; | 
|  | BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); | 
|  | std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); | 
|  |  | 
|  | // Destroy the old bits. | 
|  | std::free(Bits); | 
|  | Bits = NewBits; | 
|  |  | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | void swap(BitVector &RHS) { | 
|  | std::swap(Bits, RHS.Bits); | 
|  | std::swap(Size, RHS.Size); | 
|  | std::swap(Capacity, RHS.Capacity); | 
|  | } | 
|  |  | 
|  | private: | 
|  | unsigned NumBitWords(unsigned S) const { | 
|  | return (S + BITWORD_SIZE-1) / BITWORD_SIZE; | 
|  | } | 
|  |  | 
|  | // Set the unused bits in the high words. | 
|  | void set_unused_bits(bool t = true) { | 
|  | //  Set high words first. | 
|  | unsigned UsedWords = NumBitWords(Size); | 
|  | if (Capacity > UsedWords) | 
|  | init_words(&Bits[UsedWords], (Capacity-UsedWords), t); | 
|  |  | 
|  | //  Then set any stray high bits of the last used word. | 
|  | unsigned ExtraBits = Size % BITWORD_SIZE; | 
|  | if (ExtraBits) { | 
|  | Bits[UsedWords-1] &= ~(~0L << ExtraBits); | 
|  | Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Clear the unused bits in the high words. | 
|  | void clear_unused_bits() { | 
|  | set_unused_bits(false); | 
|  | } | 
|  |  | 
|  | void grow(unsigned NewSize) { | 
|  | Capacity = std::max(NumBitWords(NewSize), Capacity * 2); | 
|  | Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord)); | 
|  |  | 
|  | clear_unused_bits(); | 
|  | } | 
|  |  | 
|  | void init_words(BitWord *B, unsigned NumWords, bool t) { | 
|  | memset(B, 0 - (int)t, NumWords*sizeof(BitWord)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) { | 
|  | BitVector Result(LHS); | 
|  | Result &= RHS; | 
|  | return Result; | 
|  | } | 
|  |  | 
|  | inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) { | 
|  | BitVector Result(LHS); | 
|  | Result |= RHS; | 
|  | return Result; | 
|  | } | 
|  |  | 
|  | inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) { | 
|  | BitVector Result(LHS); | 
|  | Result ^= RHS; | 
|  | return Result; | 
|  | } | 
|  |  | 
|  | } // End llvm namespace | 
|  |  | 
|  | namespace std { | 
|  | /// Implement std::swap in terms of BitVector swap. | 
|  | inline void | 
|  | swap(llvm::BitVector &LHS, llvm::BitVector &RHS) { | 
|  | LHS.swap(RHS); | 
|  | } | 
|  | } | 
|  |  | 
|  | #endif |