[llvm] r301014 - [BitVector] Add find_last() and find_last_unset().

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 21 11:07:46 PDT 2017


Author: zturner
Date: Fri Apr 21 13:07:46 2017
New Revision: 301014

URL: http://llvm.org/viewvc/llvm-project?rev=301014&view=rev
Log:
[BitVector] Add find_last() and find_last_unset().

Differential Revision: https://reviews.llvm.org/D32302

Modified:
    llvm/trunk/include/llvm/ADT/BitVector.h
    llvm/trunk/include/llvm/ADT/SmallBitVector.h
    llvm/trunk/unittests/ADT/BitVectorTest.cpp

Modified: llvm/trunk/include/llvm/ADT/BitVector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/BitVector.h?rev=301014&r1=301013&r2=301014&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/BitVector.h (original)
+++ llvm/trunk/include/llvm/ADT/BitVector.h Fri Apr 21 13:07:46 2017
@@ -15,7 +15,6 @@
 #define LLVM_ADT_BITVECTOR_H
 
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/MathExtras.h"
 #include <algorithm>
 #include <cassert>
@@ -163,6 +162,22 @@ public:
     return -1;
   }
 
+  /// find_last - Returns the index of the last set bit, -1 if none of the bits
+  /// are set.
+  int find_last() const {
+    if (Size == 0)
+      return -1;
+
+    unsigned N = NumBitWords(size());
+    assert(N > 0);
+
+    unsigned i = N - 1;
+    while (i > 0 && Bits[i] == BitWord(0))
+      --i;
+
+    return int((i + 1) * BITWORD_SIZE - countLeadingZeros(Bits[i])) - 1;
+  }
+
   /// find_first_unset - Returns the index of the first unset bit, -1 if all
   /// of the bits are set.
   int find_first_unset() const {
@@ -174,6 +189,30 @@ public:
     return -1;
   }
 
+  /// find_last_unset - Returns the index of the last unset bit, -1 if all of
+  /// the bits are set.
+  int find_last_unset() const {
+    if (Size == 0)
+      return -1;
+
+    const unsigned N = NumBitWords(size());
+    assert(N > 0);
+
+    unsigned i = N - 1;
+    BitWord W = Bits[i];
+
+    // The last word in the BitVector has some unused bits, so we need to set
+    // them all to 1 first.  Set them all to 1 so they don't get treated as
+    // valid unset bits.
+    unsigned UnusedCount = BITWORD_SIZE - size() % BITWORD_SIZE;
+    W |= maskLeadingOnes<BitWord>(UnusedCount);
+
+    while (W == ~BitWord(0) && --i > 0)
+      W = Bits[i];
+
+    return int((i + 1) * BITWORD_SIZE - countLeadingOnes(W)) - 1;
+  }
+
   /// find_next - Returns the index of the next set bit following the
   /// "Prev" bit. Returns -1 if the next set bit is not found.
   int find_next(unsigned Prev) const {

Modified: llvm/trunk/include/llvm/ADT/SmallBitVector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallBitVector.h?rev=301014&r1=301013&r2=301014&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/SmallBitVector.h (original)
+++ llvm/trunk/include/llvm/ADT/SmallBitVector.h Fri Apr 21 13:07:46 2017
@@ -117,9 +117,7 @@ private:
   }
 
   // Return the size.
-  size_t getSmallSize() const {
-    return getSmallRawBits() >> SmallNumDataBits;
-  }
+  size_t getSmallSize() const { return getSmallRawBits() >> SmallNumDataBits; }
 
   void setSmallSize(size_t Size) {
     setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
@@ -216,6 +214,16 @@ public:
     return getPointer()->find_first();
   }
 
+  int find_last() const {
+    if (isSmall()) {
+      uintptr_t Bits = getSmallBits();
+      if (Bits == 0)
+        return -1;
+      return NumBaseBits - countLeadingZeros(Bits);
+    }
+    return getPointer()->find_last();
+  }
+
   /// Returns the index of the first unset bit, -1 if all of the bits are set.
   int find_first_unset() const {
     if (isSmall()) {
@@ -228,6 +236,17 @@ public:
     return getPointer()->find_first_unset();
   }
 
+  int find_last_unset() const {
+    if (isSmall()) {
+      if (count() == getSmallSize())
+        return -1;
+
+      uintptr_t Bits = getSmallBits();
+      return NumBaseBits - countLeadingOnes(Bits);
+    }
+    return getPointer()->find_last_unset();
+  }
+
   /// Returns the index of the next set bit following the "Prev" bit.
   /// Returns -1 if the next set bit is not found.
   int find_next(unsigned Prev) const {

Modified: llvm/trunk/unittests/ADT/BitVectorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/BitVectorTest.cpp?rev=301014&r1=301013&r2=301014&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/BitVectorTest.cpp (original)
+++ llvm/trunk/unittests/ADT/BitVectorTest.cpp Fri Apr 21 13:07:46 2017
@@ -186,7 +186,9 @@ TYPED_TEST(BitVectorTest, FindOperations
   // Test finding in an empty BitVector.
   TypeParam A;
   EXPECT_EQ(-1, A.find_first());
+  EXPECT_EQ(-1, A.find_last());
   EXPECT_EQ(-1, A.find_first_unset());
+  EXPECT_EQ(-1, A.find_last_unset());
   EXPECT_EQ(-1, A.find_next(0));
   EXPECT_EQ(-1, A.find_next_unset(0));
 
@@ -196,12 +198,14 @@ TYPED_TEST(BitVectorTest, FindOperations
   A.set(13);
   A.set(75);
 
+  EXPECT_EQ(75, A.find_last());
   EXPECT_EQ(12, A.find_first());
   EXPECT_EQ(13, A.find_next(12));
   EXPECT_EQ(75, A.find_next(13));
   EXPECT_EQ(-1, A.find_next(75));
 
   EXPECT_EQ(0, A.find_first_unset());
+  EXPECT_EQ(99, A.find_last_unset());
   EXPECT_EQ(14, A.find_next_unset(11));
   EXPECT_EQ(14, A.find_next_unset(12));
   EXPECT_EQ(14, A.find_next_unset(13));
@@ -213,12 +217,16 @@ TYPED_TEST(BitVectorTest, FindOperations
   A.set(0, 100);
   EXPECT_EQ(100U, A.count());
   EXPECT_EQ(0, A.find_first());
+  EXPECT_EQ(99, A.find_last());
   EXPECT_EQ(-1, A.find_first_unset());
+  EXPECT_EQ(-1, A.find_last_unset());
 
   A.reset(0, 100);
   EXPECT_EQ(0U, A.count());
   EXPECT_EQ(-1, A.find_first());
+  EXPECT_EQ(-1, A.find_last());
   EXPECT_EQ(0, A.find_first_unset());
+  EXPECT_EQ(99, A.find_last_unset());
 }
 
 TYPED_TEST(BitVectorTest, CompoundAssignment) {




More information about the llvm-commits mailing list