Skip to content

Commit 344c302

Browse files
kpamnanyRAI CI (GitHub Action Automation)
authored andcommitted
Add Base.isprecompilable (JuliaLang#58805)
Alternative to JuliaLang#58146. We want to compile a subset of the possible specializations of a function. To this end, we have a number of manually written `precompile` statements. Creating this list is, unfortunately, error-prone, and the list is also liable to going stale. Thus we'd like to validate each `precompile` statement in the list. The simple answer is, of course, to actually run the `precompile`s, and we naturally do so, but this takes time. We would like a relatively quick way to check the validity of a `precompile` statement. This is a dev-loop optimization, to allow us to check "is-precompilable" in unit tests. We can't use `hasmethod` as it has both false positives (too loose): ```julia julia> hasmethod(sum, (AbstractVector,)) true julia> precompile(sum, (AbstractVector,)) false julia> Base.isprecompilable(sum, (AbstractVector,)) # <- this PR false ``` and also false negatives (too strict): ```julia julia> bar(@nospecialize(x::AbstractVector{Int})) = 42 bar (generic function with 1 method) julia> hasmethod(bar, (AbstractVector,)) false julia> precompile(bar, (AbstractVector,)) true julia> Base.isprecompilable(bar, (AbstractVector,)) # <- this PR true ``` We can't use `hasmethod && isconcretetype` as it has false negatives (too strict): ```julia julia> has_concrete_method(f, argtypes) = all(isconcretetype, argtypes) && hasmethod(f, argtypes) has_concrete_method (generic function with 1 method) julia> has_concrete_method(bar, (AbstractVector,)) false julia> has_concrete_method(convert, (Type{Int}, Int32)) false julia> precompile(convert, (Type{Int}, Int32)) true julia> Base.isprecompilable(convert, (Type{Int}, Int32)) # <- this PR true ``` `Base.isprecompilable` is essentially `precompile` without the actual compilation.
1 parent 7bf549d commit 344c302

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

base/loading.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4184,6 +4184,20 @@ function expand_compiler_path(tup)
41844184
end
41854185
compiler_chi(tup::Tuple) = CacheHeaderIncludes(expand_compiler_path(tup))
41864186

4187+
"""
4188+
isprecompilable(f, argtypes::Tuple{Vararg{Any}})
4189+
4190+
Check, as far as is possible without actually compiling, if the given
4191+
function `f` can be compiled for the argument tuple (of types) `argtypes`.
4192+
"""
4193+
function isprecompilable(@nospecialize(f), @nospecialize(argtypes::Tuple))
4194+
isprecompilable(Tuple{Core.Typeof(f), argtypes...})
4195+
end
4196+
4197+
function isprecompilable(@nospecialize(argt::Type))
4198+
ccall(:jl_is_compilable, Int32, (Any,), argt) != 0
4199+
end
4200+
41874201
"""
41884202
precompile(f, argtypes::Tuple{Vararg{Any}})
41894203

src/gf.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3886,6 +3886,15 @@ JL_DLLEXPORT void jl_compile_method_sig(jl_method_t *m, jl_value_t *types, jl_sv
38863886
jl_compile_method_instance(mi, NULL, world);
38873887
}
38883888

3889+
JL_DLLEXPORT int jl_is_compilable(jl_tupletype_t *types)
3890+
{
3891+
size_t world = jl_atomic_load_acquire(&jl_world_counter);
3892+
size_t min_valid = 0;
3893+
size_t max_valid = ~(size_t)0;
3894+
jl_method_instance_t *mi = jl_get_compile_hint_specialization(types, world, &min_valid, &max_valid, 1);
3895+
return mi == NULL ? 0 : 1;
3896+
}
3897+
38893898
JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types)
38903899
{
38913900
size_t world = jl_atomic_load_acquire(&jl_world_counter);

src/jl_exported_funcs.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@
271271
XX(jl_istopmod) \
272272
XX(jl_is_binding_deprecated) \
273273
XX(jl_is_char_signed) \
274+
XX(jl_is_compilable) \
274275
XX(jl_is_const) \
275276
XX(jl_is_assertsbuild) \
276277
XX(jl_is_debugbuild) \

0 commit comments

Comments
 (0)