|
1 | 1 | module CompilerDevTools
|
2 | 2 |
|
3 | 3 | using Compiler
|
| 4 | +using Compiler: argextype, widenconst |
4 | 5 | using Core.IR
|
| 6 | +using Base: isexpr |
| 7 | + |
| 8 | +mutable struct SplitCacheOwner end |
5 | 9 |
|
6 |
| -struct SplitCacheOwner; end |
7 | 10 | struct SplitCacheInterp <: Compiler.AbstractInterpreter
|
8 | 11 | world::UInt
|
| 12 | + owner::SplitCacheOwner |
9 | 13 | inf_params::Compiler.InferenceParams
|
10 | 14 | opt_params::Compiler.OptimizationParams
|
11 | 15 | inf_cache::Vector{Compiler.InferenceResult}
|
12 | 16 | codegen_cache::IdDict{CodeInstance,CodeInfo}
|
13 | 17 | function SplitCacheInterp(;
|
14 | 18 | world::UInt = Base.get_world_counter(),
|
| 19 | + owner::SplitCacheOwner = SplitCacheOwner(), |
15 | 20 | inf_params::Compiler.InferenceParams = Compiler.InferenceParams(),
|
16 | 21 | opt_params::Compiler.OptimizationParams = Compiler.OptimizationParams(),
|
17 | 22 | inf_cache::Vector{Compiler.InferenceResult} = Compiler.InferenceResult[])
|
18 |
| - new(world, inf_params, opt_params, inf_cache, IdDict{CodeInstance,CodeInfo}()) |
| 23 | + new(world, owner, inf_params, opt_params, inf_cache, IdDict{CodeInstance,CodeInfo}()) |
19 | 24 | end
|
20 | 25 | end
|
21 | 26 |
|
22 | 27 | Compiler.InferenceParams(interp::SplitCacheInterp) = interp.inf_params
|
23 | 28 | Compiler.OptimizationParams(interp::SplitCacheInterp) = interp.opt_params
|
24 | 29 | Compiler.get_inference_world(interp::SplitCacheInterp) = interp.world
|
25 | 30 | Compiler.get_inference_cache(interp::SplitCacheInterp) = interp.inf_cache
|
26 |
| -Compiler.cache_owner(::SplitCacheInterp) = SplitCacheOwner() |
| 31 | +Compiler.cache_owner(interp::SplitCacheInterp) = interp.owner |
27 | 32 | Compiler.codegen_cache(interp::SplitCacheInterp) = interp.codegen_cache
|
28 | 33 |
|
29 | 34 | import Core.OptimizedGenerics.CompilerPlugins: typeinf, typeinf_edge
|
30 |
| -@eval @noinline typeinf(::SplitCacheOwner, mi::MethodInstance, source_mode::UInt8) = |
31 |
| - Base.invoke_in_world(which(typeinf, Tuple{SplitCacheOwner, MethodInstance, UInt8}).primary_world, Compiler.typeinf_ext_toplevel, SplitCacheInterp(; world=Base.tls_world_age()), mi, source_mode) |
| 35 | +@eval @noinline typeinf(owner::SplitCacheOwner, mi::MethodInstance, source_mode::UInt8) = |
| 36 | + Base.invoke_in_world(which(typeinf, Tuple{SplitCacheOwner, MethodInstance, UInt8}).primary_world, Compiler.typeinf_ext_toplevel, SplitCacheInterp(; world=Base.tls_world_age(), owner), mi, source_mode) |
32 | 37 |
|
33 |
| -@eval @noinline function typeinf_edge(::SplitCacheOwner, mi::MethodInstance, parent_frame::Compiler.InferenceState, world::UInt, source_mode::UInt8) |
| 38 | +@eval @noinline function typeinf_edge(owner::SplitCacheOwner, mi::MethodInstance, parent_frame::Compiler.InferenceState, world::UInt, source_mode::UInt8) |
34 | 39 | # TODO: This isn't quite right, we're just sketching things for now
|
35 |
| - interp = SplitCacheInterp(; world) |
| 40 | + interp = SplitCacheInterp(; world, owner) |
36 | 41 | Compiler.typeinf_edge(interp, mi.def, mi.specTypes, Core.svec(), parent_frame, false, false)
|
37 | 42 | end
|
38 | 43 |
|
39 |
| -function with_new_compiler(f, args...) |
40 |
| - mi = @ccall jl_method_lookup(Any[f, args...]::Ptr{Any}, (1+length(args))::Csize_t, Base.tls_world_age()::Csize_t)::Ref{Core.MethodInstance} |
41 |
| - world = Base.tls_world_age() |
| 44 | +function lookup_method_instance(f, args...) |
| 45 | + @ccall jl_method_lookup(Any[f, args...]::Ptr{Any}, (1+length(args))::Csize_t, Base.tls_world_age()::Csize_t)::Ref{Core.MethodInstance} |
| 46 | +end |
| 47 | + |
| 48 | +function Compiler.optimize(interp::SplitCacheInterp, opt::Compiler.OptimizationState, caller::Compiler.InferenceResult) |
| 49 | + @invoke Compiler.optimize(interp::Compiler.AbstractInterpreter, opt::Compiler.OptimizationState, caller::Compiler.InferenceResult) |
| 50 | + ir = opt.ir::Compiler.IRCode |
| 51 | + override = GlobalRef(@__MODULE__(), :with_new_compiler) |
| 52 | + for inst in ir.stmts |
| 53 | + stmt = inst[:stmt] |
| 54 | + isexpr(stmt, :call) || continue |
| 55 | + f = stmt.args[1] |
| 56 | + f === override && continue |
| 57 | + if isa(f, GlobalRef) |
| 58 | + T = widenconst(argextype(f, ir)) |
| 59 | + T <: Core.Builtin && continue |
| 60 | + end |
| 61 | + insert!(stmt.args, 1, override) |
| 62 | + insert!(stmt.args, 3, interp.owner) |
| 63 | + end |
| 64 | +end |
| 65 | + |
| 66 | +with_new_compiler(f, args...; owner::SplitCacheOwner = SplitCacheOwner()) = with_new_compiler(f, owner, args...) |
| 67 | + |
| 68 | +function with_new_compiler(f, owner::SplitCacheOwner, args...) |
| 69 | + mi = lookup_method_instance(f, args...) |
42 | 70 | new_compiler_ci = Core.OptimizedGenerics.CompilerPlugins.typeinf(
|
43 |
| - SplitCacheOwner(), mi, Compiler.SOURCE_MODE_ABI |
| 71 | + owner, mi, Compiler.SOURCE_MODE_ABI |
44 | 72 | )
|
45 | 73 | invoke(f, new_compiler_ci, args...)
|
46 | 74 | end
|
|
0 commit comments