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

effects: improve :consistent-cy analysis on getfield #46199

Merged
merged 1 commit into from
Aug 3, 2022

Conversation

aviatesk
Copy link
Sponsor Member

@aviatesk aviatesk commented Jul 27, 2022

This commit improves the accuracy of the :consistent-cy effect analysis
by handling getfield accessing local mutable objects.

The existing analysis taints :consistent-cy upon any getfield call
accessing mutable object because we really don't have a knowledge about
the object lifetime and so we need to conservatively take into account a
possibility of the mutable object being a global variable.

However we can "recover" :consistent-cy tainted by access to mutable
object when the newly added :noglobal helper effect has been proven
because in that case we can conclude that all mutable objects accessed
within the method are purely local and thus :consistent (more
precisely we also need to confirm that all the call arguments are known
not to be mutable global objects to derive this conclusion).

For example now we can prove :consistent-cy of the function below and
it will be concrete-evaluated:

julia> @noinline function mutable_consistent(s)
           broadcast(identity, Ref(s))
       end
mutable_consistent (generic function with 1 method)

julia> Base.infer_effects(mutable_consistent, (String,))
(+c,+e,!n,+t,+s,+g)

julia> code_typed() do
           mutable_consistent(:foo)
       end
1-element Vector{Any}:
 CodeInfo(
1return :foo
) => Symbol

@@ -333,6 +333,7 @@ function _is_effect_free_type(@nospecialize ty)
if isType(ty) || ty === DataType || ty === String || ty === Symbol || ty === SimpleVector
return true
end
ty === Module && return true # TODO add comment on why this is valid
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Suggested change
ty === Module && return true # TODO add comment on why this is valid
ty === Module && return true # there is no inferable constructor (with effect_free consistency), so this object must have already existed

@aviatesk aviatesk force-pushed the avi/noglobal-getfield branch 2 times, most recently from 3369020 to ed77aa5 Compare July 28, 2022 23:55
@aviatesk aviatesk force-pushed the avi/noglobal-getfield branch 3 times, most recently from d679b05 to 469c14d Compare July 30, 2022 22:21
@aviatesk aviatesk added the compiler:inference Type inference label Aug 1, 2022
Base automatically changed from avi/noglobal to master August 3, 2022 05:33
This commit improves the accuracy of the `:consistent`-cy effect analysis
by handling `getfield` accessing local mutable objects.

The existing analysis taints `:consistent`-cy upon any `getfield` call
accessing mutable object because we really don't have a knowledge about
the object lifetime and so we need to conservatively take into account a
possibility of the mutable object being a global variable.

However we can "recover" `:consistent`-cy tainted by `getfield` on mutable
object when the newly added `:noglobal` helper effect has been proven
because in that case we can conclude that all mutable objects accessed
within the method are purely local and thus `:consistent` (more
precisely we also need to confirm that all the call arguments are known
not to be mutable global objects to derive this conclusion).

For example now we can prove `:consistent`-cy of the function below and
it will be concrete-evaluated:
```julia
julia> @noinline function mutable_consistent(s)
           broadcast(identity, Ref(s))
       end
mutable_consistent (generic function with 1 method)

julia> Base.infer_effects(mutable_consistent, (String,))
(+c,+e,!n,+t,+s,+g)

julia> code_typed() do
           mutable_consistent(:foo)
       end
1-element Vector{Any}:
 CodeInfo(
1 ─     return :foo
) => Symbol
```
@aviatesk aviatesk merged commit ccc4558 into master Aug 3, 2022
@aviatesk aviatesk deleted the avi/noglobal-getfield branch August 3, 2022 10:25
@ianatol ianatol mentioned this pull request Aug 4, 2022
ffucci pushed a commit to ffucci/julia that referenced this pull request Aug 11, 2022
…6199)

This commit improves the accuracy of the `:consistent`-cy effect analysis
by handling `getfield` accessing local mutable objects.

The existing analysis taints `:consistent`-cy upon any `getfield` call
accessing mutable object because we really don't have a knowledge about
the object lifetime and so we need to conservatively take into account a
possibility of the mutable object being a global variable.

However we can "recover" `:consistent`-cy tainted by `getfield` on mutable
object when the newly added `:noglobal` helper effect has been proven
because in that case we can conclude that all mutable objects accessed
within the method are purely local and thus `:consistent` (more
precisely we also need to confirm that all the call arguments are known
not to be mutable global objects to derive this conclusion).

For example now we can prove `:consistent`-cy of the function below and
it will be concrete-evaluated:
```julia
julia> @noinline function mutable_consistent(s)
           broadcast(identity, Ref(s))
       end
mutable_consistent (generic function with 1 method)

julia> Base.infer_effects(mutable_consistent, (String,))
(+c,+e,!n,+t,+s,+g)

julia> code_typed() do
           mutable_consistent(:foo)
       end
1-element Vector{Any}:
 CodeInfo(
1 ─     return :foo
) => Symbol
```
pcjentsch pushed a commit to pcjentsch/julia that referenced this pull request Aug 18, 2022
…6199)

This commit improves the accuracy of the `:consistent`-cy effect analysis
by handling `getfield` accessing local mutable objects.

The existing analysis taints `:consistent`-cy upon any `getfield` call
accessing mutable object because we really don't have a knowledge about
the object lifetime and so we need to conservatively take into account a
possibility of the mutable object being a global variable.

However we can "recover" `:consistent`-cy tainted by `getfield` on mutable
object when the newly added `:noglobal` helper effect has been proven
because in that case we can conclude that all mutable objects accessed
within the method are purely local and thus `:consistent` (more
precisely we also need to confirm that all the call arguments are known
not to be mutable global objects to derive this conclusion).

For example now we can prove `:consistent`-cy of the function below and
it will be concrete-evaluated:
```julia
julia> @noinline function mutable_consistent(s)
           broadcast(identity, Ref(s))
       end
mutable_consistent (generic function with 1 method)

julia> Base.infer_effects(mutable_consistent, (String,))
(+c,+e,!n,+t,+s,+g)

julia> code_typed() do
           mutable_consistent(:foo)
       end
1-element Vector{Any}:
 CodeInfo(
1 ─     return :foo
) => Symbol
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:inference Type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants