From: Zachary Turner Date: Tue, 17 Jan 2017 23:09:21 +0000 (+0000) Subject: [ADT] Add SparseBitVector::find_last(). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=974466a9b805e6defa1bd5f45cf4597e7220886c;p=llvm [ADT] Add SparseBitVector::find_last(). Differential Revision: https://reviews.llvm.org/D28817 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292288 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h index e2822c46e26..a82cef6028f 100644 --- a/include/llvm/ADT/SparseBitVector.h +++ b/include/llvm/ADT/SparseBitVector.h @@ -132,6 +132,17 @@ public: 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 @@ public: 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(); diff --git a/unittests/ADT/SparseBitVectorTest.cpp b/unittests/ADT/SparseBitVectorTest.cpp index 9127225860b..6cd4de35bca 100644 --- a/unittests/ADT/SparseBitVectorTest.cpp +++ b/unittests/ADT/SparseBitVectorTest.cpp @@ -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(); +} }