]> granicus.if.org Git - llvm/commitdiff
[ADT] Add SparseBitVector::find_last().
authorZachary Turner <zturner@google.com>
Tue, 17 Jan 2017 23:09:21 +0000 (23:09 +0000)
committerZachary Turner <zturner@google.com>
Tue, 17 Jan 2017 23:09:21 +0000 (23:09 +0000)
Differential Revision: https://reviews.llvm.org/D28817

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292288 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/SparseBitVector.h
unittests/ADT/SparseBitVectorTest.cpp

index e2822c46e2667b294c85e2784f43d30983fefd17..a82cef6028f948764389970cf1191e5e653d248a 100644 (file)
@@ -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<ElementSize> &Last = *(Elements.rbegin());
+    return (Last.index() * ElementSize) + Last.find_last();
+  }
+
   // Return true if the SparseBitVector is empty
   bool empty() const {
     return Elements.empty();
index 9127225860baa30d7aeaa74377411078e2e5105a..6cd4de35bca7dc98c2e5653aa751d22965cbe70e 100644 (file)
@@ -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();
+}
 }