15 #ifndef LLVM_ADT_SPARSEBITVECTOR_H
16 #define LLVM_ADT_SPARSEBITVECTOR_H
20 #include "llvm/Support/DataTypes.h"
43 template <
unsigned ElementSize = 128>
45 :
public ilist_node<SparseBitVectorElement<ElementSize> > {
57 unsigned ElementIndex;
74 if (ElementIndex != RHS.ElementIndex)
77 if (
Bits[i] != RHS.Bits[i])
83 return !(*
this == RHS);
108 bool old =
test(Idx);
120 bool test(
unsigned Idx)
const {
125 unsigned NumBits = 0;
149 &&
"Word Position outside of element");
152 Copy &= ~0UL << BitPos;
166 bool changed =
false;
170 Bits[i] |= RHS.Bits[i];
171 if (!changed && old !=
Bits[i])
180 if (RHS.Bits[i] &
Bits[i])
190 bool changed =
false;
197 Bits[i] &= RHS.Bits[i];
201 if (!changed && old !=
Bits[i])
204 BecameZero = allzero;
212 bool changed =
false;
219 Bits[i] &= ~RHS.Bits[i];
223 if (!changed && old !=
Bits[i])
226 BecameZero = allzero;
238 Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
242 BecameZero = allzero;
246 template <
unsigned ElementSize>
262 template <
unsigned ElementSize = 128>
272 ElementListIter CurrElementIter;
277 ElementListIter FindLowerBound(
unsigned ElementIndex) {
279 if (Elements.
empty()) {
280 CurrElementIter = Elements.
begin();
281 return Elements.
begin();
285 if (CurrElementIter == Elements.
end())
290 ElementListIter ElementIter = CurrElementIter;
291 if (CurrElementIter->index() == ElementIndex) {
293 }
else if (CurrElementIter->index() > ElementIndex) {
294 while (ElementIter != Elements.
begin()
295 && ElementIter->index() > ElementIndex)
298 while (ElementIter != Elements.
end() &&
299 ElementIter->index() < ElementIndex)
302 CurrElementIter = ElementIter;
308 class SparseBitVectorIterator {
327 void AdvanceToFirstNonZero() {
335 BitNumber = Iter->index() * ElementSize;
338 WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
339 Bits = Iter->word(WordNumber);
340 Bits >>= BitPos % BITWORD_SIZE;
344 void AdvanceToNextNonZero() {
355 int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
357 if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
367 BitNumber = Iter->index() * ElementSize;
368 NextSetBitNumber = Iter->find_first();
369 BitNumber += NextSetBitNumber;
370 WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
371 Bits = Iter->word(WordNumber);
372 Bits >>= NextSetBitNumber % BITWORD_SIZE;
374 WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
375 Bits = Iter->word(WordNumber);
376 Bits >>= NextSetBitNumber % BITWORD_SIZE;
377 BitNumber = Iter->index() * ElementSize;
378 BitNumber += NextSetBitNumber;
384 inline SparseBitVectorIterator& operator++() {
387 AdvanceToNextNonZero();
392 inline SparseBitVectorIterator operator++(
int) {
393 SparseBitVectorIterator tmp = *
this;
403 bool operator==(
const SparseBitVectorIterator &RHS)
const {
405 if (AtEnd && RHS.AtEnd)
409 return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
411 bool operator!=(
const SparseBitVectorIterator &RHS)
const {
412 return !(*
this == RHS);
414 SparseBitVectorIterator():
BitVector(NULL) {
425 AdvanceToFirstNonZero();
432 CurrElementIter = Elements.
begin ();
441 while (ElementIter != RHS.Elements.
end()) {
446 CurrElementIter = Elements.
begin ();
459 while (ElementIter != RHS.Elements.
end()) {
464 CurrElementIter = Elements.
begin ();
471 if (Elements.
empty())
474 unsigned ElementIndex = Idx / ElementSize;
475 ElementListIter ElementIter = FindLowerBound(ElementIndex);
479 if (ElementIter == Elements.
end() ||
480 ElementIter->index() != ElementIndex)
482 return ElementIter->test(Idx % ElementSize);
486 if (Elements.
empty())
489 unsigned ElementIndex = Idx / ElementSize;
490 ElementListIter ElementIter = FindLowerBound(ElementIndex);
494 if (ElementIter == Elements.
end() ||
495 ElementIter->index() != ElementIndex)
497 ElementIter->reset(Idx % ElementSize);
500 if (ElementIter->empty()) {
502 Elements.
erase(ElementIter);
507 unsigned ElementIndex = Idx / ElementSize;
509 ElementListIter ElementIter;
510 if (Elements.
empty()) {
512 ElementIter = Elements.
insert(Elements.
end(), Element);
515 ElementIter = FindLowerBound(ElementIndex);
517 if (ElementIter == Elements.
end() ||
518 ElementIter->index() != ElementIndex) {
523 if (ElementIter != Elements.
end() &&
524 ElementIter->index() < ElementIndex)
525 ElementIter = Elements.
insert(++ElementIter, Element);
527 ElementIter = Elements.
insert(ElementIter, Element);
530 CurrElementIter = ElementIter;
532 ElementIter->set(Idx % ElementSize);
536 bool old =
test(Idx);
545 return !(*
this == RHS);
552 for (; Iter1 != Elements.
end() && Iter2 != RHS.Elements.
end();
554 if (*Iter1 != *Iter2)
557 return Iter1 == Elements.
end() && Iter2 == RHS.Elements.
end();
562 bool changed =
false;
563 ElementListIter Iter1 = Elements.
begin();
567 if (RHS.Elements.
empty())
570 while (Iter2 != RHS.Elements.
end()) {
571 if (Iter1 == Elements.
end() || Iter1->index() > Iter2->index()) {
576 }
else if (Iter1->index() == Iter2->index()) {
577 changed |= Iter1->unionWith(*Iter2);
584 CurrElementIter = Elements.
begin();
590 bool changed =
false;
591 ElementListIter Iter1 = Elements.
begin();
599 while (Iter2 != RHS.Elements.
end()) {
600 if (Iter1 == Elements.
end()) {
601 CurrElementIter = Elements.
begin();
605 if (Iter1->index() > Iter2->index()) {
607 }
else if (Iter1->index() == Iter2->index()) {
609 changed |= Iter1->intersectWith(*Iter2, BecameZero);
611 ElementListIter IterTmp = Iter1;
613 Elements.
erase(IterTmp);
619 ElementListIter IterTmp = Iter1;
621 Elements.
erase(IterTmp);
624 Elements.
erase(Iter1, Elements.
end());
625 CurrElementIter = Elements.
begin();
632 bool changed =
false;
633 ElementListIter Iter1 = Elements.
begin();
641 while (Iter2 != RHS.Elements.
end()) {
642 if (Iter1 == Elements.
end()) {
643 CurrElementIter = Elements.
begin();
647 if (Iter1->index() > Iter2->index()) {
649 }
else if (Iter1->index() == Iter2->index()) {
651 changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
653 ElementListIter IterTmp = Iter1;
655 Elements.
erase(IterTmp);
664 CurrElementIter = Elements.
begin();
679 CurrElementIter = Elements.
begin();
685 if (RHS1.Elements.
empty())
689 while (Iter2 != RHS2.Elements.
end()) {
690 if (Iter1 == RHS1.Elements.
end())
693 if (Iter1->index() > Iter2->index()) {
695 }
else if (Iter1->index() == Iter2->index()) {
696 bool BecameZero =
false;
716 while (Iter1 != RHS1.Elements.
end()) {
745 while (Iter2 != RHS.Elements.
end()) {
746 if (Iter1 == Elements.
end())
749 if (Iter1->index() > Iter2->index()) {
751 }
else if (Iter1->index() == Iter2->index()) {
752 if (Iter1->intersects(*Iter2))
768 return (Result == RHS);
773 if (Elements.
empty())
781 return Elements.
empty();
785 unsigned BitCount = 0;
787 Iter != Elements.
end();
789 BitCount += Iter->count();
805 template <
unsigned ElementSize>
811 template <
unsigned ElementSize>
814 return LHS->operator|=(RHS);
817 template <
unsigned ElementSize>
820 return LHS->operator&=(RHS);
823 template <
unsigned ElementSize>
831 template <
unsigned ElementSize>
832 inline SparseBitVector<ElementSize>
840 template <
unsigned ElementSize>
841 inline SparseBitVector<ElementSize>
849 template <
unsigned ElementSize>
850 inline SparseBitVector<ElementSize>
862 template <
unsigned ElementSize>
870 for (++bi; bi != be; ++bi) {
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
iplist< SparseBitVectorElement< ElementSize > >::iterator iterator
SparseBitVector & operator=(const SparseBitVector &RHS)
Element * createSentinel() const
void intersectWithComplement(const SparseBitVector< ElementSize > &RHS1, const SparseBitVector< ElementSize > &RHS2)
SmallBitVector operator&(const SmallBitVector &LHS, const SmallBitVector &RHS)
bool intersects(const SparseBitVector< ElementSize > &RHS) const
bool intersectWithComplement(const SparseBitVector< ElementSize > *RHS) const
bool test(unsigned Idx) const
bool operator!=(const SparseBitVector &RHS) const
SparseBitVectorElement(unsigned Idx)
bool unionWith(const SparseBitVectorElement &RHS)
bool operator|=(const SparseBitVector &RHS)
bool operator!=(const SparseBitVectorElement &RHS) const
bool intersectWithComplement(const SparseBitVectorElement &RHS, bool &BecameZero)
int find_first() const
find_first - Returns the index of the first set bit.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void intersectWithComplement(const SparseBitVector< ElementSize > *RHS1, const SparseBitVector< ElementSize > *RHS2)
ilist_default_traits - Default template traits for intrusive list.
SmallBitVector operator|(const SmallBitVector &LHS, const SmallBitVector &RHS)
Element * ensureHead(Element *) const
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
bool test_and_set(unsigned Idx)
ilist_sentinel_traits - A fragment for template traits for intrusive list that provides default senti...
bool operator&=(const SparseBitVector &RHS)
bool empty() const
empty - Tests whether there are no bits in this bitvector.
iterator insert(iterator where, const NodeTy &val)
static void destroySentinel(Element *)
bool operator==(const SparseBitVector &RHS) const
iterator erase(iterator where)
bool operator==(const SparseBitVectorElement &RHS) const
bool intersectWith(const SparseBitVectorElement &RHS, bool &BecameZero)
unsigned countPopulation(T Value)
Count the number of set bits in a value.
BlockMass operator*(const BlockMass &L, const BranchProbability &R)
void intersectWithComplement(const SparseBitVectorElement &RHS1, const SparseBitVectorElement &RHS2, bool &BecameZero)
BitWord word(unsigned Idx) const
Element * provideInitialHead() const
SparseBitVector is an implementation of a bitvector that is sparse by only storing the elements that ...
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
SparseBitVectorElement< ElementSize > Element
ilist_half_node - Base class that provides prev services for sentinels.
bool intersectWithComplement(const SparseBitVector &RHS)
bool test_and_set(unsigned Idx)
bool intersects(const SparseBitVector< ElementSize > *RHS) const
ilist_node - Base class that provides next/prev services for nodes that use ilist_nextprev_traits or ...
int find_next(unsigned Curr) const
find_next - Returns the index of the next set bit starting from the "Curr" bit.
SparseBitVector(const SparseBitVector &RHS)
static NodeTy * createSentinel()
createSentinel - create the dynamic sentinel
SparseBitVectorIterator iterator
static void noteHead(Element *, Element *)
This class implements an extremely fast bulk output stream that can only output to a stream...
void operator-(int, ilist_iterator< T >)=delete
bool operator&=(SparseBitVector< ElementSize > *LHS, const SparseBitVector< ElementSize > &RHS)
bool intersects(const SparseBitVectorElement &RHS) const
void push_back(const NodeTy &val)
bool contains(const SparseBitVector< ElementSize > &RHS) const