-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Inference: propagate struct initialization info on setfield!
#57222
Inference: propagate struct initialization info on setfield!
#57222
Conversation
The mechanism used to propagate |
b6aeb98
to
9906616
Compare
This should be ready (if no new issues are detected in tests) @aviatesk |
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.
LGTM.
Restarted |
…57304) So far, `PartialStruct` has been unable to represent non-contiguously defined fields, where e.g. a struct would have fields 1 and 3 defined but not field 2. This PR extends it so that such information may be represented with `PartialStruct`, extending the applicability of optimizations e.g. introduced in #55297 by @aviatesk or #57222. The semantics of `new` prevent the creation of a struct with non-contiguously defined fields, therefore this change is mostly relevant to model mutable structs whose fields may be previously set or assumed to be defined after creation, or immutable structs whose creation is opaque. Notably, with this change we may now infer information about structs in the following case: ```julia mutable struct A; x; y; z; A() = new(); end function f() mut = A() # some opaque call preventing optimizations # who knows, maybe `identity` will set fields from `mut` in a future world age! invokelatest(identity, mut) isdefined(mut, :z) && isdefined(mut, :x) || return isdefined(mut, :x) & isdefined(mut, :z) # this now infers as `true` isdefined(mut, :y) # this does not end ``` whereas previously, only information gained successively with `isdefined(mut, :x) && isdefined(mut, :y) && isdefined(mut, :z)` could allow inference to model `mut` having its `z` field defined. --------- Co-authored-by: Cédric Belmant <cedric.belmant@juliahub.com> Co-authored-by: Shuhei Kadowaki <aviatesk@gmail.com>
When a variable has a field set with
setfield!(var, field, value)
, inference now assumes that this specific field is defined and may for example constant-propagateisdefined(var, field)
astrue
.PartialStruct
, the lattice element used to encode this information, still has a few limitations in terms of what it may represent (it cannot represent mutable structs with non-contiguously defined fields yet), further work on extending it would increase the impact of this change.Consider the following function:
Here is before on
master
:And after this PR: