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

[NewOptimizer] Make stmt_effect_free less aggressive #26948

Merged
merged 1 commit into from
May 2, 2018
Merged

Conversation

Keno
Copy link
Member

@Keno Keno commented May 1, 2018

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.

@Keno Keno requested review from vtjnash and JeffBezanson May 1, 2018 20:09
@Keno Keno mentioned this pull request May 1, 2018
18 tasks
@Keno Keno added the compiler:optimizer Optimization passes (mostly in base/compiler/ssair/) label May 1, 2018
@Keno Keno force-pushed the kf/effectfree branch from 981b8fc to 7b5b956 Compare May 1, 2018 20:35
(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
Copy link
Member

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

Copy link
Member Author

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?

Copy link
Member

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)
Copy link
Member

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)

Copy link
Member Author

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?

Copy link
Member

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

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)
Copy link
Member

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

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
Copy link
Member

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.
@Keno Keno force-pushed the kf/effectfree branch from 7b5b956 to fa02d34 Compare May 1, 2018 21:37
@Keno Keno merged commit 60031ad into master May 2, 2018
@martinholters martinholters deleted the kf/effectfree branch May 2, 2018 11:47
yuyichao added a commit that referenced this pull request Sep 6, 2020
* 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)
yuyichao added a commit that referenced this pull request Sep 6, 2020
* 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)
yuyichao added a commit that referenced this pull request Sep 6, 2020
* 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)
Keno pushed a commit that referenced this pull request Dec 30, 2020
* 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)
ElOceanografo pushed a commit to ElOceanografo/julia that referenced this pull request May 4, 2021
* 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:optimizer Optimization passes (mostly in base/compiler/ssair/)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants