|
1 | | -const __bodyfunction__ = Dict{Method,Any}() |
| 1 | +using PrecompileTools: @setup_workload, @compile_workload |
2 | 2 |
|
3 | | -# Find keyword "body functions" (the function that contains the body |
4 | | -# as written by the developer, called after all missing keyword-arguments |
5 | | -# have been assigned values), in a manner that doesn't depend on |
6 | | -# gensymmed names. |
7 | | -# `mnokw` is the method that gets called when you invoke it without |
8 | | -# supplying any keywords. |
9 | | -function __lookup_kwbody__(mnokw::Method) |
10 | | - function getsym(arg) |
11 | | - isa(arg, Symbol) && return arg |
12 | | - @assert isa(arg, GlobalRef) |
13 | | - return arg.name |
| 3 | +@setup_workload begin |
| 4 | + precompile_module = @eval module $(gensym()) |
| 5 | + using ..GPUCompiler |
| 6 | + |
| 7 | + module DummyRuntime |
| 8 | + # dummy methods |
| 9 | + signal_exception() = return |
| 10 | + malloc(sz) = C_NULL |
| 11 | + report_oom(sz) = return |
| 12 | + report_exception(ex) = return |
| 13 | + report_exception_name(ex) = return |
| 14 | + report_exception_frame(idx, func, file, line) = return |
| 15 | + end |
| 16 | + |
| 17 | + struct DummyCompilerParams <: AbstractCompilerParams end |
| 18 | + const DummyCompilerJob = CompilerJob{NativeCompilerTarget, DummyCompilerParams} |
| 19 | + |
| 20 | + GPUCompiler.runtime_module(::DummyCompilerJob) = DummyRuntime |
14 | 21 | end |
15 | 22 |
|
16 | | - f = get(__bodyfunction__, mnokw, nothing) |
17 | | - if f === nothing |
18 | | - fmod = mnokw.module |
19 | | - # The lowered code for `mnokw` should look like |
20 | | - # %1 = mkw(kwvalues..., #self#, args...) |
21 | | - # return %1 |
22 | | - # where `mkw` is the name of the "active" keyword body-function. |
23 | | - ast = Base.uncompressed_ast(mnokw) |
24 | | - if isa(ast, Core.CodeInfo) && length(ast.code) >= 2 |
25 | | - callexpr = ast.code[end-1] |
26 | | - if isa(callexpr, Expr) && callexpr.head == :call |
27 | | - fsym = callexpr.args[1] |
28 | | - if isa(fsym, Symbol) |
29 | | - f = getfield(fmod, fsym) |
30 | | - elseif isa(fsym, GlobalRef) |
31 | | - if fsym.mod === Core && fsym.name === :_apply |
32 | | - f = getfield(mnokw.module, getsym(callexpr.args[2])) |
33 | | - elseif fsym.mod === Core && fsym.name === :_apply_iterate |
34 | | - f = getfield(mnokw.module, getsym(callexpr.args[3])) |
35 | | - else |
36 | | - f = getfield(fsym.mod, fsym.name) |
37 | | - end |
38 | | - else |
39 | | - f = missing |
40 | | - end |
41 | | - else |
42 | | - f = missing |
43 | | - end |
44 | | - else |
45 | | - f = missing |
| 23 | + kernel() = nothing |
| 24 | + |
| 25 | + @compile_workload begin |
| 26 | + source = methodinstance(typeof(kernel), Tuple{}) |
| 27 | + target = NativeCompilerTarget() |
| 28 | + params = precompile_module.DummyCompilerParams() |
| 29 | + config = CompilerConfig(target, params) |
| 30 | + job = CompilerJob(source, config) |
| 31 | + |
| 32 | + JuliaContext() do ctx |
| 33 | + # XXX: on Windows, compiling the GPU runtime leaks GPU code in the native cache, |
| 34 | + # so prevent building the runtime library (see JuliaGPU/GPUCompiler.jl#601) |
| 35 | + GPUCompiler.compile(:asm, job; libraries=false) |
46 | 36 | end |
47 | | - __bodyfunction__[mnokw] = f |
48 | 37 | end |
49 | | - return f |
50 | | -end |
51 | 38 |
|
52 | | -function _precompile_() |
53 | | - ccall(:jl_generating_output, Cint, ()) == 1 || return nothing |
54 | | - @assert precompile(Tuple{typeof(GPUCompiler.assign_args!),Expr,Vector{Any}}) |
55 | | - @assert precompile(Tuple{typeof(GPUCompiler.lower_unreachable!),LLVM.Function}) |
56 | | - @assert precompile(Tuple{typeof(GPUCompiler.lower_gc_frame!),LLVM.Function}) |
57 | | - @assert precompile(Tuple{typeof(GPUCompiler.lower_throw!),LLVM.Module}) |
58 | | - #@assert precompile(Tuple{typeof(GPUCompiler.split_kwargs),Tuple{},Vector{Symbol},Vararg{Vector{Symbol}, N} where N}) |
59 | | - # let fbody = try __lookup_kwbody__(which(GPUCompiler.compile, (Symbol,GPUCompiler.CompilerJob,))) catch missing end |
60 | | - # if !ismissing(fbody) |
61 | | - # @assert precompile(fbody, (Bool,Bool,Bool,Bool,Bool,Bool,Bool,typeof(GPUCompiler.compile),Symbol,GPUCompiler.CompilerJob,)) |
62 | | - # @assert precompile(fbody, (Bool,Bool,Bool,Bool,Bool,Bool,Bool,typeof(GPUCompiler.compile),Symbol,GPUCompiler.CompilerJob,)) |
63 | | - # end |
64 | | - # end |
| 39 | + # reset state that was initialized during precompilation |
| 40 | + __llvm_initialized[] = false |
65 | 41 | end |
0 commit comments