Skip to content

Commit

Permalink
[ADT] Add SparseBitVector::find_last().
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D28817

llvm-svn: 292288
  • Loading branch information
Zachary Turner committed Jan 17, 2017
1 parent 1d8c2ce commit c095f6a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
19 changes: 19 additions & 0 deletions llvm/include/llvm/ADT/SparseBitVector.h
Expand Up @@ -132,6 +132,17 @@ template <unsigned ElementSize = 128> struct SparseBitVectorElement {
llvm_unreachable("Illegal empty element");
}

/// find_last - Returns the index of the last set bit.
int find_last() const {
for (unsigned I = 0; I < BITWORDS_PER_ELEMENT; ++I) {
unsigned Idx = BITWORDS_PER_ELEMENT - I - 1;
if (Bits[Idx] != 0)
return Idx * BITWORD_SIZE + BITWORD_SIZE -
countLeadingZeros(Bits[Idx]) - 1;
}
llvm_unreachable("Illegal empty element");
}

/// find_next - Returns the index of the next set bit starting from the
/// "Curr" bit. Returns -1 if the next set bit is not found.
int find_next(unsigned Curr) const {
Expand Down Expand Up @@ -768,6 +779,14 @@ class SparseBitVector {
return (First.index() * ElementSize) + First.find_first();
}

// Return the last set bit in the bitmap. Return -1 if no bits are set.
int find_last() const {
if (Elements.empty())
return -1;
const SparseBitVectorElement<ElementSize> &Last = *(Elements.rbegin());
return (Last.index() * ElementSize) + Last.find_last();
}

// Return true if the SparseBitVector is empty
bool empty() const {
return Elements.empty();
Expand Down
39 changes: 39 additions & 0 deletions llvm/unittests/ADT/SparseBitVectorTest.cpp
Expand Up @@ -127,4 +127,43 @@ TEST(SparseBitVectorTest, SelfAssignment) {
EXPECT_TRUE(Vec.empty());
}

TEST(SparseBitVectorTest, Find) {
SparseBitVector<> Vec;
Vec.set(1);
EXPECT_EQ(1, Vec.find_first());
EXPECT_EQ(1, Vec.find_last());

Vec.set(2);
EXPECT_EQ(1, Vec.find_first());
EXPECT_EQ(2, Vec.find_last());

Vec.set(0);
Vec.set(3);
EXPECT_EQ(0, Vec.find_first());
EXPECT_EQ(3, Vec.find_last());

Vec.reset(1);
Vec.reset(0);
Vec.reset(3);
EXPECT_EQ(2, Vec.find_first());
EXPECT_EQ(2, Vec.find_last());

// Set some large bits to ensure we are pulling bits from more than just a
// single bitword.
Vec.set(500);
Vec.set(2000);
Vec.set(3000);
Vec.set(4000);
Vec.reset(2);
EXPECT_EQ(500, Vec.find_first());
EXPECT_EQ(4000, Vec.find_last());

Vec.reset(500);
Vec.reset(3000);
Vec.reset(4000);
EXPECT_EQ(2000, Vec.find_first());
EXPECT_EQ(2000, Vec.find_last());

Vec.clear();
}
}

0 comments on commit c095f6a

Please sign in to comment.