From 0a3b8732fde86d4abfa36f3c15a01e1c30fa0a3d Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Tue, 17 Jan 2017 23:09:21 +0000 Subject: [PATCH] [ADT] Add SparseBitVector::find_last(). Differential Revision: https://reviews.llvm.org/D28817 llvm-svn: 292288 --- include/llvm/ADT/SparseBitVector.h | 19 +++++++++++++ unittests/ADT/SparseBitVectorTest.cpp | 39 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) 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(); +} }