[llvm] r302254 - [ADT] Add BitVector::find_prev.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri May 5 10:00:04 PDT 2017


Author: zturner
Date: Fri May  5 12:00:04 2017
New Revision: 302254

URL: http://llvm.org/viewvc/llvm-project?rev=302254&view=rev
Log:
[ADT] Add BitVector::find_prev.

This almost completes the matrix of all possible find
functions.

*EXISTING*
----------
find_first
find_first_unset
find_next
find_next_unset
find_last
find_last_unset

*NEW*
----
find_prev

*STILL MISSING*
---------------
find_prev_unset

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

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=302254&r1=302253&r2=302254&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/BitVector.h (original)
+++ llvm/trunk/include/llvm/ADT/BitVector.h Fri May  5 12:00:04 2017
@@ -253,6 +253,33 @@ public:
     return -1;
   }
 
+  /// find_prev - Returns the index of the first set bit that precedes the
+  /// the bit at \p PriorTo.  Returns -1 if all previous bits are unset.
+  int find_prev(unsigned PriorTo) {
+    if (PriorTo == 0)
+      return -1;
+
+    --PriorTo;
+
+    unsigned WordPos = PriorTo / BITWORD_SIZE;
+    unsigned BitPos = PriorTo % BITWORD_SIZE;
+    BitWord Copy = Bits[WordPos];
+    // Mask off next bits.
+    Copy &= maskTrailingOnes<BitWord>(BitPos + 1);
+
+    if (Copy != 0)
+      return (WordPos + 1) * BITWORD_SIZE - countLeadingZeros(Copy) - 1;
+
+    // Check previous words.
+    for (unsigned i = 1; i <= WordPos; ++i) {
+      unsigned Index = WordPos - i;
+      if (Bits[Index] == 0)
+        continue;
+      return (Index + 1) * BITWORD_SIZE - countLeadingZeros(Bits[Index]) - 1;
+    }
+    return -1;
+  }
+
   /// clear - Clear all bits.
   void clear() {
     Size = 0;

Modified: llvm/trunk/include/llvm/ADT/SmallBitVector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallBitVector.h?rev=302254&r1=302253&r2=302254&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/SmallBitVector.h (original)
+++ llvm/trunk/include/llvm/ADT/SmallBitVector.h Fri May  5 12:00:04 2017
@@ -278,6 +278,24 @@ public:
     return getPointer()->find_next_unset(Prev);
   }
 
+  /// find_prev - Returns the index of the first set bit that precedes the
+  /// the bit at \p PriorTo.  Returns -1 if all previous bits are unset.
+  int find_prev(unsigned PriorTo) const {
+    if (isSmall()) {
+      if (PriorTo == 0)
+        return -1;
+
+      --PriorTo;
+      uintptr_t Bits = getSmallBits();
+      Bits &= maskTrailingOnes<uintptr_t>(PriorTo + 1);
+      if (Bits == 0)
+        return -1;
+
+      return NumBaseBits - countLeadingZeros(Bits) - 1;
+    }
+    return getPointer()->find_prev(PriorTo);
+  }
+
   /// Clear all bits.
   void clear() {
     if (!isSmall())

Modified: llvm/trunk/unittests/ADT/BitVectorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/BitVectorTest.cpp?rev=302254&r1=302253&r2=302254&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/BitVectorTest.cpp (original)
+++ llvm/trunk/unittests/ADT/BitVectorTest.cpp Fri May  5 12:00:04 2017
@@ -204,6 +204,11 @@ TYPED_TEST(BitVectorTest, FindOperations
   EXPECT_EQ(75, A.find_next(13));
   EXPECT_EQ(-1, A.find_next(75));
 
+  EXPECT_EQ(-1, A.find_prev(12));
+  EXPECT_EQ(12, A.find_prev(13));
+  EXPECT_EQ(13, A.find_prev(75));
+  EXPECT_EQ(75, A.find_prev(90));
+
   EXPECT_EQ(0, A.find_first_unset());
   EXPECT_EQ(99, A.find_last_unset());
   EXPECT_EQ(14, A.find_next_unset(11));
@@ -240,6 +245,11 @@ TYPED_TEST(BitVectorTest, FindOperations
   EXPECT_EQ(16, A.find_next(4));
   EXPECT_EQ(-1, A.find_next(16));
 
+  EXPECT_EQ(-1, A.find_prev(3));
+  EXPECT_EQ(3, A.find_prev(4));
+  EXPECT_EQ(4, A.find_prev(16));
+  EXPECT_EQ(16, A.find_prev(18));
+
   EXPECT_EQ(0, A.find_first_unset());
   EXPECT_EQ(19, A.find_last_unset());
   EXPECT_EQ(5, A.find_next_unset(3));




More information about the llvm-commits mailing list