-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Ensure CI from external MI and foreign abs interpreter survive precompilation #60747
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
base: master
Are you sure you want to change the base?
Changes from all commits
54fbf13
9a8e5d2
28258c4
aad3a99
cdd1fc7
364e470
5456f9d
e63e802
b0bd228
aa1846b
ca70636
289699e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # This file is a part of Julia. License is MIT: https://julialang.org/license | ||
|
|
||
| using Test | ||
|
|
||
| include("precompile_utils.jl") | ||
|
|
||
| precompile_test_harness() do load_path | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @aviatesk I added a new test here instead of adding to precopile_absintX since the structure is slightly different. The test comes from where we have a "compiler" package and a "user" package, and we are adding a code instance to a method instance that is already owned somewhere else |
||
| write(joinpath(load_path, "ExampleCompiler.jl"), :( | ||
vchuravy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| module ExampleCompiler | ||
| const CC = Core.Compiler | ||
|
|
||
| struct ExampleInterpreter <: CC.AbstractInterpreter | ||
| world::UInt | ||
| inf_cache::Vector{CC.InferenceResult} | ||
| end | ||
| ExampleInterpreter(world::UInt) = | ||
| ExampleInterpreter(world, CC.InferenceResult[]) | ||
|
|
||
| CC.InferenceParams(::ExampleInterpreter) = CC.InferenceParams() | ||
| CC.OptimizationParams(::ExampleInterpreter) = CC.OptimizationParams() | ||
| CC.get_inference_cache(interp::ExampleInterpreter) = interp.inf_cache | ||
| CC.cache_owner(interp::ExampleInterpreter) = :ExampleInterpreter | ||
|
|
||
| CC.get_inference_world(interp::ExampleInterpreter) = interp.world | ||
| CC.lock_mi_inference(::ExampleInterpreter, ::Core.MethodInstance) = nothing | ||
| CC.unlock_mi_inference(::ExampleInterpreter, ::Core.MethodInstance) = nothing | ||
|
|
||
| function infer(mi, world) | ||
| interp = ExampleInterpreter(world) | ||
| ci = CC.typeinf_ext(interp, mi, CC.SOURCE_MODE_GET_SOURCE) | ||
| @assert ci !== nothing "Inference of $mi failed" | ||
|
|
||
| return ci | ||
| end | ||
|
|
||
| function precompile(f, tt; world = Base.get_world_counter()) | ||
| mi = Base.method_instance(f, tt; world) | ||
| infer(mi, world) | ||
| end | ||
| end) |> string) | ||
| Base.compilecache(Base.PkgId("ExampleCompiler")) | ||
|
|
||
| write(joinpath(load_path, "ExampleUser.jl"), :( | ||
| module ExampleUser | ||
| import ExampleCompiler | ||
|
|
||
| function square(x) | ||
| return x * x | ||
| end | ||
| ExampleCompiler.precompile(square, (Float64,)) | ||
|
|
||
| # Stubbed together version of PrecompileTools | ||
| ccall(:jl_tag_newly_inferred_enable, Cvoid, ()) | ||
| try | ||
| # Important `identity(::Any) mi does not belong to us` | ||
| ExampleCompiler.precompile(identity, (Float64,)) | ||
| finally | ||
| ccall(:jl_tag_newly_inferred_disable, Cvoid, ()) | ||
| end | ||
| end) |> string) | ||
| Base.compilecache(Base.PkgId("ExampleUser")) | ||
|
|
||
| @eval let | ||
| using ExampleUser | ||
| cache_owner = :ExampleInterpreter | ||
|
|
||
| mi_square = Base.method_instance(ExampleUser.square, (Float64,)) | ||
| @test check_presence(mi_square, :ExampleInterpreter) !== nothing | ||
|
|
||
| mi_identity = Base.method_instance(identity, (Float64,)) | ||
| @test check_presence(mi_identity, :ExampleInterpreter) !== nothing | ||
| end | ||
| end | ||
|
|
||
| finish_precompile_test!() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,3 +29,15 @@ let original_depot_path = copy(Base.DEPOT_PATH) | |
| append!(Base.LOAD_PATH, original_load_path) | ||
| end | ||
| end | ||
|
|
||
| function check_presence(mi, token) | ||
| ci = isdefined(mi, :cache) ? mi.cache : nothing | ||
| while ci !== nothing | ||
| if ci.owner === token | ||
| @test ci.max_world == Base.ReinferUtils.WORLD_AGE_REVALIDATION_SENTINEL || ci.min_world <= 1 | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vtjnash I am a bit confused about this query:
The values I am observing here are: Which does look to me like they are correctly integrated? But they of course fail the test, since |
||
| return ci | ||
| end | ||
| ci = isdefined(ci, :next) ? ci.next : nothing | ||
| end | ||
| return nothing | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.