X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FBitVector.h;h=f58dd7356c7dd093e8550701260d306ce1a8e3ca;hb=746609067cd66b2f10acd592acd0b2fea3669567;hp=df896b98f4db3870a9fb287a475c821266d8047d;hpb=1144af3c9b4da48cd581156e05b24261c8de366a;p=oota-llvm.git diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index df896b98f4d..f58dd7356c7 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -29,11 +29,15 @@ class BitVector { enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT }; + static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32, + "Unsupported word size"); + BitWord *Bits; // Actual bits. unsigned Size; // Size of bitvector in bits. unsigned Capacity; // Size of allocated memory in BitWord. public: + typedef unsigned size_type; // Encapsulation of a single bit. class reference { friend class BitVector; @@ -49,7 +53,7 @@ public: BitPos = Idx % BITWORD_SIZE; } - ~reference() {} + reference(const reference&) = default; reference &operator=(reference t) { *this = bool(t); @@ -58,21 +62,21 @@ public: reference& operator=(bool t) { if (t) - *WordRef |= 1L << BitPos; + *WordRef |= BitWord(1) << BitPos; else - *WordRef &= ~(1L << BitPos); + *WordRef &= ~(BitWord(1) << BitPos); return *this; } operator bool() const { - return ((*WordRef) & (1L << BitPos)) ? true : false; + return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false; } }; /// BitVector default ctor - Creates an empty bitvector. BitVector() : Size(0), Capacity(0) { - Bits = 0; + Bits = nullptr; } /// BitVector ctor - Creates a bitvector of specified number of bits. All @@ -88,7 +92,7 @@ public: /// BitVector copy ctor. BitVector(const BitVector &RHS) : Size(RHS.size()) { if (Size == 0) { - Bits = 0; + Bits = nullptr; Capacity = 0; return; } @@ -98,12 +102,10 @@ public: std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); } -#if LLVM_USE_RVALUE_REFERENCES BitVector(BitVector &&RHS) : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { - RHS.Bits = 0; + RHS.Bits = nullptr; } -#endif ~BitVector() { std::free(Bits); @@ -113,18 +115,13 @@ public: bool empty() const { return Size == 0; } /// size - Returns the number of bits in this bitvector. - unsigned size() const { return Size; } + size_type size() const { return Size; } /// count - Returns the number of bits which are set. - unsigned count() const { + size_type 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 - llvm_unreachable("Unsupported!"); + NumBits += countPopulation(Bits[i]); return NumBits; } @@ -138,8 +135,15 @@ public: /// all - Returns true if all bits are set. bool all() const { - // TODO: Optimize this. - return count() == size(); + for (unsigned i = 0; i < Size / BITWORD_SIZE; ++i) + if (Bits[i] != ~0UL) + return false; + + // If bits remain check that they are ones. The unused bits are always zero. + if (unsigned Remainder = Size % BITWORD_SIZE) + return Bits[Size / BITWORD_SIZE] == (1UL << Remainder) - 1; + + return true; } /// none - Returns true if none of the bits are set. @@ -151,13 +155,8 @@ public: /// 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]); - if (sizeof(BitWord) == 8) - return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); - llvm_unreachable("Unsupported!"); - } + if (Bits[i] != 0) + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); return -1; } @@ -174,23 +173,13 @@ public: // Mask off previous bits. Copy &= ~0UL << BitPos; - if (Copy != 0) { - if (sizeof(BitWord) == 4) - return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy); - if (sizeof(BitWord) == 8) - return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy); - llvm_unreachable("Unsupported!"); - } + if (Copy != 0) + return WordPos * BITWORD_SIZE + countTrailingZeros(Copy); // 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]); - if (sizeof(BitWord) == 8) - return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); - llvm_unreachable("Unsupported!"); - } + if (Bits[i] != 0) + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); return -1; } @@ -233,7 +222,37 @@ public: } BitVector &set(unsigned Idx) { - Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE); + assert(Bits && "Bits never allocated"); + Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE); + return *this; + } + + /// set - Efficiently set a range of bits in [I, E) + BitVector &set(unsigned I, unsigned E) { + assert(I <= E && "Attempted to set backwards range!"); + assert(E <= size() && "Attempted to set out-of-bounds range!"); + + if (I == E) return *this; + + if (I / BITWORD_SIZE == E / BITWORD_SIZE) { + BitWord EMask = 1UL << (E % BITWORD_SIZE); + BitWord IMask = 1UL << (I % BITWORD_SIZE); + BitWord Mask = EMask - IMask; + Bits[I / BITWORD_SIZE] |= Mask; + return *this; + } + + BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); + Bits[I / BITWORD_SIZE] |= PrefixMask; + I = RoundUpToAlignment(I, BITWORD_SIZE); + + for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) + Bits[I / BITWORD_SIZE] = ~0UL; + + BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; + if (I < E) + Bits[I / BITWORD_SIZE] |= PostfixMask; + return *this; } @@ -243,7 +262,36 @@ public: } BitVector &reset(unsigned Idx) { - Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE)); + Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE)); + return *this; + } + + /// reset - Efficiently reset a range of bits in [I, E) + BitVector &reset(unsigned I, unsigned E) { + assert(I <= E && "Attempted to reset backwards range!"); + assert(E <= size() && "Attempted to reset out-of-bounds range!"); + + if (I == E) return *this; + + if (I / BITWORD_SIZE == E / BITWORD_SIZE) { + BitWord EMask = 1UL << (E % BITWORD_SIZE); + BitWord IMask = 1UL << (I % BITWORD_SIZE); + BitWord Mask = EMask - IMask; + Bits[I / BITWORD_SIZE] &= ~Mask; + return *this; + } + + BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); + Bits[I / BITWORD_SIZE] &= ~PrefixMask; + I = RoundUpToAlignment(I, BITWORD_SIZE); + + for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) + Bits[I / BITWORD_SIZE] = 0UL; + + BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; + if (I < E) + Bits[I / BITWORD_SIZE] &= ~PostfixMask; + return *this; } @@ -255,7 +303,7 @@ public: } BitVector &flip(unsigned Idx) { - Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE); + Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE); return *this; } @@ -267,7 +315,7 @@ public: bool operator[](unsigned Idx) const { assert (Idx < Size && "Out-of-bounds Bit access."); - BitWord Mask = 1L << (Idx % BITWORD_SIZE); + BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE); return (Bits[Idx / BITWORD_SIZE] & Mask) != 0; } @@ -311,7 +359,7 @@ public: return !(*this == RHS); } - // Intersection, union, disjoint union. + /// Intersection, union, disjoint union. BitVector &operator&=(const BitVector &RHS) { unsigned ThisWords = NumBitWords(size()); unsigned RHSWords = NumBitWords(RHS.size()); @@ -328,7 +376,7 @@ public: return *this; } - // reset - Reset bits that are set in RHS. Same as *this &= ~RHS. + /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS. BitVector &reset(const BitVector &RHS) { unsigned ThisWords = NumBitWords(size()); unsigned RHSWords = NumBitWords(RHS.size()); @@ -338,6 +386,23 @@ public: return *this; } + /// test - Check if (This - RHS) is zero. + /// This is the same as reset(RHS) and any(). + bool test(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]) != 0) + return true; + + for (; i != ThisWords ; ++i) + if (Bits[i] != 0) + return true; + + return false; + } + BitVector &operator|=(const BitVector &RHS) { if (size() < RHS.size()) resize(RHS.size()); @@ -369,6 +434,7 @@ public: // Grow the bitvector to have enough elements. Capacity = RHSWords; + assert(Capacity > 0 && "negative capacity?"); BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); @@ -379,7 +445,6 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES const BitVector &operator=(BitVector &&RHS) { if (this == &RHS) return *this; @@ -388,11 +453,10 @@ public: Size = RHS.Size; Capacity = RHS.Capacity; - RHS.Bits = 0; + RHS.Bits = nullptr; return *this; } -#endif void swap(BitVector &RHS) { std::swap(Bits, RHS.Bits); @@ -466,6 +530,7 @@ private: void grow(unsigned NewSize) { Capacity = std::max(NumBitWords(NewSize), Capacity * 2); + assert(Capacity > 0 && "realloc-ing zero space"); Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord)); clear_unused_bits(); @@ -477,7 +542,7 @@ private: template void applyMask(const uint32_t *Mask, unsigned MaskWords) { - assert(BITWORD_SIZE % 32 == 0 && "Unsupported BitWord size."); + static_assert(BITWORD_SIZE % 32 == 0, "Unsupported BitWord size."); MaskWords = std::min(MaskWords, (size() + 31) / 32); const unsigned Scale = BITWORD_SIZE / 32; unsigned i;