-
-
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
AbstractInterpreter
: implement findsup
for OverlayMethodTable
#44448
Conversation
base/compiler/methodtable.jl
Outdated
min_valid[] = typemin(UInt) | ||
max_valid[] = typemax(UInt) |
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.
technically not legal to reset this, but is perfectly acceptable not to
min_valid[] = typemin(UInt) | |
max_valid[] = typemax(UInt) |
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.
I decided to make a duplicated call to findsup
here.
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.
ah, makes sense
though note it is mandatory to preserve the lookup min_valid/max_valid regardless of whether you get a result
note 2 that it is also always mandatory to execute the "fall back to the internal method table" code, unless you can prove that the results are fully covered
3716665
to
246b900
Compare
base/compiler/methodtable.jl
Outdated
end | ||
|
||
function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=typemax(Int)) | ||
result = _findall(sig, table.mt, table.world, limit) | ||
result === missing || isempty(result) || return result |
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.
If this part of the result is missing
, then the total result must also be missing
Though I find the change between false
and missing
to be somewhat odd for the API–you don't get less by adding more. Perhaps we should use something consistent such as nothing
? (even true
might be a better choice, since it means we found too many matches)
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.
Yeah, I think nothing
or missing
would be better, since they are easier to be handled by Conditional
? Given that such case means "too many matches", missing
sounds a bit counter-intuitive.
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.
246b900
to
219f08d
Compare
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
219f08d
to
c86d43a
Compare
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Now `jl_gf_invoke_lookup` accepts an optional overlayed method table, but actual code execution (as done by JuliaInterpreter) doesn't need to care about it at this moment.
Now `jl_gf_invoke_lookup` accepts an optional overlayed method table, but actual code execution (as done by JuliaInterpreter) doesn't need to care about it at this moment.
result = _findall(sig, table.mt, table.world, limit) | ||
result === missing && return missing | ||
if !isempty(result) | ||
if all(match->match.fully_covers, result) |
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.
It only matters if result[end].fully_covers
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.
Let me check my understanding.
We can just look at result[end].fully_covers
since:
jl_matching_methods
returns matching methods in order of speciality
(and so the last match is always the most general case)- if the last match
fully_covers
, it means this call is assured to be
dispatched to the last match when it's not dispatched with the other matches
WorldRange(min(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world), | ||
max(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)), |
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.
you need the max of the min_worlds and the min of the max_worlds
result.ambig | fallback_result.ambig) | ||
end | ||
end | ||
# fall back to the internal method table |
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.
Even if the result is empty, you are still required to return the valid_worlds
data from the (failed) lookup
(result.method, WorldRange(min_valid[], max_valid[])) | ||
result = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}), | ||
sig, mt, world, min_valid, max_valid)::Union{MethodMatch, Nothing} | ||
return result === nothing ? result : (result, WorldRange(min_valid[], max_valid[])) |
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.
This is conservatively correct currently (since we return Any
), but it would be more correct to return the tuple unconditionally, since the WorldRange applies to the lookup, regardless of the result.
- respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
- respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
- respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
#44511) - respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
#44511) - respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
…44478) Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
Previously
findsup
doesn't supportOverlayMethodTable
at all.This hasn't been recognized since
abstract_invoke
didn't usethe
method_table
interface properly until #44389 ,but now we need this support.
xref: JuliaGPU/GPUCompiler.jl#303 (comment)