Skip to content

Commit

Permalink
Add a @compile directive to disable interpreter (#42128)
Browse files Browse the repository at this point in the history
We currently use a `while false; end` hack to disable to interpreter,
and this is getting more widely used outside of base. Unfortunately,
improvements to the interpreter that would allow us to interpret loops
would defeat the intention. This allows developers to annotate blocks
with `@compile` to specify that they want to force the compiler to run
on this block.
  • Loading branch information
timholy authored Sep 10, 2021
1 parent f6b38a6 commit 5405994
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
7 changes: 7 additions & 0 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,13 @@ 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 @@ -203,7 +203,7 @@ julia> @time begin
"""
macro time(ex)
quote
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
@compile
local stats = gc_num()
local elapsedtime = time_ns()
local compile_elapsedtime = cumulative_compile_time_ns_before()
Expand Down Expand Up @@ -249,7 +249,7 @@ pool allocs: 1
"""
macro timev(ex)
quote
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
@compile
local stats = gc_num()
local elapsedtime = time_ns()
local compile_elapsedtime = cumulative_compile_time_ns_before()
Expand Down Expand Up @@ -282,7 +282,7 @@ julia> @elapsed sleep(0.3)
"""
macro elapsed(ex)
quote
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
@compile
local t0 = time_ns()
$(esc(ex))
(time_ns() - t0) / 1e9
Expand Down Expand Up @@ -314,7 +314,7 @@ julia> @allocated rand(10^6)
"""
macro allocated(ex)
quote
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
@compile
local b0 = Ref{Int64}(0)
local b1 = Ref{Int64}(0)
gc_bytes(b0)
Expand Down Expand Up @@ -362,7 +362,7 @@ julia> stats.gcstats.total_time
"""
macro timed(ex)
quote
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
@compile
local stats = gc_num()
local elapsedtime = time_ns()
local val = $(esc(ex))
Expand Down
12 changes: 8 additions & 4 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ 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, compile_sym))
return 1;
for(i=0; i < jl_array_len(body); i++) {
jl_value_t *stmt = jl_array_ptr_ref(body,i);
expr_attributes(stmt, &has_intrinsics, &has_defs, &has_opaque);
Expand All @@ -387,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)
static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs, int *has_loops, int *has_opaque, int *has_compile)
{
size_t i;
*has_loops = 0;
Expand All @@ -405,6 +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, compile_sym);
}

static jl_module_t *call_require(jl_module_t *mod, jl_sym_t *var) JL_GLOBALLY_ROOTED
Expand Down Expand Up @@ -848,19 +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;
int has_intrinsics = 0, has_defs = 0, has_loops = 0, has_opaque = 0, has_compile = 0;
assert(head == 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);
body_attributes((jl_array_t*)thk->code, &has_intrinsics, &has_defs, &has_loops, &has_opaque, &has_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)) {
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN) ||
has_compile) {
// use codegen
mfunc = method_instance_for_thunk(thk, m);
jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);
Expand Down

0 comments on commit 5405994

Please sign in to comment.