-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
[NewOptimizer] Make stmt_effect_free less aggressive #26948
Conversation
base/compiler/tfuncs.jl
Outdated
(isa(a, DataType) && (isa(a.parameters[1], Type) || isa(a.parameters[1], TypeVar))) || return false | ||
at = a.parameters[1] | ||
# Check that the element type is compatible with the element we're assigning | ||
(argtypes[3] ⊑ (isa(at, Type) ? at : at.lb)) || return false |
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.
lb
might be a TypeVar
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.
So, iterate until we hit a type? Can they be circular?
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.
can't be circular, I think Jeff added a helper function to unwrap TypeVar
if isa(name, Const) | ||
(isa(sv, Module) && isa(name.val, Symbol)) || return false | ||
(isa(name.val, Symbol) || isa(name.val, Int)) || return false | ||
return isdefined(sv, name.val) |
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.
only if immutable (or isdefined
returns true)
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.
Is that true? Can you un-initialize a field of a mutable?
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.
Oh, right. I was thinking this was returning the value – not whether it's an error
base/compiler/tfuncs.jl
Outdated
if isa(s, Union) | ||
return getfield_nothrow(rewrap(s.a, s00), name, inbounds) && | ||
getfield_nothrow(rewrap(s.b, s00), name, inbounds) | ||
elseif isa(s, Conditional) |
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
can't be Conditional after widenconst
base/compiler/tfuncs.jl
Outdated
s.abstract && return false | ||
# If all fields are always initialized, and bounds check is disabled, we can assume | ||
# we don't throw | ||
(fieldcount(s) == s.ninitialized) && return true |
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.
may throw (isvatuple
, or some NamedTuples)
Previously, the new optimizer used the pre-existing `effect_free` function to determine whether it is safe to remove an unreferenced statement. However, this function ignores many builtin's error cases, causing them to be removed when that is not legal to do (because that would potentially remove an exception that would otherwise be thrown). Start fixing this, by introducing a version of the function that is correct for a subset of intresting functions. We will likely need to expand this when we look at the benchmarks, but this should be correct for now.
* Use the field index passed in in `lift_leaves` The caller has already done all the computation including bound checking. The `field` computed in this function is also affecting all the following iterations which is almost certainly wrong. * Remove unnecessary type check on `field` in `lift_leaves` since it is always `Int` * Move a branch disabling `return nothing` higher up * Remove some duplicated calculation on field index in `getfield_elim_pass!` * Fix `try_compute_fieldidx` to return `nothing` for non-`Int` `Integer` field index. This can cause `getfield_nothrow` to return incorrect result. It also gives the caller worse type info about the return value. * Teach `getfield_nothrow` that `isbits` field cannot be undefined and getfield on such field cannot throw. This is already handled in `isdefined_tfunc`. ---- Ref #26948 (fa02d34) Ref #27126 (9100329)
* Use the field index passed in in `lift_leaves` The caller has already done all the computation including bound checking. The `field` computed in this function is also affecting all the following iterations which is almost certainly wrong. * Remove unnecessary type check on `field` in `lift_leaves` since it is always `Int` * Move a branch disabling `return nothing` higher up * Remove some duplicated calculation on field index in `getfield_elim_pass!` * Fix `try_compute_fieldidx` to return `nothing` for non-`Int` `Integer` field index. This can cause `getfield_nothrow` to return incorrect result. It also gives the caller worse type info about the return value. * Teach `getfield_nothrow` that `isbits` field cannot be undefined and getfield on such field cannot throw. This is already handled in `isdefined_tfunc`. ---- Ref #26948 (fa02d34) Ref #27126 (9100329)
* Use the field index passed in in `lift_leaves` The caller has already done all the computation including bound checking. The `field` computed in this function is also affecting all the following iterations which is almost certainly wrong. * Remove unnecessary type check on `field` in `lift_leaves` since it is always `Int` * Move a branch disabling `return nothing` higher up * Remove some duplicated calculation on field index in `getfield_elim_pass!` * Fix `try_compute_fieldidx` to return `nothing` for non-`Int` `Integer` field index. This can cause `getfield_nothrow` to return incorrect result. It also gives the caller worse type info about the return value. * Teach `getfield_nothrow` that `isbits` field cannot be undefined and getfield on such field cannot throw. This is already handled in `isdefined_tfunc`. * Fix a few wrong use of `isbits` in dead branches ---- Ref #26948 (fa02d34) Ref #27126 (9100329)
* Use the field index passed in in `lift_leaves` The caller has already done all the computation including bound checking. The `field` computed in this function is also affecting all the following iterations which is almost certainly wrong. * Remove unnecessary type check on `field` in `lift_leaves` since it is always `Int` * Move a branch disabling `return nothing` higher up * Remove some duplicated calculation on field index in `getfield_elim_pass!` * Fix `try_compute_fieldidx` to return `nothing` for non-`Int` `Integer` field index. This can cause `getfield_nothrow` to return incorrect result. It also gives the caller worse type info about the return value. * Teach `getfield_nothrow` that `isbits` field cannot be undefined and getfield on such field cannot throw. This is already handled in `isdefined_tfunc`. * Fix a few wrong use of `isbits` in dead branches ---- Ref #26948 (fa02d34) Ref #27126 (9100329)
* Use the field index passed in in `lift_leaves` The caller has already done all the computation including bound checking. The `field` computed in this function is also affecting all the following iterations which is almost certainly wrong. * Remove unnecessary type check on `field` in `lift_leaves` since it is always `Int` * Move a branch disabling `return nothing` higher up * Remove some duplicated calculation on field index in `getfield_elim_pass!` * Fix `try_compute_fieldidx` to return `nothing` for non-`Int` `Integer` field index. This can cause `getfield_nothrow` to return incorrect result. It also gives the caller worse type info about the return value. * Teach `getfield_nothrow` that `isbits` field cannot be undefined and getfield on such field cannot throw. This is already handled in `isdefined_tfunc`. * Fix a few wrong use of `isbits` in dead branches ---- Ref JuliaLang#26948 (fa02d34) Ref JuliaLang#27126 (9100329)
Previously, the new optimizer used the pre-existing
effect_free
functionto determine whether it is safe to remove an unreferenced statement. However,
this function ignores many builtin's error cases, causing them to be
removed when that is not legal to do (because that would potentially remove
an exception that would otherwise be thrown). Start fixing this, by
introducing a version of the function that is correct for a subset of
intresting functions. We will likely need to expand this when we look
at the benchmarks, but this should be correct for now.