Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force compilation with @force_compile #42379

Merged
merged 1 commit into from
Oct 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions base/experimental.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,29 @@ macro compiler_options(args...)
return opts
end

"""
Experimental.@force_compile

Force compilation of the block or function (Julia's built-in interpreter is blocked from executing it).

# Examples

```
module WithPrecompiles
#=
code definitions
=#

if Sys.iswindows()
Experimental.@compile
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it

Suggested change
Experimental.@compile
Experimental.@force_compile

here?

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iswindows check feels kind of artificial here as well?

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch both of you. See #42760

compile_me() # `compile_me` will be compiled before execution
end

end
```
"""
macro force_compile() Expr(:meta, :force_compile) end

# UI features for errors

"""
Expand Down
7 changes: 0 additions & 7 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,6 @@ macro propagate_inbounds(ex)
esc(ex)
end

"""
@compile

Force compilation of the block or function (Julia's built-in interpreter is blocked from executing it).
"""
macro compile() Expr(:meta, :compile) end

"""
@polly

Expand Down
10 changes: 5 additions & 5 deletions base/timing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ julia> @time begin
"""
macro time(ex)
quote
@compile
Experimental.@force_compile
local stats = gc_num()
local elapsedtime = time_ns()
local compile_elapsedtime = cumulative_compile_time_ns_before()
Expand Down Expand Up @@ -260,7 +260,7 @@ pool allocs: 1
"""
macro timev(ex)
quote
@compile
Experimental.@force_compile
local stats = gc_num()
local elapsedtime = time_ns()
local compile_elapsedtime = cumulative_compile_time_ns_before()
Expand Down Expand Up @@ -294,7 +294,7 @@ julia> @elapsed sleep(0.3)
"""
macro elapsed(ex)
quote
@compile
Experimental.@force_compile
local t0 = time_ns()
$(esc(ex))
(time_ns() - t0) / 1e9
Expand Down Expand Up @@ -326,7 +326,7 @@ julia> @allocated rand(10^6)
"""
macro allocated(ex)
quote
@compile
Experimental.@force_compile
local b0 = Ref{Int64}(0)
local b1 = Ref{Int64}(0)
gc_bytes(b0)
Expand Down Expand Up @@ -374,7 +374,7 @@ julia> stats.gcstats.total_time
"""
macro timed(ex)
quote
@compile
Experimental.@force_compile
local stats = gc_num()
local elapsedtime = time_ns()
local val = $(esc(ex))
Expand Down
2 changes: 2 additions & 0 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ JL_DLLEXPORT jl_sym_t *jl_atom_sym;
JL_DLLEXPORT jl_sym_t *jl_statement_sym;
JL_DLLEXPORT jl_sym_t *jl_all_sym;
JL_DLLEXPORT jl_sym_t *jl_compile_sym;
JL_DLLEXPORT jl_sym_t *jl_force_compile_sym;
JL_DLLEXPORT jl_sym_t *jl_infer_sym;
JL_DLLEXPORT jl_sym_t *jl_atomic_sym;
JL_DLLEXPORT jl_sym_t *jl_not_atomic_sym;
Expand Down Expand Up @@ -437,6 +438,7 @@ void jl_init_common_symbols(void)
jl_specialize_sym = jl_symbol("specialize");
jl_optlevel_sym = jl_symbol("optlevel");
jl_compile_sym = jl_symbol("compile");
jl_force_compile_sym = jl_symbol("force_compile");
jl_infer_sym = jl_symbol("infer");
jl_macrocall_sym = jl_symbol("macrocall");
jl_escape_sym = jl_symbol("escape");
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,7 @@ extern JL_DLLEXPORT jl_sym_t *jl_atom_sym;
extern JL_DLLEXPORT jl_sym_t *jl_statement_sym;
extern JL_DLLEXPORT jl_sym_t *jl_all_sym;
extern JL_DLLEXPORT jl_sym_t *jl_compile_sym;
extern JL_DLLEXPORT jl_sym_t *jl_force_compile_sym;
extern JL_DLLEXPORT jl_sym_t *jl_infer_sym;
extern JL_DLLEXPORT jl_sym_t *jl_atomic_sym;
extern JL_DLLEXPORT jl_sym_t *jl_not_atomic_sym;
Expand Down
22 changes: 11 additions & 11 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ int jl_code_requires_compiler(jl_code_info_t *src)
assert(jl_typeis(body, jl_array_any_type));
size_t i;
int has_intrinsics = 0, has_defs = 0, has_opaque = 0;
if (jl_has_meta(body, jl_compile_sym))
if (jl_has_meta(body, jl_force_compile_sym))
return 1;
for(i=0; i < jl_array_len(body); i++) {
jl_value_t *stmt = jl_array_ptr_ref(body,i);
Expand All @@ -389,7 +389,7 @@ int jl_code_requires_compiler(jl_code_info_t *src)
return 0;
}

static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs, int *has_loops, int *has_opaque, int *has_compile)
static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs, int *has_loops, int *has_opaque, int *forced_compile)
{
size_t i;
*has_loops = 0;
Expand All @@ -407,7 +407,7 @@ static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs
}
expr_attributes(stmt, has_intrinsics, has_defs, has_opaque);
}
*has_compile = jl_has_meta(body, jl_compile_sym);
*forced_compile = jl_has_meta(body, jl_force_compile_sym);
}

static jl_module_t *call_require(jl_module_t *mod, jl_sym_t *var) JL_GLOBALLY_ROOTED
Expand Down Expand Up @@ -851,20 +851,20 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int
return (jl_value_t*)ex;
}

int has_intrinsics = 0, has_defs = 0, has_loops = 0, has_opaque = 0, has_compile = 0;
int has_intrinsics = 0, has_defs = 0, has_loops = 0, has_opaque = 0, forced_compile = 0;
assert(head == jl_thunk_sym);
thk = (jl_code_info_t*)jl_exprarg(ex, 0);
assert(jl_is_code_info(thk));
assert(jl_typeis(thk->code, jl_array_any_type));
body_attributes((jl_array_t*)thk->code, &has_intrinsics, &has_defs, &has_loops, &has_opaque, &has_compile);
body_attributes((jl_array_t*)thk->code, &has_intrinsics, &has_defs, &has_loops, &has_opaque, &forced_compile);

jl_value_t *result;
if (has_intrinsics || (!has_defs && fast && has_loops &&
jl_options.compile_enabled != JL_OPTIONS_COMPILE_OFF &&
jl_options.compile_enabled != JL_OPTIONS_COMPILE_MIN &&
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_OFF &&
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN) ||
has_compile) {
if (forced_compile || has_intrinsics ||
(!has_defs && fast && has_loops &&
jl_options.compile_enabled != JL_OPTIONS_COMPILE_OFF &&
jl_options.compile_enabled != JL_OPTIONS_COMPILE_MIN &&
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_OFF &&
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN)) {
// use codegen
mfunc = method_instance_for_thunk(thk, m);
jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);
Expand Down