-
Notifications
You must be signed in to change notification settings - Fork 347
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
[Peephole Optimization 1/n] Don't allocate for structs with a single primval field #146
Conversation
// enums with just one variant are no different, but `.struct_variant()` doesn't work for enums | ||
let variant = &def.variants[0]; | ||
// FIXME: also allow structs with only a single non zst field | ||
if variant.fields.len() == 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let fields = variant.fields.iter().filter(|field|self.type_size(.ty(self.tcx, substs)) != Ok(Some(0))).collect::<Vec<_>>();
if fields.len() == 1{
//...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately it's not that easy, other code also has the invariant that we treat zst fields as real fields.
@@ -490,7 +490,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { | |||
args.push((undef, field_ty)); | |||
} | |||
}, | |||
_ => bug!("rust-call ABI tuple argument was {:?}", last), | |||
_ => bug!("rust-call ABI tuple argument was {:?}, but {:?} were expected", last, fields), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/were/was?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well... the fields are multiple xD not sure what the exact grammar is.
FWIW I'd love to have this encoded in How does this relate to "newtype unpacking"? Well, we already have something like that! |
Offsets before the first field are already representable by
Do you mean another variant of that enum? or encoded in the existing variants?
Isn't that the closed RFC about enum variants being their own types? |
Correct, but we don't have the logic to generate the right LLVM types (rust-lang/rust#39999 gets close).
New variant, as an alternative to
Indeed! However, we can use it inside the compiler to replace |
This is an optimization I wanted, and I'm fine with merging this as-is, but I definitely want to find some way to make it more general and avoid special-case checks for 1 field (or 1 non-ZST field) all over the place. Hopefully it could also combine with some of the 2-field ByValPair checks. I haven't digested everything @eddyb said, but it'd be nice if rustc could help us out here. |
I've tried implementing this in rustc, but I'm not sure if my design is sensible, since apparently it's easy to miss some cases and then stage2 segfaults. I added a new |
I have improvements coming on top of this PR for 2 field optimizations and cleanups simplifying everything. But I want to do this incrementally. |
No description provided.