Index: llvm/trunk/include/llvm/ADT/BitVector.h =================================================================== --- llvm/trunk/include/llvm/ADT/BitVector.h +++ llvm/trunk/include/llvm/ADT/BitVector.h @@ -253,6 +253,33 @@ 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(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; Index: llvm/trunk/include/llvm/ADT/SmallBitVector.h =================================================================== --- llvm/trunk/include/llvm/ADT/SmallBitVector.h +++ llvm/trunk/include/llvm/ADT/SmallBitVector.h @@ -278,6 +278,24 @@ 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(PriorTo + 1); + if (Bits == 0) + return -1; + + return NumBaseBits - countLeadingZeros(Bits) - 1; + } + return getPointer()->find_prev(PriorTo); + } + /// Clear all bits. void clear() { if (!isSmall()) Index: llvm/trunk/unittests/ADT/BitVectorTest.cpp =================================================================== --- llvm/trunk/unittests/ADT/BitVectorTest.cpp +++ llvm/trunk/unittests/ADT/BitVectorTest.cpp @@ -204,6 +204,11 @@ 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 @@ 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));