Skip to content

Commit 46775af

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 7a308f1 commit 46775af

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
@@ -4178,6 +4178,20 @@ function expand_compiler_path(tup)
41784178
end
41794179
compiler_chi(tup::Tuple) = CacheHeaderIncludes(expand_compiler_path(tup))
41804180

4181+
"""
4182+
isprecompilable(f, argtypes::Tuple{Vararg{Any}})
4183+
4184+
Check, as far as is possible without actually compiling, if the given
4185+
function `f` can be compiled for the argument tuple (of types) `argtypes`.
4186+
"""
4187+
function isprecompilable(@nospecialize(f), @nospecialize(argtypes::Tuple))
4188+
isprecompilable(Tuple{Core.Typeof(f), argtypes...})
4189+
end
4190+
4191+
function isprecompilable(@nospecialize(argt::Type))
4192+
ccall(:jl_is_compilable, Int32, (Any,), argt) != 0
4193+
end
4194+
41814195
"""
41824196
precompile(f, argtypes::Tuple{Vararg{Any}})
41834197

src/gf.c

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

3892+
JL_DLLEXPORT int jl_is_compilable(jl_tupletype_t *types)
3893+
{
3894+
size_t world = jl_atomic_load_acquire(&jl_world_counter);
3895+
size_t min_valid = 0;
3896+
size_t max_valid = ~(size_t)0;
3897+
jl_method_instance_t *mi = jl_get_compile_hint_specialization(types, world, &min_valid, &max_valid, 1);
3898+
return mi == NULL ? 0 : 1;
3899+
}
3900+
38923901
JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types)
38933902
{
38943903
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)