Static Value-Flow Analysis
Classes | Public Types | Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | List of all members
SVF::CoreBitVector Class Reference

#include <CoreBitVector.h>

Inheritance diagram for SVF::CoreBitVector:
SVF::BitVector

Classes

class  CoreBitVectorIterator
 

Public Types

typedef unsigned long long Word
 
typedef CoreBitVectorIterator const_iterator
 
typedef const_iterator iterator
 

Public Member Functions

 CoreBitVector (void)
 Construct empty CBV. More...
 
 CoreBitVector (size_t n)
 Construct empty CBV with space reserved for n Words. More...
 
 CoreBitVector (const CoreBitVector &cbv)
 Copy constructor. More...
 
 CoreBitVector (CoreBitVector &&cbv)
 Move constructor. More...
 
CoreBitVectoroperator= (const CoreBitVector &rhs)
 Copy assignment. More...
 
CoreBitVectoroperator= (CoreBitVector &&rhs)
 Move assignment. More...
 
bool empty (void) const
 Returns true if no bits are set. More...
 
u32_t count (void) const
 Returns number of bits set. More...
 
void clear (void)
 Empty the CBV. More...
 
bool test (u32_t bit) const
 Returns true if bit is set in this CBV. More...
 
bool test_and_set (u32_t bit)
 
void set (u32_t bit)
 Sets bit in the CBV. More...
 
void reset (u32_t bit)
 Resets bit in the CBV. More...
 
bool contains (const CoreBitVector &rhs) const
 Returns true if this CBV is a superset of rhs. More...
 
bool intersects (const CoreBitVector &rhs) const
 Returns true if this CBV and rhs share any set bits. More...
 
bool operator== (const CoreBitVector &rhs) const
 Returns true if this CBV and rhs have the same bits set. More...
 
bool operator!= (const CoreBitVector &rhs) const
 Returns true if either this CBV or rhs has a bit set unique to the other. More...
 
bool operator|= (const CoreBitVector &rhs)
 
bool operator&= (const CoreBitVector &rhs)
 
bool operator-= (const CoreBitVector &rhs)
 
bool intersectWithComplement (const CoreBitVector &rhs)
 
void intersectWithComplement (const CoreBitVector &lhs, const CoreBitVector &rhs)
 Put intersection of lhs with complement of rhs into this CBV. More...
 
size_t hash (void) const
 Hash for this CBV. More...
 
const_iterator begin (void) const
 
const_iterator end (void) const
 

Static Public Attributes

static const size_t WordSize = sizeof(Word) * CHAR_BIT
 

Private Member Functions

void extendBackward (u32_t bit)
 Add enough words (prepend) to be able to include bit. More...
 
void extendForward (u32_t bit)
 Add enough words (append) to be able to include bit. More...
 
void extendTo (u32_t bit)
 Add enough words (append xor prepend) to be able to include bit. More...
 
size_t indexForBit (u32_t bit) const
 Returns the index into words which would hold bit. More...
 
bool canHold (u32_t bit) const
 Returns true if bit can fit in this CBV without resizing. More...
 
u32_t finalBit (void) const
 Returns the last bit that this CBV can hold. More...
 
u32_t firstCommonBit (const CoreBitVector &rhs) const
 Returns the first bit position that both this CBV and rhs can hold. More...
 
size_t nextSetIndex (const size_t start) const
 

Private Attributes

u32_t offset
 The first bit of the first word. More...
 
std::vector< Wordwords
 Our actual bit vector. More...
 

Detailed Description

A contiguous bit vector that only contains what it needs according to the operations carried. For example, when two bit vectors are unioned, their sizes may be increased to fit all the bits from the other set. This implementation never shrinks. Since points-to sets (generally) grow monotonically, does not have too big an impact on points-to analysis and so it isn't implemented. Abbreviated CBV.

Definition at line 30 of file CoreBitVector.h.

Member Typedef Documentation

◆ const_iterator

Definition at line 37 of file CoreBitVector.h.

◆ iterator

Definition at line 38 of file CoreBitVector.h.

◆ Word

typedef unsigned long long SVF::CoreBitVector::Word

Definition at line 33 of file CoreBitVector.h.

Constructor & Destructor Documentation

◆ CoreBitVector() [1/4]

SVF::CoreBitVector::CoreBitVector ( void  )

Construct empty CBV.

Definition at line 24 of file CoreBitVector.cpp.

25  : CoreBitVector(0) { }
CoreBitVector(void)
Construct empty CBV.

◆ CoreBitVector() [2/4]

SVF::CoreBitVector::CoreBitVector ( size_t  n)

Construct empty CBV with space reserved for n Words.

