SmallBitVector.h revision e7962c9897cf3ac5fc731702d5e5d8963fc5c723
1cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===//
2cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//
3cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//                     The LLVM Compiler Infrastructure
4cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//
5cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman// This file is distributed under the University of Illinois Open Source
6cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman// License. See LICENSE.TXT for details.
7cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//
8cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//===----------------------------------------------------------------------===//
9cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//
10cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman// This file implements the SmallBitVector class.
11cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//
12cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman//===----------------------------------------------------------------------===//
13cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
14cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman#ifndef LLVM_ADT_SMALLBITVECTOR_H
15cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman#define LLVM_ADT_SMALLBITVECTOR_H
16cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
17cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman#include "llvm/ADT/BitVector.h"
18cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman#include "llvm/ADT/PointerIntPair.h"
19cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman#include "llvm/Support/MathExtras.h"
20cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman#include <cassert>
21cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
22cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmannamespace llvm {
23cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
24cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman/// SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array),
25cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman/// optimized for the case when the array is small.  It contains one
26cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman/// pointer-sized field, which is directly used as a plain collection of bits
27cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman/// when possible, or as a pointer to a larger heap-allocated array when
28cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman/// necessary.  This allows normal "small" cases to be fast without losing
29cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman/// generality for large inputs.
30cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman///
31cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmanclass SmallBitVector {
32cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // TODO: In "large" mode, a pointer to a BitVector is used, leading to an
33cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // unnecessary level of indirection. It would be more efficient to use a
34cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // pointer to memory containing size, allocation size, and the array of bits.
35cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  PointerIntPair<BitVector *, 1, uintptr_t> X;
36cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
37cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // The number of bits in this class.
38ad2cee44e02b4fa8d5888a80e39c01a9604b409eDan Gohman  static const size_t NumBaseBits = sizeof(uintptr_t) * CHAR_BIT;
39cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
40cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // One bit is used to discriminate between small and large mode. The
41cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // remaining bits are used for the small-mode representation.
42cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  static const size_t SmallNumRawBits = NumBaseBits - 1;
43cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
44cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // A few more bits are used to store the size of the bit set in small mode.
45cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Theoretically this is a ceil-log2. These bits are encoded in the most
46cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // significant bits of the raw bits.
47cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  static const size_t SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
48cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman                                          NumBaseBits == 64 ? 6 :
49cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman                                          SmallNumRawBits);
50cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
51cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // The remaining bits are used to store the actual set in small mode.
52cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  static const size_t SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits;
53cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
54cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool isSmall() const {
55cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.getInt();
56cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
57cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
58cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) {
59cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    X.setInt(true);
60cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    setSmallSize(NewSize);
61cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    setSmallBits(NewSmallBits);
62cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
63cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
64cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void switchToLarge(BitVector *BV) {
65cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    X.setInt(false);
66cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    X.setPointer(BV);
67cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
68cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
69cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Return all the bits used for the "small" representation; this includes
70cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // bits for the size as well as the element bits.
71cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  uintptr_t getSmallRawBits() const {
72cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return reinterpret_cast<uintptr_t>(X.getPointer()) >> 1;
73cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
74cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
75cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void setSmallRawBits(uintptr_t NewRawBits) {
76cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.setPointer(reinterpret_cast<BitVector *>(NewRawBits << 1));
77cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
78cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
79cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Return the size.
80cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  size_t getSmallSize() const {
81cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return getSmallRawBits() >> SmallNumDataBits;
82cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
83cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
84cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void setSmallSize(size_t Size) {
85cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
86cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
87cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
88cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Return the element bits.
89cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  uintptr_t getSmallBits() const {
90cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return getSmallRawBits() & ~(~uintptr_t(0) << SmallNumDataBits);
91cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
92cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
93cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void setSmallBits(uintptr_t NewBits) {
94cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    setSmallRawBits((getSmallRawBits() & (~uintptr_t(0) << SmallNumDataBits)) |
95cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman                    (NewBits & ~(~uintptr_t(0) << getSmallSize())));
96cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
97cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
98cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmanpublic:
99cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// SmallBitVector default ctor - Creates an empty bitvector.
100cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector() : X(0, 1) {}
101cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
102cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// SmallBitVector ctor - Creates a bitvector of specified number of bits. All
103cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// bits are initialized to the specified value.
104cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  explicit SmallBitVector(unsigned s, bool t = false) : X(0, 1) {
105cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (s <= SmallNumRawBits)
106cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      switchToSmall(t ? ~uintptr_t(0) : 0, s);
107cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
108cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      switchToLarge(new BitVector(s, t));
109cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
110cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
111cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// SmallBitVector copy ctor.
112cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector(const SmallBitVector &RHS) {
113cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (RHS.isSmall())
114cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X = RHS.X;
115cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
116cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      switchToLarge(new BitVector(*RHS.X.getPointer()));
117cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
118cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
119cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  ~SmallBitVector() {
120cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (!isSmall())
121cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      delete X.getPointer();
122cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
123cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
124cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// empty - Tests whether there are no bits in this bitvector.
125cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool empty() const {
126cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return isSmall() ? getSmallSize() == 0 : X.getPointer()->empty();
127cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
128cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
129cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// size - Returns the number of bits in this bitvector.
130cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  size_t size() const {
131cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return isSmall() ? getSmallSize() : X.getPointer()->size();
132cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
133cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
134cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// count - Returns the number of bits which are set.
135cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  unsigned count() const {
136cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall()) {
137cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      uintptr_t Bits = getSmallBits();
138cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (sizeof(uintptr_t) * CHAR_BIT == 32)
139cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        return CountPopulation_32(Bits);
140cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (sizeof(uintptr_t) * CHAR_BIT == 64)
141cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        return CountPopulation_64(Bits);
142cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      assert(0 && "Unsupported!");
143cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    }
144cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.getPointer()->count();
145cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
146cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
147cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// any - Returns true if any bit is set.
148cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool any() const {
149cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
150cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      return getSmallBits() != 0;
151cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.getPointer()->any();
152cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
153cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
154cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// none - Returns true if none of the bits are set.
155cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool none() const {
156cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
157cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      return getSmallBits() == 0;
158cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.getPointer()->none();
159cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
160cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
161cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// find_first - Returns the index of the first set bit, -1 if none
162cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// of the bits are set.
163cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  int find_first() const {
164cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall()) {
165cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      uintptr_t Bits = getSmallBits();
166cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (sizeof(uintptr_t) * CHAR_BIT == 32)
167cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        return CountTrailingZeros_32(Bits);
168cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (sizeof(uintptr_t) * CHAR_BIT == 64)
169cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        return CountTrailingZeros_64(Bits);
170cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      assert(0 && "Unsupported!");
171cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    }
172cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.getPointer()->find_first();
173cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
174cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
175cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// find_next - Returns the index of the next set bit following the
176cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// "Prev" bit. Returns -1 if the next set bit is not found.
177cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  int find_next(unsigned Prev) const {
178cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall()) {
179cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      uintptr_t Bits = getSmallBits();
180cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      // Mask off previous bits.
181cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      Bits &= ~uintptr_t(0) << Prev;
182cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (sizeof(uintptr_t) * CHAR_BIT == 32)
183cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        return CountTrailingZeros_32(Bits);
184cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (sizeof(uintptr_t) * CHAR_BIT == 64)
185cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        return CountTrailingZeros_64(Bits);
186cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      assert(0 && "Unsupported!");
187cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    }
188cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.getPointer()->find_next(Prev);
189cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
190cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
191cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// clear - Clear all bits.
192cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void clear() {
193cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (!isSmall())
194cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      delete X.getPointer();
195cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    switchToSmall(0, 0);
196cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
197cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
198cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// resize - Grow or shrink the bitvector.
199cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void resize(unsigned N, bool t = false) {
200cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (!isSmall()) {
201cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->resize(N, t);
202cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    } else if (getSmallSize() >= N) {
203cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallSize(N);
204cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallBits(getSmallBits());
205cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    } else {
206cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      BitVector *BV = new BitVector(N, t);
207cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      uintptr_t OldBits = getSmallBits();
208cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      for (size_t i = 0, e = getSmallSize(); i != e; ++i)
209cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        (*BV)[i] = (OldBits >> i) & 1;
210cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      switchToLarge(BV);
211cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    }
212cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
213cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
214cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void reserve(unsigned N) {
215cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall()) {
216cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (N > SmallNumDataBits) {
217cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        uintptr_t OldBits = getSmallRawBits();
218cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        size_t SmallSize = getSmallSize();
219cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        BitVector *BV = new BitVector(SmallSize);
220cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        for (size_t i = 0; i < SmallSize; ++i)
221cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman          if ((OldBits >> i) & 1)
222cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman            BV->set(i);
223cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        BV->reserve(N);
224cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        switchToLarge(BV);
225cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      }
226cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    } else {
227cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->reserve(N);
228cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    }
229cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
230cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
231cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Set, reset, flip
232cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector &set() {
233cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
234cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallBits(~uintptr_t(0));
235cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
236cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->set();
237cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return *this;
238cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
239cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
240cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector &set(unsigned Idx) {
241cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
242cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
243cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
244cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->set(Idx);
245cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return *this;
246cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
247cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
248cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector &reset() {
249cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
250cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallBits(0);
251cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
252cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->reset();
253cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return *this;
254cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
255cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
256cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector &reset(unsigned Idx) {
257cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
258cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
259cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
260cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->reset(Idx);
261cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return *this;
262cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
263cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
264cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector &flip() {
265cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
266cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallBits(~getSmallBits());
267cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
268cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->flip();
269cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return *this;
270cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
271cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
272cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector &flip(unsigned Idx) {
273cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
274cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
275cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
276cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      X.getPointer()->flip(Idx);
277cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return *this;
278cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
279cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
280cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // No argument flip.
281cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector operator~() const {
282cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return SmallBitVector(*this).flip();
283cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
284cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
285cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Indexing.
286cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // TODO: Add an index operator which returns a "reference" (proxy class).
287cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool operator[](unsigned Idx) const {
288cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    assert(Idx < size() && "Out-of-bounds Bit access.");
289cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
290cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      return ((getSmallBits() >> Idx) & 1) != 0;
291cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return X.getPointer()->operator[](Idx);
292cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
293cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
294cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool test(unsigned Idx) const {
295cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return (*this)[Idx];
296cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
297cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
298cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Comparison operators.
299cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool operator==(const SmallBitVector &RHS) const {
300cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (size() != RHS.size())
301cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      return false;
302cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall())
303cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      return getSmallBits() == RHS.getSmallBits();
304cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    else
305cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      return *X.getPointer() == *RHS.X.getPointer();
306cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
307cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
308cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  bool operator!=(const SmallBitVector &RHS) const {
309cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return !(*this == RHS);
310cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
311cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
312cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Intersection, union, disjoint union.
313e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman  SmallBitVector &operator&=(const SmallBitVector &RHS) {
314e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    resize(std::max(size(), RHS.size()));
315e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    if (isSmall())
316e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      setSmallBits(getSmallBits() & RHS.getSmallBits());
317e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    else if (!RHS.isSmall())
318e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      X.getPointer()->operator&=(*RHS.X.getPointer());
319e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    else {
320e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      SmallBitVector Copy = RHS;
321e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      Copy.resize(size());
322e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      X.getPointer()->operator&=(*Copy.X.getPointer());
323e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    }
324e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    return *this;
325e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman  }
326cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
327e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman  SmallBitVector &operator|=(const SmallBitVector &RHS) {
328e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    resize(std::max(size(), RHS.size()));
329e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    if (isSmall())
330e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      setSmallBits(getSmallBits() | RHS.getSmallBits());
331e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    else if (!RHS.isSmall())
332e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      X.getPointer()->operator|=(*RHS.X.getPointer());
333e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    else {
334e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      SmallBitVector Copy = RHS;
335e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      Copy.resize(size());
336e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      X.getPointer()->operator|=(*Copy.X.getPointer());
337e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    }
338e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    return *this;
339e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman  }
340cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
341e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman  SmallBitVector &operator^=(const SmallBitVector &RHS) {
342e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    resize(std::max(size(), RHS.size()));
343e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    if (isSmall())
344e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      setSmallBits(getSmallBits() ^ RHS.getSmallBits());
345e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    else if (!RHS.isSmall())
346e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      X.getPointer()->operator^=(*RHS.X.getPointer());
347e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    else {
348e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      SmallBitVector Copy = RHS;
349e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      Copy.resize(size());
350e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman      X.getPointer()->operator^=(*Copy.X.getPointer());
351e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    }
352e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman    return *this;
353e7962c9897cf3ac5fc731702d5e5d8963fc5c723Dan Gohman  }
354cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
355cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  // Assignment operator.
356cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  const SmallBitVector &operator=(const SmallBitVector &RHS) {
357cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    if (isSmall()) {
358cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (RHS.isSmall())
359cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        X = RHS.X;
360cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      else
361cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        switchToLarge(new BitVector(*RHS.X.getPointer()));
362cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    } else {
363cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      if (!RHS.isSmall())
364cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        *X.getPointer() = *RHS.X.getPointer();
365cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      else {
366cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        delete X.getPointer();
367cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman        X = RHS.X;
368cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman      }
369cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    }
370cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    return *this;
371cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
372cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
373cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  void swap(SmallBitVector &RHS) {
374cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    std::swap(X, RHS.X);
375cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
376cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman};
377cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
378cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmaninline SmallBitVector
379cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmanoperator&(const SmallBitVector &LHS, const SmallBitVector &RHS) {
380cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector Result(LHS);
381cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  Result &= RHS;
382cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  return Result;
383cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman}
384cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
385cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmaninline SmallBitVector
386cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmanoperator|(const SmallBitVector &LHS, const SmallBitVector &RHS) {
387cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector Result(LHS);
388cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  Result |= RHS;
389cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  return Result;
390cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman}
391cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
392cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmaninline SmallBitVector
393cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmanoperator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
394cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  SmallBitVector Result(LHS);
395cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  Result ^= RHS;
396cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  return Result;
397cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman}
398cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
399cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman} // End llvm namespace
400cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
401cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohmannamespace std {
402cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  /// Implement std::swap in terms of BitVector swap.
403cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  inline void
404cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
405cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman    LHS.swap(RHS);
406cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman  }
407cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman}
408cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman
409cb89afc965c66029ae38712d1c52f5bbe4dee942Dan Gohman#endif
410