Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Follow multiple transparent links in Option layout #699

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dcreager
Copy link

Option can take advantage of layout optimizations when its inner type is nullable or zeroable. Before, we were only looking at the Option's direct generic parameter when deciding whether we could use this optimization. But the layout optimization "propagates through" typedefs and transparent structs. We now repeatedly follow these type aliases until we reach a non-aliased type, and only then check whether the type is nullable/zeroable.

Fixes #690
Fixes #326

Option can take advantage of layout optimizations when its inner type is
nullable or zeroable.  Before, we were only looking at the Option's
direct generic parameter when deciding whether we could use this
optimization.  But the layout optimization "propagates through" typedefs
and transparent structs.  We now repeatedly follow these type aliases
until we reach a non-aliased type, and only then check whether the type
is nullable/zeroable.
Comment on lines +11 to +12
file: Handle<File>,
maybe_file: Option<Handle<File>>,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I don't like about this patch is that you end up with different types for these two fields.

Comment on lines 9 to 10
Handle_File file;
uint32_t maybe_file;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like here. Ideally both fields would be Handle_File.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, agreed... In practice it shouldn't be a huge deal for C. For C++ it can be a bit more annoying (I can imagine someone defining their own Handle<> for example.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest patch fixes this, at the expense of the infinite_recursion_typedef_monomorph test going into an infinite loop. I'd really love to be able to use the Monomorphs data here, but that's not generated until later in the process, and it looks like it depends on all of the types already having been simplified.

/// This happens via `#[repr(transparent)]` structs and via typedefs.
#[derive(Default)]
pub struct TransparentTypes {
transparent: HashMap<Path, (Type, GenericParams)>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it is quite a bit unfortunate to have to go through all items again creating this data structure when we already have a <Path, Struct> etc hashmap in ItemMap, it just feels like a lot of upfront work for something that could be much more efficient.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I definitely agree. At first I tried passing &ItemMap<Struct> and &ItemMap<Typedef> references in to the simplify_standard_types methods, but that runs afoul of the borrow checker, since we're calling them from within a for_all_items_mut loop that is updating the contents of those ItemMaps. Do you have any suggestions for how to break that double-borrow?

Comment on lines 9 to 10
Handle_File file;
uint32_t maybe_file;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, agreed... In practice it shouldn't be a huge deal for C. For C++ it can be a bit more annoying (I can imagine someone defining their own Handle<> for example.

As part of simplifying, we follow any typedefs or transparent structs to
determine if a path type is aliased to a type that is nullable or
zeroable.  If so, that path type can participate in the Option layout
optimization just like primitive nullable/zeroable types.
@jonnius
Copy link

jonnius commented Sep 8, 2021

Just in case you are looking for a complex example. I tried to run a build from this PR on libsignal-client and ran into a stackoverflow (with 16 GB of RAM). I guess this might be result of (endless) recursion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants