-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
inference: avoid unnecessary specializations in callinfo constructions
- Loading branch information
Showing
3 changed files
with
74 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,139 +1,162 @@ | ||
# This file is a part of Julia. License is MIT: https://julialang.org/license | ||
|
||
@nospecialize | ||
|
||
""" | ||
struct MethodMatchInfo | ||
call::CallMeta | ||
Captures the result of a `method_matches` lookup for the given call. This | ||
info may then be used by the optimizer to inline the matches, without having | ||
to re-consult the method table. This info is illegal on any statement that is | ||
not a call to a generic function. | ||
A simple struct that captures both the return type (`call.rt`) | ||
and any additional information (`call.info`) for a given generic call. | ||
""" | ||
struct MethodMatchInfo | ||
results::MethodLookupResult | ||
struct CallMeta | ||
rt::Any | ||
info::Any | ||
end | ||
|
||
""" | ||
struct MethodResultPure | ||
info::MethodMatchInfo | ||
This struct represents a method result constant was proven to be | ||
effect-free, including being no-throw (typically because the value was computed | ||
by calling an `@pure` function). | ||
Captures the result of a `:jl_matching_methods` lookup for the given call (`info.results`). | ||
This info may then be used by the optimizer to inline the matches, without having | ||
to re-consult the method table. This info is illegal on any statement that is | ||
not a call to a generic function. | ||
""" | ||
struct MethodResultPure | ||
info::Any | ||
end | ||
let instance = MethodResultPure(false) | ||
global MethodResultPure | ||
MethodResultPure() = instance | ||
struct MethodMatchInfo | ||
results::MethodLookupResult | ||
end | ||
|
||
""" | ||
struct UnionSplitInfo | ||
info::UnionSplitInfo | ||
If inference decides to partition the method search space by splitting unions, | ||
it will issue a method lookup query for each such partition. This info indicates | ||
that such partitioning happened and wraps the corresponding MethodMatchInfo for | ||
each partition. This info is illegal on any statement that is not a call to a | ||
generic function. | ||
that such partitioning happened and wraps the corresponding `MethodMatchInfo` for | ||
each partition (`info.matches::Vector{MethodMatchInfo}`). | ||
This info is illegal on any statement that is not a call to a generic function. | ||
""" | ||
struct UnionSplitInfo | ||
matches::Vector{MethodMatchInfo} | ||
end | ||
|
||
""" | ||
struct CallMeta | ||
info::MethodResultPure | ||
A simple struct that captures both the return type (`rt`) and any additional information | ||
(`info`) for a given generic call. | ||
This struct represents a method result constant was proven to be | ||
effect-free, including being no-throw (typically because the value was computed | ||
by calling an `@pure` function). | ||
""" | ||
struct CallMeta | ||
rt::Any | ||
info::Any | ||
struct MethodResultPure | ||
info::Union{MethodMatchInfo,UnionSplitInfo,Bool} | ||
end | ||
let instance = MethodResultPure(false) | ||
global MethodResultPure | ||
MethodResultPure() = instance | ||
end | ||
|
||
""" | ||
struct AbstractIterationInfo | ||
info::AbstractIterationInfo | ||
Captures all the information for abstract iteration analysis of a single value. | ||
Each (abstract) call to `iterate`, corresponds to one entry in `each`. | ||
Each (abstract) call to `iterate`, corresponds to one entry in `info.each::Vector{CallMeta}`. | ||
""" | ||
struct AbstractIterationInfo | ||
each::Vector{CallMeta} | ||
end | ||
|
||
const MaybeAbstractIterationInfo = Union{Nothing, AbstractIterationInfo} | ||
|
||
""" | ||
struct ApplyCallInfo | ||
info::ApplyCallInfo | ||
This info applies to any call of `_apply_iterate(...)` and captures both the | ||
info of the actual call being applied and the info for any implicit call | ||
to the `iterate` function. Note that it is possible for the call itself | ||
to be yet another `_apply_iterate`, in which case the `.call` field will | ||
to be yet another `_apply_iterate`, in which case the `info.call` field will | ||
be another `ApplyCallInfo`. This info is illegal on any statement that is | ||
not an `_apply_iterate` call. | ||
""" | ||
struct ApplyCallInfo | ||
# The info for the call itself | ||
call::Any | ||
# AbstractIterationInfo for each argument, if applicable | ||
arginfo::Vector{Union{Nothing, AbstractIterationInfo}} | ||
arginfo::Vector{MaybeAbstractIterationInfo} | ||
end | ||
|
||
""" | ||
struct UnionSplitApplyCallInfo | ||
info::UnionSplitApplyCallInfo | ||
Like `UnionSplitInfo`, but for `ApplyCallInfo` rather than MethodMatchInfo. | ||
Like `UnionSplitInfo`, but for `ApplyCallInfo` rather than `MethodMatchInfo`. | ||
This info is illegal on any statement that is not an `_apply_iterate` call. | ||
""" | ||
struct UnionSplitApplyCallInfo | ||
infos::Vector{ApplyCallInfo} | ||
end | ||
|
||
""" | ||
call::ConstCallInfo | ||
info::ConstCallInfo | ||
The precision of this call was improved using constant information. | ||
In addition to the original call information `call.call`, `call` also keeps | ||
the inference results with constant information `call.results::Vector{Union{Nothing,InferenceResult}}`. | ||
In addition to the original call information `info.call`, this info also keeps | ||
the inference results with constant information `info.results::Vector{Union{Nothing,InferenceResult}}`. | ||
""" | ||
struct ConstCallInfo | ||
call::Union{MethodMatchInfo,UnionSplitInfo} | ||
results::Vector{Union{Nothing,InferenceResult}} | ||
end | ||
|
||
""" | ||
call::InvokeCallInfo | ||
info::InvokeCallInfo | ||
Represents a resolved call to `invoke`, carrying the `call.match::MethodMatch` of the | ||
method that has been processed. | ||
Optionally keeps `result::InferenceResult` that carries constant information. | ||
Represents a resolved call to `Core.invoke`, carrying the `info.match::MethodMatch` of | ||
the method that has been processed. | ||
Optionally keeps `info.result::InferenceResult` that keeps constant information. | ||
""" | ||
struct InvokeCallInfo | ||
match::MethodMatch | ||
result::Union{Nothing,InferenceResult} | ||
end | ||
|
||
""" | ||
call::OpaqueClosureCallInfo | ||
info::OpaqueClosureCallInfo | ||
Represents a resolved call of opaque closure, carrying the `call.match::MethodMatch` of the | ||
method that has been processed. | ||
Optionally keeps `result::InferenceResult` that carries constant information. | ||
Represents a resolved call of opaque closure, carrying the `info.match::MethodMatch` of | ||
the method that has been processed. | ||
Optionally keeps `info.result::InferenceResult` that keeps constant information. | ||
""" | ||
struct OpaqueClosureCallInfo | ||
match::MethodMatch | ||
result::Union{Nothing,InferenceResult} | ||
end | ||
|
||
""" | ||
info::OpaqueClosureCreateInfo | ||
This info may be constructed upon opaque closure construction, with `info.unspec::CallMeta` | ||
carrying out inference result of an unreal, partially specialized call (i.e. specialized on | ||
the closure environment, but not on the argument types of the opaque closure) in order to | ||
allow the optimizer to rewrite the return type parameter of the `OpaqueClosure` based on it. | ||
""" | ||
struct OpaqueClosureCreateInfo | ||
unspec::CallMeta | ||
function OpaqueClosureCreateInfo(unspec::CallMeta) | ||
@assert isa(unspec.info, OpaqueClosureCallInfo) | ||
return new(unspec) | ||
end | ||
end | ||
|
||
# Stmt infos that are used by external consumers, but not by optimization. | ||
# These are not produced by default and must be explicitly opted into by | ||
# the AbstractInterpreter. | ||
|
||
""" | ||
info::ReturnTypeCallInfo | ||
Represents a resolved call of `Core.Compiler.return_type`. | ||
`info.call` wraps the info corresponding to the call that `Core.Compiler.return_type` call | ||
was supposed to analyze. | ||
""" | ||
struct ReturnTypeCallInfo | ||
# The info corresponding to the call that return_type was supposed to | ||
# analyze. | ||
info::Any | ||
end | ||
|
||
@specialize |