Definition at line 27 of file CoreBitVector.cpp.

28  : offset(0), words(n, 0) { }
cJSON * n
Definition: cJSON.cpp:2558
u32_t offset
The first bit of the first word.
std::vector< Word > words
Our actual bit vector.

◆ CoreBitVector() [3/4]

SVF::CoreBitVector::CoreBitVector ( const CoreBitVector cbv)

Copy constructor.

Definition at line 30 of file CoreBitVector.cpp.

31  : offset(cbv.offset), words(cbv.words) { }

◆ CoreBitVector() [4/4]

SVF::CoreBitVector::CoreBitVector ( CoreBitVector &&  cbv)

Move constructor.

Definition at line 33 of file CoreBitVector.cpp.

34  : offset(cbv.offset), words(std::move(cbv.words)) { }
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447

Member Function Documentation

◆ begin()

CoreBitVector::const_iterator SVF::CoreBitVector::begin ( void  ) const

Definition at line 315 of file CoreBitVector.cpp.

316 {
317  return CoreBitVectorIterator(this);
318 }

◆ canHold()

bool SVF::CoreBitVector::canHold ( u32_t  bit) const
private

Returns true if bit can fit in this CBV without resizing.

Definition at line 366 of file CoreBitVector.cpp.

367 {
368  return bit >= offset && bit < offset + words.size() * WordSize;
369 }
static const size_t WordSize
Definition: CoreBitVector.h:34

◆ clear()

void SVF::CoreBitVector::clear ( void  )

Empty the CBV.

Definition at line 65 of file CoreBitVector.cpp.

66 {
67  offset = 0;
68  words.clear();
69  words.shrink_to_fit();
70 }

◆ contains()

bool SVF::CoreBitVector::contains ( const CoreBitVector rhs) const

Returns true if this CBV is a superset of rhs.

Definition at line 105 of file CoreBitVector.cpp.

106 {
107  CoreBitVector tmp(*this);
108  tmp &= rhs;
109  return tmp == rhs;
110 }

◆ count()

u32_t SVF::CoreBitVector::count ( void  ) const

Returns number of bits set.

Definition at line 58 of file CoreBitVector.cpp.

59 {
60  u32_t n = 0;
61  for (const Word &w : words) n += countPopulation(w);
62  return n;
63 }
unsigned u32_t
Definition: CommandLine.h:18
unsigned long long Word
Definition: CoreBitVector.h:33
unsigned countPopulation(T Value)

◆ empty()

bool SVF::CoreBitVector::empty ( void  ) const

Returns true if no bits are set.

Definition at line 50 of file CoreBitVector.cpp.

51 {
52  for (const Word& w : words)
53  if (w)
54  return false;
55  return true;
56 }

◆ end()

CoreBitVector::const_iterator SVF::CoreBitVector::end ( void  ) const

Definition at line 310 of file CoreBitVector.cpp.

311 {
312  return CoreBitVectorIterator(this, true);
313 }

◆ extendBackward()

void SVF::CoreBitVector::extendBackward ( u32_t  bit)
private

Add enough words (prepend) to be able to include bit.

Definition at line 320 of file CoreBitVector.cpp.

321 {
322  // New offset is the starting bit of the word which contains bit.
323  u32_t newOffset = (bit / WordSize) * WordSize;
324 
325  // TODO: maybe assertions?
326  // Check if bit can already be included in this BV or if it's extendForward's problem.
327  if (newOffset >= offset) return;
328 
329  words.insert(words.begin(), (offset - newOffset) / WordSize, 0);
330  offset = newOffset;
331 }

◆ extendForward()

void SVF::CoreBitVector::extendForward ( u32_t  bit)
private

Add enough words (append) to be able to include bit.

Definition at line 333 of file CoreBitVector.cpp.

334 {
335  // TODO: maybe assertions?
336  // Not our problem; extendBackward's problem, or there is nothing to do.
337  if (bit < offset || canHold(bit)) return;
338 
339  // Starting bit of word which would contain bit.
340  u32_t bitsWord = (bit / WordSize) * WordSize;
341 
342  // Add 1 to represent the final word starting at bitsWord.
343  u32_t wordsToAdd = 1 + (bitsWord - words.size() * WordSize - offset) / WordSize;
344  words.insert(words.end(), wordsToAdd, 0);
345 }
bool canHold(u32_t bit) const
Returns true if bit can fit in this CBV without resizing.

◆ extendTo()

void SVF::CoreBitVector::extendTo ( u32_t  bit)
private

Add enough words (append xor prepend) to be able to include bit.

Definition at line 347 of file CoreBitVector.cpp.

