This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Add an abstraction for embedding an integer within a pointer-like type.
ClosedPublic

Authored by chandlerc on Jan 2 2016, 2:51 AM.

Details

Summary

This makes it easy and safe to use a set of flags as one elmenet of
a tagged union with pointers. There is quite a bit of code that has
historically done this by casting arbitrary integers to "pointers" and
assuming that this was safe and reliable. It is neither, and has started
to rear its head by triggering safety asserts in various abstractions
like PointerLikeTypeTraits when the integers chosen are invariably poor
choices for *some* platform and *some* situation. Not to mention the
(hopefully unlikely) prospect of one of these integers actually getting
allocated!

With this, it will be straightforward to build type safe abstractions
like this without being error prone. The abstraction itself is also
remarkably simple thanks to the implicit conversion.

Diff Detail

Repository
rL LLVM

Event Timeline

chandlerc updated this revision to Diff 43845.Jan 2 2016, 2:51 AM
chandlerc retitled this revision from to [ADT] Add an abstraction for embedding an integer within a pointer-like type..
chandlerc updated this object.
chandlerc added a reviewer: rsmith.
chandlerc added a subscriber: llvm-commits.

You can see an example usage in http://reviews.llvm.org/D15845

Ha, I wrote the same thing, but it's only used for Swift-Clang's "API notes" feature that hasn't been upstreamed, so it's still sitting in our repository. I called it Fixnum. Sorry about that.

Differences:

  • when stored outside a PointerIntPair, it uses the smallest storage possible
  • safe upcasting is implicitly allowed
  • assignment/construction between bit widths is permitted but checked
  • I hadn't written special DenseMapInfo (because we never used it in a DenseMap)

I'm fine switching ours over to yours, or you taking ours as is. I really thought we had tests for it too but I can't find them.

Ha, I wrote the same thing, but it's only used for Swift-Clang's "API notes" feature that hasn't been upstreamed, so it's still sitting in our repository. I called it Fixnum. Sorry about that.

No problem, seems like this is going in the right direction anyways. =]

Differences:

  • when stored outside a PointerIntPair, it uses the smallest storage possible
  • safe upcasting is implicitly allowed
  • assignment/construction between bit widths is permitted but checked
  • I hadn't written special DenseMapInfo (because we never used it in a DenseMap)

I'm fine switching ours over to yours, or you taking ours as is. I really thought we had tests for it too but I can't find them.

Well, the approach I've taken (storing it as a pointer, and quickly converting it an integer type for any/all operations) is at least from the code size much simpler, so I have a bias towards that.

Let's start with the patch as I have it since it at least works for some use cases and is really boring and simple. It also has basic tests that can be extended incrementally.

So far at least, I have found it really effective to rely on the single implicit conversion to a particular integer type, and then allow promotion and normal arithmetic to take place. This seemed to work well. The typical result I expect is that the ADT type only really exists inside of a sum type or pointer union. All the other places, you just get the integer.

However, I've not used it super widely, so if you try to use this in Swift you may uncover reasons why we need to add some (or all) of the facilities from your version. If/when you do, you can post the patches to merge functionality into this (along with tests that show what usage pattern needs it) until it is sufficient for the use cases you have in Swift.

I'm going to land this as is since you seem fine with it, but just follow up with any issues you run into when it shows up on the swift side of things. Thanks!

-Chandler

This revision was automatically updated to reflect the committed changes.