This is an archive of the discontinued LLVM Phabricator instance.

BitVector: add iterators for bits that are set
ClosedPublic

Authored by thegameg on Apr 13 2017, 3:51 PM.

Details

Summary

Add iterators to iterate on the bits of the bit vector that are set. This is useful when BitVector is used as a set<unsigned>, which usually is a set of basic block numbers or a set of registers.

D30808 would be a user of this.

This would allow us to transform:

for (int Elt = Vector.find_first(); Elt >= 0; Elt = Vector.find_next(Elt)) {
  // Stuff
}

into

for (int Elt : Vector.bits_set()) {
  // Stuff
}

Diff Detail

Repository
rL LLVM

Event Timeline

thegameg created this revision.Apr 13 2017, 3:51 PM
MatzeB edited edge metadata.Apr 13 2017, 5:28 PM

Thanks for working on this. I missed this feature myself a couple of times.

We generally do not commit unused code, so before commit this we have to wait until one of the shrink-wrapping patches is accepted. Or you go around llvm and try to find a few find_next() users that can be replaced with a range based for.

include/llvm/ADT/BitVector.h
79–80 ↗(On Diff #95232)

You should probably pull this out of the class, as it doesn't use any private methods and is used not just by BitVector but also by SmallBitVector.

81 ↗(On Diff #95232)

Does this ever make sense to be nullptr? I'd recommend using a reference.

87 ↗(On Diff #95232)

I'd recommend an explicit modifier here.

91–94 ↗(On Diff #95232)

This can be private.

107 ↗(On Diff #95232)

We have size_type BitVector::size() or BitVector::set(unsigned Idx). We seem to be a bit inconsistent regarding size_type vs. unsigned but the majority of functions appear to be using unsigned for bit indexes so this should be the return type here.

108 ↗(On Diff #95232)

Is it necessary to make this accessible? Having access to the parent bitvector seems like an implementation detail to me that could stay private.

111–118 ↗(On Diff #95232)

This could be more consistent: const_bits_set_iterator, bit_set_begin() and bit_set().

114–115 ↗(On Diff #95232)
665–679 ↗(On Diff #95232)

Isn't it possible to move those into the iterator class?

unittests/ADT/BitVectorTest.cpp
514 ↗(On Diff #95232)

How about EXPECT_TRUE(false); to make it more obvious?

526–533 ↗(On Diff #95232)

Maybe construct an array {1,10,99,25} that you verify against during the iteration to make sure we do indeed return the right numbers?

Adding a few reviewers who often have comments on ADT changes.

thegameg updated this revision to Diff 95256.Apr 13 2017, 6:41 PM
thegameg marked 11 inline comments as done.

Thanks Matthias for the review.

thegameg updated this revision to Diff 95257.Apr 13 2017, 6:43 PM

Fixl typo in unit tests.

MatzeB added inline comments.Apr 13 2017, 7:01 PM
include/llvm/ADT/SmallBitVector.h
139–144 ↗(On Diff #95257)

This is still inconsistent bits_set vs. bit_set.

thegameg updated this revision to Diff 95307.Apr 14 2017, 9:35 AM
thegameg marked an inline comment as done.

Updated some passes to use this.

thegameg updated this revision to Diff 95523.Apr 17 2017, 6:52 PM

Better name for the iterator range.
Fix typo.

This is looking pretty good, but I'd expect the range based for loops to use the same type as operator() of operator*(), i.e. `for (unsigned Bit : Empty.set_bits()) {}.

thegameg updated this revision to Diff 96234.Apr 21 2017, 2:29 PM

int -> unsigned.

MatzeB accepted this revision.Apr 21 2017, 2:34 PM

LGTM

This revision is now accepted and ready to land.Apr 21 2017, 2:34 PM
This revision was automatically updated to reflect the committed changes.