348 {
349  if (offset == 0 && words.size() == 0)
350  {
351  offset = (bit / WordSize) * WordSize;
352  words.push_back(0);
353  }
354  else if (bit < offset) extendBackward(bit);
355  else if (bit >= offset + words.size() * WordSize) extendForward(bit);
356 }
void extendForward(u32_t bit)
Add enough words (append) to be able to include bit.
void extendBackward(u32_t bit)
Add enough words (prepend) to be able to include bit.

◆ finalBit()

u32_t SVF::CoreBitVector::finalBit ( void  ) const
private

Returns the last bit that this CBV can hold.

Definition at line 371 of file CoreBitVector.cpp.

372 {
373  return offset + words.size() * WordSize - 1;
374 }

◆ firstCommonBit()

u32_t SVF::CoreBitVector::firstCommonBit ( const CoreBitVector rhs) const
private

Returns the first bit position that both this CBV and rhs can hold.

◆ hash()

size_t SVF::CoreBitVector::hash ( void  ) const

Hash for this CBV.

Definition at line 298 of file CoreBitVector.cpp.

299 {
300  // From https://stackoverflow.com/a/27216842
301  size_t h = words.size();
302  for (const Word &w : words)
303  {
304  h ^= w + 0x9e3779b9 + (h << 6) + (h >> 2);
305  }
306 
307  return h + offset;
308 }

◆ indexForBit()

size_t SVF::CoreBitVector::indexForBit ( u32_t  bit) const
private

Returns the index into words which would hold bit.

Definition at line 358 of file CoreBitVector.cpp.

359 {
360  assert(canHold(bit));
361  // Recall, offset (and the bits in that word) are represented by words[0],
362  // so solve (offset + x) / WordSize == 0... x == -offset.
363  return (bit - offset) / WordSize;
364 }

◆ intersects()

bool SVF::CoreBitVector::intersects ( const CoreBitVector rhs) const

Returns true if this CBV and rhs share any set bits.

Definition at line 112 of file CoreBitVector.cpp.

113 {
114  // TODO: want some common iteration method.
115  if (empty() && rhs.empty()) return false;
116 
117  const CoreBitVector &earlierOffsetCBV = offset <= rhs.offset ? *this : rhs;
118  const CoreBitVector &laterOffsetCBV = offset <= rhs.offset ? rhs : *this;
119 
120  size_t earlierOffset = (offset < rhs.offset ? offset : rhs.offset) / WordSize;
121  size_t laterOffset = (offset > rhs.offset ? offset : rhs.offset) / WordSize;
122  laterOffset -= earlierOffset;
123 
124  const Word *eWords = &earlierOffsetCBV.words[0];
125  const size_t eSize = earlierOffsetCBV.words.size();
126  const Word *lWords = &laterOffsetCBV.words[0];
127  const size_t lSize = laterOffsetCBV.words.size();
128 
129  size_t e = 0;
130  for ( ; e != laterOffset && e != eSize; ++e) { }
131 
132  size_t l = 0;
133  for ( ; e != eSize && l != lSize; ++e, ++l)
134  {
135  if (eWords[e] & lWords[l]) return true;
136  }
137 
138  return false;
139 }
bool empty(void) const
Returns true if no bits are set.

◆ intersectWithComplement() [1/2]

void SVF::CoreBitVector::intersectWithComplement ( const CoreBitVector lhs,
const CoreBitVector rhs 
)

Put intersection of lhs with complement of rhs into this CBV.

Definition at line 291 of file CoreBitVector.cpp.

292 {
293  // TODO: inefficient!
294  *this = lhs;
296 }
bool intersectWithComplement(const CoreBitVector &rhs)

◆ intersectWithComplement() [2/2]

bool SVF::CoreBitVector::intersectWithComplement ( const CoreBitVector rhs)

Put intersection of this CBV with complement of rhs into this CBV. Returns true if this CBV changed.

Definition at line 286 of file CoreBitVector.cpp.

287 {
288  return *this -= rhs;
289 }

◆ nextSetIndex()

size_t SVF::CoreBitVector::nextSetIndex ( const size_t  start) const
private

Returns the next index in the words array at or after start which contains set bits. This index and start are indices into the words array not accounting for the offset. Returns a value greater than or equal to words.size() when there are no more set bits.

Definition at line 376 of file CoreBitVector.cpp.

377 {
378  size_t index = start;
379  for ( ; index < words.size(); ++index)
380  {
381  if (words[index]) break;
382  }
383 
384  return index;
385 }
int index
Definition: cJSON.h:170

◆ operator!=()

bool SVF::CoreBitVector::operator!= ( const CoreBitVector rhs) const

