diff --git a/base/loading.jl b/base/loading.jl index b26a063247169..87ce12588aa6b 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -4166,17 +4166,19 @@ end compiler_chi(tup::Tuple) = CacheHeaderIncludes(expand_compiler_path(tup)) """ - precompile(f, argtypes::Tuple{Vararg{Any}}) + precompile(f, argtypes::Tuple{Vararg{Any}}; check_only::Bool=false) Compile the given function `f` for the argument tuple (of types) `argtypes`, but do not execute it. +If `check_only` is `true`, do not compile `f`; check whether `f` should be compileable for `argtypes` +and return `true` or `false` accordingly. """ -function precompile(@nospecialize(f), @nospecialize(argtypes::Tuple)) - precompile(Tuple{Core.Typeof(f), argtypes...}) +function precompile(@nospecialize(f), @nospecialize(argtypes::Tuple); check_only::Bool=false) + precompile(Tuple{Core.Typeof(f), argtypes...}; check_only) end const ENABLE_PRECOMPILE_WARNINGS = Ref(false) -function precompile(@nospecialize(argt::Type)) - ret = ccall(:jl_compile_hint, Int32, (Any,), argt) != 0 +function precompile(@nospecialize(argt::Type); check_only::Bool=false) + ret = ccall(:jl_compile_hint, Int32, (Any, Cint), argt, check_only) != 0 if !ret && ENABLE_PRECOMPILE_WARNINGS[] @warn "Inactive precompile statement" maxlog=100 form=argt _module=nothing _file=nothing _line=0 end diff --git a/src/gf.c b/src/gf.c index 5b21dfa7e1143..b339c249961ad 100644 --- a/src/gf.c +++ b/src/gf.c @@ -3365,7 +3365,7 @@ JL_DLLEXPORT void jl_compile_method_sig(jl_method_t *m, jl_value_t *types, jl_sv jl_compile_method_instance(mi, NULL, world); } -JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) +JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types, int check_only) { size_t world = jl_atomic_load_acquire(&jl_world_counter); size_t min_valid = 0; @@ -3373,8 +3373,10 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) jl_method_instance_t *mi = jl_get_compile_hint_specialization(types, world, &min_valid, &max_valid, 1); if (mi == NULL) return 0; - JL_GC_PROMISE_ROOTED(mi); - jl_compile_method_instance(mi, types, world); + if (!check_only) { + JL_GC_PROMISE_ROOTED(mi); + jl_compile_method_instance(mi, types, world); + } return 1; } diff --git a/src/julia_internal.h b/src/julia_internal.h index fd8720b7f1701..8dc1e4a11fa9e 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -713,7 +713,7 @@ JL_DLLEXPORT const char *jl_debuginfo_name(jl_value_t *func) JL_NOTSAFEPOINT; JL_DLLEXPORT int jl_is_compiled_codeinst(jl_code_instance_t *codeinst) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_compile_method_instance(jl_method_instance_t *mi, jl_tupletype_t *types, size_t world); JL_DLLEXPORT void jl_compile_method_sig(jl_method_t *m, jl_value_t *types, jl_svec_t *sparams, size_t world); -JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types); +JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types, int check_only); JL_DLLEXPORT int jl_add_entrypoint(jl_tupletype_t *types); jl_code_info_t *jl_code_for_interpreter(jl_method_instance_t *lam JL_PROPAGATES_ROOT, size_t world); jl_value_t *jl_code_or_ci_for_interpreter(jl_method_instance_t *lam JL_PROPAGATES_ROOT, size_t world); diff --git a/src/precompile.c b/src/precompile.c index c21cf5367fba6..bcb1f8d1cf518 100644 --- a/src/precompile.c +++ b/src/precompile.c @@ -132,7 +132,7 @@ JL_DLLEXPORT void jl_write_compiler_output(void) jl_value_t *tt = jl_is_type(f) ? (jl_value_t*)jl_wrap_Type(f) : jl_typeof(f); JL_GC_PUSH1(&tt); tt = jl_apply_tuple_type_v(&tt, 1); - jl_compile_hint((jl_tupletype_t*)tt); + jl_compile_hint((jl_tupletype_t*)tt, 0); if (jl_options.trim) jl_add_entrypoint((jl_tupletype_t*)tt); JL_GC_POP(); diff --git a/src/precompile_utils.c b/src/precompile_utils.c index 84619b714b624..5378786931fca 100644 --- a/src/precompile_utils.c +++ b/src/precompile_utils.c @@ -61,7 +61,7 @@ static int _compile_all_tvar_union(jl_value_t *methsig) if (sig) { roots[0] = sig; if (jl_is_datatype(sig) && jl_has_concrete_subtype(sig)) - all = all && jl_compile_hint((jl_tupletype_t*)sig); + all = all && jl_compile_hint((jl_tupletype_t*)sig, 0); else all = 0; }