Static Value-Flow Analysis
Loading...
Searching...
No Matches
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.
 
 CoreBitVector (size_t n)
 Construct empty CBV with space reserved for n Words.
 
 CoreBitVector (const CoreBitVector &cbv)
 Copy constructor.
 
 CoreBitVector (CoreBitVector &&cbv)
 Move constructor.
 
CoreBitVectoroperator= (const CoreBitVector &rhs)
 Copy assignment.
 
CoreBitVectoroperator= (CoreBitVector &&rhs)
 Move assignment.
 
bool empty (void) const
 Returns true if no bits are set.
 
u32_t count (void) const
 Returns number of bits set.
 
void clear (void)
 Empty the CBV.
 
bool test (u32_t bit) const
 Returns true if bit is set in this CBV.
 
bool test_and_set (u32_t bit)
 
void set (u32_t bit)
 Sets bit in the CBV.
 
void reset (u32_t bit)
 Resets bit in the CBV.
 
bool contains (const CoreBitVector &rhs) const
 Returns true if this CBV is a superset of rhs.
 
bool intersects (const CoreBitVector &rhs) const
 Returns true if this CBV and rhs share any set bits.
 
bool operator== (const CoreBitVector &rhs) const
 Returns true if this CBV and rhs have the same bits set.
 
bool operator!= (const CoreBitVector &rhs) const
 Returns true if either this CBV or rhs has a bit set unique to the other.
 
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.
 
size_t hash (void) const
 Hash for this CBV.
 
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.
 
void extendForward (u32_t bit)
 Add enough words (append) to be able to include bit.
 
void extendTo (u32_t bit)
 Add enough words (append xor prepend) to be able to include bit.
 
size_t indexForBit (u32_t bit) const
 Returns the index into words which would hold bit.
 
bool canHold (u32_t bit) const
 Returns true if bit can fit in this CBV without resizing.
 
u32_t finalBit (void) const
 Returns the last bit that this CBV can hold.
 
u32_t firstCommonBit (const CoreBitVector &rhs) const
 Returns the first bit position that both this CBV and rhs can hold.
 
size_t nextSetIndex (const size_t start) const
 

Private Attributes

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

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

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)) { }

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

◆ 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}
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ 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
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)
55 return true;
56}
if(prebuffer< 0)
Definition cJSON.cpp:1269
return(char *) p.buffer
#define false
Definition cJSON.cpp:70

◆ 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);
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;
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;
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
246 for ( ; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex)
247 {
249 words[thisIndex] &= rhs.words[rhsIndex];
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;
274 size_t rhsIndex = rhs.indexForBit(greaterOffset);
276 for ( ; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex)
277 {
279 words[thisIndex] &= ~rhs.words[rhsIndex];
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
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.
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?
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;
101 Word mask = ~((Word)0b1 << (bit % WordSize));
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
93 Word mask = (Word)0b1 << (bit % WordSize);
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: