Index: llvm/trunk/include/llvm/ADT/SparseBitVector.h =================================================================== --- llvm/trunk/include/llvm/ADT/SparseBitVector.h +++ llvm/trunk/include/llvm/ADT/SparseBitVector.h @@ -132,6 +132,17 @@ 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 { @@ -768,6 +779,14 @@ 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 &Last = *(Elements.rbegin()); + return (Last.index() * ElementSize) + Last.find_last(); + } + // Return true if the SparseBitVector is empty bool empty() const { return Elements.empty(); Index: llvm/trunk/unittests/ADT/SparseBitVectorTest.cpp =================================================================== --- llvm/trunk/unittests/ADT/SparseBitVectorTest.cpp +++ llvm/trunk/unittests/ADT/SparseBitVectorTest.cpp @@ -127,4 +127,43 @@ 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(); +} }