Index: llvm/include/llvm/ADT/CoalescingBitVector.h =================================================================== --- llvm/include/llvm/ADT/CoalescingBitVector.h +++ llvm/include/llvm/ADT/CoalescingBitVector.h @@ -268,7 +268,6 @@ /// Advance the iterator to \p Index, if it is contained within the current /// interval. void advanceTo(IndexT Index) { - assert(OffsetIntoMapIterator == 0 && "Not implemented"); assert(Index <= CachedStop && "Cannot advance to OOB index"); if (Index < CachedStart) // We're already past this index. @@ -314,6 +313,25 @@ operator++(); return tmp; } + + /// Advance the iterator to the first set bit AT, OR AFTER, \p Index. If + /// no such set bit exists, advance to end(). This is like std::lower_bound. + /// This is useful if \p Index is close to the current iterator position. + /// However, unlike \ref find(), this has worst-case O(n) performance. + void advanceToLowerBound(IndexT Index) { + assert(OffsetIntoMapIterator != kIteratorAtTheEndOffset && + "Cannot advance"); + + // Advance to the first interval containing (or past) Index, or to end(). + while (Index > CachedStop) { + ++MapIterator; + resetCache(); + if (OffsetIntoMapIterator == kIteratorAtTheEndOffset) + return; + } + + advanceTo(Index); + } }; const_iterator begin() const { return const_iterator(Intervals.begin()); } Index: llvm/unittests/ADT/CoalescingBitVectorTest.cpp =================================================================== --- llvm/unittests/ADT/CoalescingBitVectorTest.cpp +++ llvm/unittests/ADT/CoalescingBitVectorTest.cpp @@ -453,6 +453,37 @@ EXPECT_EQ(*BV.find(3), 3u); } +TEST(CoalescingBitVectorTest, AdvanceToLowerBound) { + U64BitVec::Allocator Alloc; + U64BitVec BV(Alloc); + uint64_t BigNum1 = uint64_t(1) << 32; + uint64_t BigNum2 = (uint64_t(1) << 33) + 1; + + auto advFromBegin = [&](uint64_t To) -> U64BitVec::const_iterator { + auto It = BV.begin(); + It.advanceToLowerBound(To); + return It; + }; + + EXPECT_TRUE(advFromBegin(BigNum1) == BV.end()); + BV.set(BigNum1); + auto Find1 = advFromBegin(BigNum1); + EXPECT_EQ(*Find1, BigNum1); + BV.set(BigNum2); + auto Find2 = advFromBegin(BigNum1); + EXPECT_EQ(*Find2, BigNum1); + auto Find3 = advFromBegin(BigNum2); + EXPECT_EQ(*Find3, BigNum2); + BV.reset(BigNum1); + auto Find4 = advFromBegin(BigNum1); + EXPECT_EQ(*Find4, BigNum2); + + BV.clear(); + BV.set({1, 2, 3}); + EXPECT_EQ(*advFromBegin(2), 2u); + EXPECT_EQ(*advFromBegin(3), 3u); +} + TEST(CoalescingBitVectorTest, Print) { std::string S; {