This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Add Bitfield utilities - design #2
AbandonedPublic

Authored by gchatelet on Jun 17 2020, 3:30 PM.

Details

Summary

Alternative design to D81580 with the following change in API

using Bool = Bitfield<bool, 0, 1>;

// testField becomes cast to bool operator

before: if(Bool::testField(Storage))
after:  if(bitfield<Bool>(Storage).isSet())

// getField becomes cast to UserType
before: auto Value = Bool::getField(Storage);
after:  auto Value = bitfield<Bool>(Storage);

// setField becomes returning a UserType assignable object
before: Bool::setField(Storage, Value);
after:  bitfield<Bool>(Storage) = Value;

Diff Detail

Event Timeline

gchatelet created this revision.Jun 17 2020, 3:30 PM
gchatelet updated this revision to Diff 271503.Jun 17 2020, 3:32 PM
  • update API documentation
Harbormaster completed remote builds in B60722: Diff 271503.
courbet added inline comments.Jun 18 2020, 2:23 AM
llvm/include/llvm/ADT/Bitfields.h
144

The conversion from/to enum/bool are done in the public API outside of this template where is that ?

197

I'm actually a bit frightened by this, even with the guaranteed elision in c++, this is still dangerous: https://godbolt.org/z/t-Gzi7

The previous Bitfield::setField() approach has the same issue, but at least we're returning a reference and not a value, so the issue is more visible.

246

This is only a type, make ctor private to make it clear that it's not meant to be instantiated ?

266

This should not be static. It can be inline, but this is already implied by the template.

llvm/unittests/ADT/BitFieldsTest.cpp
22

I think @serge-sans-paille was suggesting to go one step further : do away with the bitfield function, and replace it with the ctor directly: Bool(Storage) = true.

gchatelet edited the summary of this revision. (Show Details)Jun 18 2020, 2:30 AM
gchatelet added a reviewer: jfb.
gchatelet marked 3 inline comments as done.Jun 18 2020, 3:18 AM
gchatelet added inline comments.
llvm/include/llvm/ADT/Bitfields.h
144

Outdated comment, thx for noticing.
The documentation is not polished yet, I'd like to get in agreement on the API code first.
Keeping your comment not Done for now.

197

Yeah that's why I'm not fond of this version, the object semantic adds its own set of gotchas on top of the already complex functional code.

llvm/unittests/ADT/BitFieldsTest.cpp
22

Yes unfortunately this is not possible as Storage type needs to be deduced somehow.
e.g.

template<typename UserType, unsigned Offset, unsigned Size, UserType MaxValue = ...>
struct Bitfield {
  Bitfield(StorageType &Storage) // where does StorageType comes from?
};

The type would need to be part of the template arguments.
e.g.

template<typename StorageType, typename UserType, unsigned Offset, unsigned Size, UserType MaxValue = ...>
struct Bitfield {
  Bitfield(StorageType &Storage) //OK
};

But I believe this is confusing to declare (e.g. Bitfield<uint64_t, uint_8t, 0, 4>) and would require a lot of editing in case the StorageType changes.

The function is the trick to deduce StorageType automatically.

courbet added inline comments.Jun 18 2020, 4:58 AM
llvm/unittests/ADT/BitFieldsTest.cpp
22

That makes sense. Then maybe at least make the function static and part of the class ?

using Bool = Bitfield<bool, 0, 1>;
Bool::fieldOf(Storage) = true;

That's a midpoint between the current proposal:

using Bool = Bitfield<bool, 0, 1>;
bitfield<Bool>(Storage) = true;

And the previous one:

using Bool = Bitfield<bool, 0, 1>;
Bool::setField(Storage, true);
gchatelet marked an inline comment as done.Jun 19 2020, 12:45 AM
gchatelet added inline comments.
llvm/unittests/ADT/BitFieldsTest.cpp
22

@jfb would you have some time to give your thoughts on which approach is best? (I've added you as a reviewer since you seemed interested in abstractions when I introduced Align.)
@serge-sans-paille what do you think of the API you suggested ?

Additional thoughts: even though there wasn't a lot of answers to your initial thread on llvm-dev, I'd post a followup with a few examples of the two approaches to gather some feedback from the community. I personally like this one, obviously :-)

llvm/unittests/ADT/BitFieldsTest.cpp
22

@gchatelet : I really like the syntax eye candy. That looks very readable to me. thanks for going as far as implementing an alternate version.

gchatelet retitled this revision from [ADT] Add Bitfield utilities - alternative design to [ADT] Add Bitfield utilities - design #2.Jun 24 2020, 5:17 AM
gchatelet abandoned this revision.Jun 29 2020, 5:49 AM

Dropped in favor of D82454