This is an archive of the discontinued LLVM Phabricator instance.

Add methods to find the next *unset* bits in a bit vector
ClosedPublic

Authored by zturner on Apr 6 2017, 9:29 PM.

Details

Summary

It's nice to be able to find the next set bit, but often you have a clump of them and you want to find where they stop, i.e. by locating the next unset bit. This patch does that.

Diff Detail

Repository
rL LLVM

Event Timeline

zturner created this revision.Apr 6 2017, 9:29 PM

Not really in the scope of this change, but, since BitVector has these STL-like methods, 'twould be nice if there were a BitVector::npos analogous to std::basic_string::npos rather than having all the users of the class have to hardcode the magic value or make vague checks like >= 0.

I realize that these methods are returning an int rather than a size_type like the corresponding methods on strings. Still, magic sentinel values are magic sentinel values, and the usage would be more consistent.

dberlin edited edge metadata.Apr 7 2017, 10:14 AM

Not really in the scope of this change, but, since BitVector has these STL-like methods, 'twould be nice if there were a BitVector::npos analogous to std::basic_string::npos rather than having all the users of the class have to hardcode the magic value or make vague checks like >= 0.

I realize that these methods are returning an int rather than a size_type like the corresponding methods on strings. Still, magic sentinel values are magic sentinel values, and the usage would be more consistent.

Yes, it would be nice for bitvecrtor and sparsebitvector to be more stl like.

dberlin added inline comments.Apr 7 2017, 10:27 AM
llvm/include/llvm/ADT/BitVector.h
206 ↗(On Diff #94479)

Remind me what endianness we use ?
I would have expected it to simply be << some number of bits, then countleadingones.
It looks reversed, so i'm assuming i'm thinking the wrong way around :)

220 ↗(On Diff #94479)

It would be nice to factor this out with the copy above the loop into a little helper function that takes and Bits.

zturner updated this revision to Diff 94609.Apr 8 2017, 9:15 PM

Fixed an issue where find_first_unset() was returning BV.size() if all bits were set, and added a unit test for that case.

zturner added inline comments.Apr 8 2017, 9:23 PM
llvm/include/llvm/ADT/BitVector.h
206 ↗(On Diff #94479)

Yea, we had this same confusion last time. Didn't you write this thing! :)

If you want the 0'th bit, it's the rightmost bit. So using an example, say Prev is 4, which means you've got something like XXXXXXXXXXXXYYYY where the Y's are the bits you don't care about, and the rightmost X is the bit you want to start searching from, leftwards. So, we set all the Y bits to 1 by producing the bit pattern 10000 and then subtracting 1, and then or that in. Then we count the number of trailing 1s.

The check below that looks if there is at least one zero-bit, and if there is it finds the last one by counting the number of trailing 1s. But the confusion doesn't stop there, because if your word size is, say, 64 bits, but your BitVector only represents 10 bits, then then the left most 54 bits are going to be 0 even though they are out of bounds. So we need the Result < size() check there as well.

zturner updated this revision to Diff 94622.Apr 9 2017, 10:48 AM

Factored the return statement into a small helper function.

dberlin accepted this revision.Apr 10 2017, 10:18 AM
This revision is now accepted and ready to land.Apr 10 2017, 10:18 AM
This revision was automatically updated to reflect the committed changes.