8#ifndef SPARSEBITVECTOR_H
9#define SPARSEBITVECTOR_H
23# define HAS_CLZ __has_builtin(__builtin_clz)
24# define HAS_CLZLL __has_builtin(__builtin_clzll)
25# define HAS_CTZ __has_builtin(__builtin_ctz)
26# define HAS_CTZLL __has_builtin(__builtin_ctzll)
53 return std::numeric_limits<T>::digits;
58 unsigned ZeroBits = 0;
59 T Shift = std::numeric_limits<T>::digits >> 1;
60 T Mask = std::numeric_limits<T>::max() >> Shift;
63 if ((Val & Mask) == 0)
75#if defined(__GNUC__) || defined(_MSC_VER)
76template <
typename T>
struct TrailingZerosCounter<T, 4>
83#if HAS_CTZ || defined(__GNUC__)
84 return __builtin_ctz(Val);
85#elif defined(_MSC_VER)
87 _BitScanForward(&Index, Val);
93#if !defined(_MSC_VER) || defined(_M_X64)
101#if HAS_CTZLL || defined(__GNUC__)
102 return __builtin_ctzll(Val);
103#elif defined(_MSC_VER)
105 _BitScanForward64(&Index, Val);
123 static_assert(std::numeric_limits<T>::is_integer &&
124 !std::numeric_limits<T>::is_signed,
125 "Only unsigned integral types are allowed.");
134 static_assert(SizeOfT <= 4,
"Not implemented!");
136 return __builtin_popcount(
Value);
139 v = v - ((v >> 1) & 0x55555555);
140 v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
141 return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
151 return std::numeric_limits<T>::digits;
154 unsigned ZeroBits = 0;
155 for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1)
157 T Tmp = Val >> Shift;
167#if defined(__GNUC__) || defined(_MSC_VER)
168template <
typename T>
struct LeadingZerosCounter<T, 4>
175#if defined(__GNUC__) || HAS_CLZ
176 return __builtin_clz(Val);
177#elif defined(_MSC_VER)
179 _BitScanReverse(&Index, Val);
185#if !defined(_MSC_VER) || defined(_M_X64)
193#if defined(__GNUC__) || HAS_CLZLL
194 return __builtin_clzll(Val);
195#elif defined(_MSC_VER)
197 _BitScanReverse64(&Index, Val);
215 static_assert(std::numeric_limits<T>::is_integer &&
216 !std::numeric_limits<T>::is_signed,
217 "Only unsigned integral types are allowed.");
226 return __builtin_popcountll(
Value);
229 v = v - ((v >> 1) & 0x5555555555555555ULL);
230 v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
231 v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
232 return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
243 static_assert(std::numeric_limits<T>::is_integer &&
244 !std::numeric_limits<T>::is_signed,
245 "Only unsigned integral types are allowed.");
299 return !(*
this == RHS);
329 bool old =
test(Idx);
350 unsigned NumBits = 0;
362 assert(
false &&
"SBV: find_first: SBV cannot be empty");
376 assert(
false &&
"SBV: find_last: SBV cannot be empty");
391 &&
"Word Position outside of element");
394 Copy &= ~0UL << BitPos;
409 bool changed =
false;
415 if (!changed && old !=
Bits[i])
437 bool changed =
false;
449 if (!changed && old !=
Bits[i])
452 BecameZero = allzero;
462 bool changed =
false;
470 Bits[i] &= ~RHS.Bits[i];
474 if (!changed && old !=
Bits[i])
477 BecameZero = allzero;
492 Bits[i] = RHS1.
Bits[i] & ~RHS2.Bits[i];
496 BecameZero = allzero;
500template <
unsigned ElementSize = 128>
504 using ElementList = std::list<SparseBitVectorElement<ElementSize>>;
554 while (ElementIter != Begin
555 && ElementIter->index() > ElementIndex)
560 while (ElementIter != End &&
561 ElementIter->index() < ElementIndex)
609 unsigned BitPos =
Iter->find_first();
631 int NextSetBitNumber =
Iter->find_next(
BitNumber % ElementSize) ;
633 if (NextSetBitNumber == -1 || (
BitNumber % ElementSize == 0))
646 NextSetBitNumber =
Iter->find_first();
712 return !(*
this == RHS);
755 unsigned ElementIndex = Idx / ElementSize;
760 if (ElementIter ==
Elements.end() ||
761 ElementIter->index() != ElementIndex)
765 return ElementIter->test(Idx % ElementSize);
773 unsigned ElementIndex = Idx / ElementSize;
778 if (ElementIter ==
Elements.end() ||
779 ElementIter->index() != ElementIndex)
781 ElementIter->reset(Idx % ElementSize);
784 if (ElementIter->empty())
793 unsigned ElementIndex = Idx / ElementSize;
803 if (ElementIter ==
Elements.end() ||
804 ElementIter->index() != ElementIndex)
809 if (ElementIter !=
Elements.end() &&
810 ElementIter->index() < ElementIndex)
812 ElementIter =
Elements.emplace(ElementIter, ElementIndex);
817 ElementIter->set(Idx % ElementSize);
822 bool old =
test(Idx);
833 return !(*
this == RHS);
844 if (*Iter1 != *Iter2)
856 bool changed =
false;
866 if (Iter1 ==
Elements.end() || Iter1->index() > Iter2->index())
872 else if (Iter1->index() == Iter2->index())
874 changed |= Iter1->unionWith(*Iter2);
893 bool changed =
false;
910 if (Iter1->index() > Iter2->index())
914 else if (Iter1->index() == Iter2->index())
917 changed |= Iter1->intersectWith(*Iter2, BecameZero);
961 bool changed =
false;
978 if (Iter1->index() > Iter2->index())
982 else if (Iter1->index() == Iter2->index())
985 changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
1022 else if (
this == &RHS2)
1040 while (Iter2 != RHS2.
Elements.end())
1045 if (Iter1->index() > Iter2->index())
1049 else if (Iter1->index() == Iter2->index())
1051 bool BecameZero =
false;
1052 Elements.emplace_back(Iter1->index());
1053 Elements.back().intersectWithComplement(*Iter1, *Iter2, BecameZero);
1091 while (Iter2 != RHS.
Elements.end())
1096 if (Iter1->index() > Iter2->index())
1100 else if (Iter1->index() == Iter2->index())
1102 if (Iter1->intersects(*Iter2))
1121 return (Result == RHS);
1150 unsigned BitCount = 0;
1154 BitCount += Iter->count();
1173template <
unsigned ElementSize>
1180template <
unsigned ElementSize>
1184 return LHS->operator|=(RHS);
1187template <
unsigned ElementSize>
1191 return LHS->operator&=(RHS);
1194template <
unsigned ElementSize>
1203template <
unsigned ElementSize>
1204inline SparseBitVector<ElementSize>
1213template <
unsigned ElementSize>
1214inline SparseBitVector<ElementSize>
1223template <
unsigned ElementSize>
1224inline SparseBitVector<ElementSize>
1234template <
unsigned ElementSize>
1244 for (++bi; bi != be; ++bi)
1255template <
unsigned N>
struct std::hash<
SVF::SparseBitVector<N>>
1260 return h(std::make_pair(std::make_pair(sbv.
count(), sbv.
find_first()),
SparseBitVectorIterator()=delete
void AdvanceToNextNonZero()
ElementListConstIter Iter
bool operator!=(const SparseBitVectorIterator &RHS) const
void AdvanceToFirstNonZero()
SparseBitVectorIterator(const SparseBitVector< ElementSize > *RHS, bool end=false)
bool operator==(const SparseBitVectorIterator &RHS) const
SparseBitVectorIterator operator++(int)
unsigned operator*() const
const SparseBitVector< ElementSize > * BitVector
SparseBitVectorElement< ElementSize >::BitWord Bits
SparseBitVectorIterator & operator++()
SparseBitVectorIterator iterator
SparseBitVector & operator=(SparseBitVector &&RHS)
bool test(unsigned Idx) const
bool operator&=(const SparseBitVector &RHS)
bool intersects(const SparseBitVector< ElementSize > *RHS) const
std::list< SparseBitVectorElement< ElementSize > > ElementList
void intersectWithComplement(const SparseBitVector< ElementSize > *RHS1, const SparseBitVector< ElementSize > *RHS2)
bool test_and_set(unsigned Idx)
typename ElementList::iterator ElementListIter
bool operator|=(const SparseBitVector &RHS)
bool intersects(const SparseBitVector< ElementSize > &RHS) const
bool operator==(const SparseBitVector &RHS) const
bool intersectWithComplement(const SparseBitVector &RHS)
SparseBitVector(SparseBitVector &&RHS) noexcept
SparseBitVector(const SparseBitVector &RHS)
bool intersectWithComplement(const SparseBitVector< ElementSize > *RHS) const
ElementListIter FindLowerBound(unsigned ElementIndex)
ElementListConstIter FindLowerBoundConst(unsigned ElementIndex) const
bool contains(const SparseBitVector< ElementSize > &RHS) const
bool operator!=(const SparseBitVector &RHS) const
typename ElementList::const_iterator ElementListConstIter
ElementListIter FindLowerBoundImpl(unsigned ElementIndex) const
SparseBitVector & operator=(const SparseBitVector &RHS)
ElementListIter CurrElementIter
void intersectWithComplement(const SparseBitVector< ElementSize > &RHS1, const SparseBitVector< ElementSize > &RHS2)
IntervalValue operator-(const IntervalValue &lhs, const IntervalValue &rhs)
Subtract IntervalValues.
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
bool operator&=(SparseBitVector< ElementSize > *LHS, const SparseBitVector< ElementSize > &RHS)
IntervalValue operator&(const IntervalValue &lhs, const IntervalValue &rhs)
Bitwise AND of IntervalValues.
llvm::Value Value
LLVM Basic classes.
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
void dump(const SparseBitVector< ElementSize > &LHS, std::ostream &out)
IntervalValue operator|(const IntervalValue &lhs, const IntervalValue &rhs)
Bitwise OR of IntervalValues.
unsigned countPopulation(T Value)
ZeroBehavior
The behavior an operation has on an input of 0.
@ ZB_Undefined
The returned value is undefined.
@ ZB_Max
The returned value is numeric_limits<T>::max().
@ ZB_Width
The returned value is numeric_limits<T>::digits.
unsigned countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
provide extra hash function for std::pair handling
static unsigned count(T Val, ZeroBehavior)
static unsigned count(T Value)
static unsigned count(T Value)
int find_last() const
find_last - Returns the index of the last set bit.
int find_first() const
find_first - Returns the index of the first set bit.
bool intersects(const SparseBitVectorElement &RHS) const
bool intersectWith(const SparseBitVectorElement &RHS, bool &BecameZero)
bool unionWith(const SparseBitVectorElement &RHS)
bool test(unsigned Idx) const
BitWord Bits[BITWORDS_PER_ELEMENT]
BitWord word(unsigned Idx) const
int find_next(unsigned Curr) const
void intersectWithComplement(const SparseBitVectorElement &RHS1, const SparseBitVectorElement &RHS2, bool &BecameZero)
SparseBitVectorElement(unsigned Idx)
bool test_and_set(unsigned Idx)
SparseBitVectorElement()=default
bool operator==(const SparseBitVectorElement &RHS) const
bool operator!=(const SparseBitVectorElement &RHS) const
bool intersectWithComplement(const SparseBitVectorElement &RHS, bool &BecameZero)
static unsigned count(T Val, ZeroBehavior)
size_t operator()(const SVF::SparseBitVector< N > &sbv) const