Returns true if either this CBV or rhs has a bit set unique to the other.

Definition at line 169 of file CoreBitVector.cpp.

170 {
171  return !(*this == rhs);
172 }

◆ operator&=()

bool SVF::CoreBitVector::operator&= ( const CoreBitVector rhs)

Put intersection of this CBV and rhs into this CBV. Returns true if CBV changed.

Definition at line 214 of file CoreBitVector.cpp.

215 {
216  // The first bit this and rhs have in common is the greater of
217  // their offsets if the CBV with the smaller offset can hold
218  // the greater offset.
219  u32_t greaterOffset = std::max(offset, rhs.offset);
220 
221  // If there is no overlap, then clear this CBV.
222  if (!canHold(greaterOffset) || !rhs.canHold(greaterOffset))
223  {
224  bool changed = false;
225  for (size_t i = 0; i < words.size(); ++i)
226  {
227  if (!changed) changed = words[i] != 0;
228  words[i] = 0;
229  }
230 
231  return changed;
232  }
233 
234  bool changed = false;
235  size_t thisIndex = indexForBit(greaterOffset);
236  size_t rhsIndex = rhs.indexForBit(greaterOffset);
237 
238  // Clear everything before the overlapping part.
239  for (size_t i = 0; i < thisIndex; ++i)
240  {
241  if (!changed) changed = words[i] != 0;
242  words[i] = 0;
243  }
244 
245  Word oldWord;
246  for ( ; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex)
247  {
248  if (!changed) oldWord = words[thisIndex];
249  words[thisIndex] &= rhs.words[rhsIndex];
250  if (!changed) changed = oldWord != words[thisIndex];
251  }
252 
253  // Clear the remaining bits with no rhs analogue.
254  for ( ; thisIndex < words.size(); ++thisIndex)
255  {
256  if (!changed && words[thisIndex] != 0) changed = true;
257  words[thisIndex] = 0;
258  }
259 
260  return changed;
261 }
size_t indexForBit(u32_t bit) const
Returns the index into words which would hold bit.

◆ operator-=()

bool SVF::CoreBitVector::operator-= ( const CoreBitVector rhs)

Remove set bits in rhs from this CBV. Returns true if CBV changed.

Definition at line 263 of file CoreBitVector.cpp.

264 {
265  // Similar to |= in that we only iterate over rhs within this, but we
266  // don't need to extend anything since nothing from rhs is being added.
267  u32_t greaterOffset = std::max(offset, rhs.offset);
268  // TODO: calling twice.
269  // No overlap if either cannot hold the greater offset.
270  if (!canHold(greaterOffset) || !rhs.canHold(greaterOffset)) return false;
271 
272  bool changed = false;
273  size_t thisIndex = indexForBit(greaterOffset);
274  size_t rhsIndex = rhs.indexForBit(greaterOffset);
275  Word oldWord;
276  for ( ; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex)
277  {
278  if (!changed) oldWord = words[thisIndex];
279  words[thisIndex] &= ~rhs.words[rhsIndex];
280  if (!changed) changed = oldWord != words[thisIndex];
281  }
282 
283  return changed;
284 }

◆ operator=() [1/2]

CoreBitVector & SVF::CoreBitVector::operator= ( const CoreBitVector rhs)

Copy assignment.

Definition at line 36 of file CoreBitVector.cpp.

37 {
38  this->offset = rhs.offset;
39  this->words = rhs.words;
40  return *this;
41 }

◆ operator=() [2/2]

CoreBitVector & SVF::CoreBitVector::operator= ( CoreBitVector &&  rhs)

Move assignment.

Definition at line 43 of file CoreBitVector.cpp.

44 {
45  this->offset = rhs.offset;
46  this->words = std::move(rhs.words);
47  return *this;
48 }

◆ operator==()

bool SVF::CoreBitVector::operator== ( const CoreBitVector rhs) const

Returns true if this CBV and rhs have the same bits set.

Definition at line 141 of file CoreBitVector.cpp.

142 {
143  if (this == &rhs) return true;
144 
145  // TODO: maybe a simple equal offset, equal size path?
146 
147  size_t lhsSetIndex = nextSetIndex(0);
148  size_t rhsSetIndex = rhs.nextSetIndex(0);
149  // Iterate comparing only words with set bits, if there is ever a mismatch,
150  // then the bit-vectors aren't equal.
151  while (lhsSetIndex < words.size() && rhsSetIndex < rhs.words.size())
152  {
153  // If the first bit is not the same in the word or words are different,
154  // then we have a mismatch.
155  if (lhsSetIndex * WordSize + offset != rhsSetIndex * WordSize + rhs.offset
156  || words[lhsSetIndex] != rhs.words[rhsSetIndex])
157  {
158  return false;
159  }
160 
161  lhsSetIndex = nextSetIndex(lhsSetIndex + 1);
162  rhsSetIndex = rhs.nextSetIndex(rhsSetIndex + 1);
163  }
164 
165  // Make sure both got to the end at the same time.
166  return lhsSetIndex >= words.size() && rhsSetIndex >= rhs.words.size();
167 }
size_t nextSetIndex(const size_t start) const

◆ operator|=()

bool SVF::CoreBitVector::operator|= ( const CoreBitVector rhs)

Put union of this CBV and rhs into this CBV. Returns true if CBV changed.

Definition at line 174 of file CoreBitVector.cpp.

175 {
176  if (words.size() == 0)
177  {
178  *this = rhs;
179  return words.size() != 0;
180  }
181 
182  if (rhs.words.size() == 0) return false;
183 
184  if (this == &rhs) return false;
185 
186  // TODO: some redundancy in extendTo calls.
187  if (finalBit() < rhs.finalBit()) extendForward(rhs.finalBit());
188  if (offset > rhs.offset) extendBackward(rhs.offset);
189 
190  // Start counting this where rhs starts.
191  const size_t thisIndex = indexForBit(rhs.offset);
192  size_t rhsIndex = 0;
193 
194  // Only need to test against rhs's size since we extended this to hold rhs.
195  Word *thisWords = &words[thisIndex];
196  const Word *rhsWords = &rhs.words[rhsIndex];
197  const size_t length = rhs.words.size();
198  Word changed = 0;
199 
200  // Can start counting from 0 because we took the addresses of both
201  // word vectors at the correct index.
202  // #pragma omp simd
203  for (size_t i = 0 ; i < length; ++i)
204  {
205  const Word oldWord = thisWords[i];
206  // Is there anything in rhs not in *this?
207  thisWords[i] = thisWords[i] | rhsWords[i];
208  changed |= oldWord ^ thisWords[i];
209  }
210 
211  return changed;
212 }
char const int length
Definition: cJSON.h:163
u32_t finalBit(void) const
Returns the last bit that this CBV can hold.

◆ reset()

void SVF::CoreBitVector::reset ( u32_t  bit)

Resets bit in the CBV.

Definition at line 97 of file CoreBitVector.cpp.

98 {
99  if (bit < offset || bit >= offset + words.size() * WordSize) return;
100  Word &containingWord = words[(bit - offset) / WordSize];
101  Word mask = ~((Word)0b1 << (bit % WordSize));
102  containingWord &= mask;
103 }

◆ set()

void SVF::CoreBitVector::set ( u32_t  bit)

Sets bit in the CBV.

Definition at line 88 of file CoreBitVector.cpp.

89 {
90  extendTo(bit);
91 
92  Word &containingWord = words[(bit - offset) / WordSize];
93  Word mask = (Word)0b1 << (bit % WordSize);
94  containingWord |= mask;
95 }
void extendTo(u32_t bit)
Add enough words (append xor prepend) to be able to include bit.

◆ test()

bool SVF::CoreBitVector::test ( u32_t  bit) const

Returns true if bit is set in this CBV.

Definition at line 72 of file CoreBitVector.cpp.

73 {
74  if (bit < offset || bit >= offset + words.size() * WordSize) return false;
75  const Word &containingWord = words[(bit - offset) / WordSize];
76  const Word mask = (Word)0b1 << (bit % WordSize);
77  return mask & containingWord;
78 }

◆ test_and_set()

bool SVF::CoreBitVector::test_and_set ( u32_t  bit)

Check if bit is set. If it is, returns false. Otherwise, sets bit and returns true.

Definition at line 80 of file CoreBitVector.cpp.

81 {
82  // TODO: can be faster.
83  if (test(bit)) return false;
84  set(bit);
85  return true;
86 }
void set(u32_t bit)
Sets bit in the CBV.
bool test(u32_t bit) const
Returns true if bit is set in this CBV.

Member Data Documentation

◆ offset

u32_t SVF::CoreBitVector::offset
private

The first bit of the first word.

Definition at line 198 of file CoreBitVector.h.

◆ words

std::vector<Word> SVF::CoreBitVector::words
private

Our actual bit vector.

Definition at line 200 of file CoreBitVector.h.

◆ WordSize

const size_t SVF::CoreBitVector::WordSize = sizeof(Word) * CHAR_BIT
static

Definition at line 34 of file CoreBitVector.h.


The documentation for this class was generated from the following files: