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

Optimize away try/catch blocks that are known not to trigger #51674

Merged
merged 2 commits into from Oct 15, 2023
Merged

Conversation

Keno
Copy link
Member

@Keno Keno commented Oct 12, 2023

This leverages the support from #51590 to delete any try catch block that is known not to be triggered (either because the try-body is empty to because we have proven :nothrow for all contained statements).

Fix #34270.

@Keno
Copy link
Member Author

Keno commented Oct 12, 2023

@nanosoldier runtests().

@brenhinkeller brenhinkeller added the performance Must go faster label Oct 13, 2023
@nanosoldier
Copy link
Collaborator

The package evaluation job you requested has completed - possible new issues were detected.
The full report is available.

@Keno
Copy link
Member Author

Keno commented Oct 14, 2023

@nanosoldier runtests(["AlignedSpans", "AtmosphericModels", "WinchModels", "OptimizationMetaheuristics", "TMLE", "LongwaveModePropagator", "KitePodModels", "MixedModelsPermutations", "HetaSimulator", "ModeCouplingTheory", "SpatialEcology", "TrajectoryGamesBase", "DTables", "ChemicalIdentifiers", "StatsKit", "NCEI", "ManifoldDiff", "AstrodynamicalModels", "TimeseriesTools", "MiseEnPage", "SGtSNEpi", "GIFImages", "HiGHS", "FinEtoolsVoxelMesher", "Grumps", "GasChromatographySimulator", "HierarchicalTemporalMemory", "KiteUtils", "LinRegOutliers", "CausalityTools", "MINDFulMakie", "EpithelialDynamics1D", "UnfoldSim", "GeoInterfaceMakie", "MRINavigator", "JumpProblemLibrary", "EarlyStopping", "OndaEDFSchemas", "MinimallyDisruptiveCurves", "PALEOaqchem", "MetidaBioeq", "RangeTrees", "Agents", "PlutoStaticHTML", "Petri", "MixedModelsDatasets", "Tapestree", "RxEnvironments", "MixedModelsSim", "OndaEDF", "InteractiveDynamics", "SymbolicNumericIntegration", "HiQGA", "ManifoldsBase", "BayesianQuadrature", "PALEOocean", "Dynesty", "BDisposal", "Legolas", "AnovaMixedModels", "GeometricIntegrators", "MixedModelsSerialization", "DPFEHM", "IterativeLearningControl", "HierarchicalEOM", "RigorousInvariantMeasures", "BM3DDenoise"])

Copy link
Sponsor Member

@aviatesk aviatesk left a comment

Choose a reason for hiding this comment

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

LGTM.

base/compiler/abstractinterpretation.jl Outdated Show resolved Hide resolved
base/compiler/abstractinterpretation.jl Show resolved Hide resolved
@nanosoldier
Copy link
Collaborator

The package evaluation job you requested has completed - possible new issues were detected.
The full report is available.

This leverages the support from #51590 to delete any try catch block
that is known not to be triggered (either because the try-body is
empty to because we have proven `:nothrow` for all contained
statements).
@Keno Keno merged commit 0acca3c into master Oct 15, 2023
6 checks passed
@Keno Keno deleted the kf/erroropt branch October 15, 2023 19:21
Keno added a commit that referenced this pull request Oct 18, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Oct 18, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
aviatesk pushed a commit that referenced this pull request Oct 24, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 3, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 13, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 13, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 17, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 17, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 18, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 19, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However,
there are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that
is the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work
on interface checking (since interfaces imply the absence of
MethodErrors), so this PR lays the groundwork for appropriate modeling
of these error paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing
to `Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Keno added a commit that referenced this pull request Nov 19, 2023
Currently the type of a caught exception is always modeled as `Any`.
This isn't a huge problem, because control flow in Julia is generally
assumed to be somewhat slow, so the extra type imprecision of not
knowing the return type does not matter all that much. However, there
are a few situations where it matters. For example:

```
maybe_getindex(A, i) =
    try; A[i]; catch e; isa(e, BoundsError) && return nothing; rethrow(); end
```

At present, we cannot infer :nothrow for this method, even if that is
the only error type that `A[i]` can throw. This is particularly
noticable, since we can now optimize away `:nothrow` exception frames
entirely (#51674). Note that this PR still does not make the above
example particularly efficient (at least interprocedurally), though
specialized codegen could be added on top of this to make that happen.
It does however improve the inference result.

A second major motivation of this change is that reasoning about
exception types is likely to be a major aspect of any future work on
interface checking (since interfaces imply the absence of MethodErrors),
so this PR lays the groundwork for appropriate modeling of these error
paths.

Note that this PR adds all the required plumbing, but does not yet have
a particularly precise model of error types for our builtins, bailing to
`Any` for any builtin not known to be `:nothrow`. This can be improved
in follow up PRs as required.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Must go faster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optimize away overhead from setting up try catch if exception is impossible
4 participants