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

Use jl_method_lookup_by_tt #546

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,17 @@ runtime_module(@nospecialize(job::CompilerJob)) = error("Not implemented")
isintrinsic(@nospecialize(job::CompilerJob), fn::String) = false

# provide a specific interpreter to use.
if isdefined(Base, :method_instance)
get_interpreter(@nospecialize(job::CompilerJob)) =
GPUInterpreter(job.world; method_table=method_table(job),
token=ci_cache_token(job), inf_params=inference_params(job),
opt_params=optimization_params(job))
else
get_interpreter(@nospecialize(job::CompilerJob)) =
GPUInterpreter(job.world; method_table=method_table(job),
code_cache=ci_cache(job), inf_params=inference_params(job),
opt_params=optimization_params(job))
end

# does this target support throwing Julia exceptions with jl_throw?
# if not, calls to throw will be replaced with calls to the GPU runtime
Expand Down Expand Up @@ -207,7 +214,23 @@ needs_byval(@nospecialize(job::CompilerJob)) = true
# whether pointer is a valid call target
valid_function_pointer(@nospecialize(job::CompilerJob), ptr::Ptr{Cvoid}) = false

# Care is required for anything that impacts:
# - method_table
# - inference_params
# - optimization_params
# By default that is just always_inline
# the cache token is compared with jl_egal
struct GPUCompilerCacheToken
target_type::Type
always_inline::Bool
end

ci_cache_token(@nospecialize(job::CompilerJob)) = GPUCompilerCacheToken(typeof(job.config.target), job.config.always_inline)

# the codeinfo cache to use
if isdefined(Core.Compiler, :cache_owner)
ci_cache(@nospecialize(job::CompilerJob)) = Core.Compiler.InternalCodeCache(ci_cache_token(job))
else
function ci_cache(@nospecialize(job::CompilerJob))
lock(GLOBAL_CI_CACHES_LOCK) do
cache = get!(GLOBAL_CI_CACHES, job.config) do
Expand All @@ -216,6 +239,7 @@ function ci_cache(@nospecialize(job::CompilerJob))
return cache
end
end
end

# the method table to use
method_table(@nospecialize(job::CompilerJob)) = GLOBAL_METHOD_TABLE
Expand Down
97 changes: 82 additions & 15 deletions src/jlgen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,34 @@
# `tls_world_age` should be used to look up the current world age. in most cases, this is
# what you should use to invoke the compiler with.

tls_world_age() = ccall(:jl_get_tls_world_age, UInt, ())

if isdefined(Base, :tls_world_age)
import Base: tls_world_age
else
tls_world_age() = ccall(:jl_get_tls_world_age, UInt, ())
end

## looking up method instances

export methodinstance

@static if isdefined(Base, :method_instance)
function signature_type_by_tt(ft, tt)
u = Base.unwrap_unionall(tt)::DataType
return Base.rewrap_unionall(Tuple{ft, u.parameters...}, tt)
end

function methodinstance(ft, tt, world=tls_world_age())
# XXX: Base.method_instance uses f not ft...
sig = signature_type_by_tt(ft, tt)
mi = ccall(:jl_method_lookup_by_tt, Any,
(Any, Csize_t, Any),
sig, world, #=method_table=# nothing)
# XXX: MethodError takes `f` not `ft`?
mi === nothing && throw(MethodError(ft, tt, world))
return mi
end
else

@inline function typed_signature(ft::Type, tt::Type)
u = Base.unwrap_unionall(tt)
return Base.rewrap_unionall(Tuple{ft, u.parameters...}, tt)
Expand Down Expand Up @@ -43,17 +64,6 @@ macro LineInfoNode(method)
end
end

"""
methodinstance(ft::Type, tt::Type, [world::UInt])

Look up the method instance that corresponds to invoking the function with type `ft` with
argument typed `tt`. If the `world` argument is specified, the look-up is static and will
always return the same result. If the `world` argument is not specified, the look-up is
dynamic and the returned method instance will automatically be invalidated when a relevant
function is redefined.

If the method is not found, a `MethodError` is thrown.
"""
function methodinstance(ft::Type, tt::Type, world::Integer)
sig = typed_signature(ft, tt)

Expand Down Expand Up @@ -134,9 +144,24 @@ methodinstance(f, tt) = methodinstance(f, tt, tls_world_age())

end

end # isdefined(Base, :method_instance)
@doc """
methodinstance(ft::Type, tt::Type, [world::UInt])

Look up the method instance that corresponds to invoking the function with type `ft` with
argument typed `tt`. If the `world` argument is specified, the look-up is static and will
always return the same result. If the `world` argument is not specified, the look-up is
dynamic and the returned method instance will automatically be invalidated when a relevant
function is redefined.

If the method is not found, a `MethodError` is thrown.
""" methodinstance


## code instance cache
const HAS_INTEGRATED_CACHE = isdefined(Core.Compiler, :cache_owner)

if !HAS_INTEGRATED_CACHE
struct CodeCache
dict::IdDict{MethodInstance,Vector{CodeInstance}}

Expand Down Expand Up @@ -264,6 +289,7 @@ function (callback::CodeCacheCallback)(replaced::MethodInstance, max_world::UInt
end

end
end # !HAS_INTEGRATED_CACHE

## method overrides

Expand Down Expand Up @@ -295,13 +321,47 @@ struct GPUInterpreter <: CC.AbstractInterpreter
world::UInt
method_table::GPUMethodTableView

@static if HAS_INTEGRATED_CACHE
token::Any
else
code_cache::CodeCache
end
inf_cache::Vector{CC.InferenceResult}

inf_params::CC.InferenceParams
opt_params::CC.OptimizationParams
end

@static if HAS_INTEGRATED_CACHE
function GPUInterpreter(world::UInt=Base.get_world_counter();
method_table::MTType,
token::Any,
inf_params::CC.InferenceParams,
opt_params::CC.OptimizationParams)
@assert world <= Base.get_world_counter()

method_table = get_method_table_view(world, method_table)
inf_cache = Vector{CC.InferenceResult}()

return GPUInterpreter(world, method_table,
token, inf_cache,
inf_params, opt_params)
end

function GPUInterpreter(interp::GPUInterpreter;
world::UInt=interp.world,
method_table::GPUMethodTableView=interp.method_table,
token::Any=interp.token,
inf_cache::Vector{CC.InferenceResult}=interp.inf_cache,
inf_params::CC.InferenceParams=interp.inf_params,
opt_params::CC.OptimizationParams=interp.opt_params)
return GPUInterpreter(world, method_table,
token, inf_cache,
inf_params, opt_params)
end

else

function GPUInterpreter(world::UInt=Base.get_world_counter();
method_table::MTType,
code_cache::CodeCache,
Expand All @@ -328,12 +388,17 @@ function GPUInterpreter(interp::GPUInterpreter;
code_cache, inf_cache,
inf_params, opt_params)
end
end # HAS_INTEGRATED_CACHE

CC.InferenceParams(interp::GPUInterpreter) = interp.inf_params
CC.OptimizationParams(interp::GPUInterpreter) = interp.opt_params
#=CC.=#get_inference_world(interp::GPUInterpreter) = interp.world
CC.get_inference_cache(interp::GPUInterpreter) = interp.inf_cache
CC.code_cache(interp::GPUInterpreter) = WorldView(interp.code_cache, interp.world)
if HAS_INTEGRATED_CACHE
CC.cache_owner(interp::GPUInterpreter) = interp.token
else
CC.code_cache(interp::GPUInterpreter) = WorldView(interp.code_cache, interp.world)
end

# No need to do any locking since we're not putting our results into the runtime cache
CC.lock_mi_inference(interp::GPUInterpreter, mi::MethodInstance) = nothing
Expand Down Expand Up @@ -385,9 +450,10 @@ end


## world view of the cache

using Core.Compiler: WorldView

if !HAS_INTEGRATED_CACHE

function CC.haskey(wvc::WorldView{CodeCache}, mi::MethodInstance)
CC.get(wvc, mi, nothing) !== nothing
end
Expand Down Expand Up @@ -426,6 +492,7 @@ function CC.setindex!(wvc::WorldView{CodeCache}, ci::CodeInstance, mi::MethodIns
CC.setindex!(wvc.cache, ci, mi)
end

end # HAS_INTEGRATED_CACHE

## codegen/inference integration

Expand Down
1 change: 0 additions & 1 deletion test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
LLVM = "929cbde3-209d-540e-8aea-75f648917ca0"
Metal_LLVM_Tools_jll = "0418c028-ff8c-56b8-a53e-0f9676ed36fc"
Expand Down
Loading