Skip to content

Commit 5405994

Browse files
authored
Add a @compile directive to disable interpreter (#42128)
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.
1 parent f6b38a6 commit 5405994

File tree

3 files changed

+20
-9
lines changed

3 files changed

+20
-9
lines changed

base/expr.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,13 @@ macro propagate_inbounds(ex)
374374
esc(ex)
375375
end
376376

377+
"""
378+
@compile
379+
380+
Force compilation of the block or function (Julia's built-in interpreter is blocked from executing it).
381+
"""
382+
macro compile() Expr(:meta, :compile) end
383+
377384
"""
378385
@polly
379386

base/timing.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ julia> @time begin
203203
"""
204204
macro time(ex)
205205
quote
206-
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
206+
@compile
207207
local stats = gc_num()
208208
local elapsedtime = time_ns()
209209
local compile_elapsedtime = cumulative_compile_time_ns_before()
@@ -249,7 +249,7 @@ pool allocs: 1
249249
"""
250250
macro timev(ex)
251251
quote
252-
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
252+
@compile
253253
local stats = gc_num()
254254
local elapsedtime = time_ns()
255255
local compile_elapsedtime = cumulative_compile_time_ns_before()
@@ -282,7 +282,7 @@ julia> @elapsed sleep(0.3)
282282
"""
283283
macro elapsed(ex)
284284
quote
285-
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
285+
@compile
286286
local t0 = time_ns()
287287
$(esc(ex))
288288
(time_ns() - t0) / 1e9
@@ -314,7 +314,7 @@ julia> @allocated rand(10^6)
314314
"""
315315
macro allocated(ex)
316316
quote
317-
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
317+
@compile
318318
local b0 = Ref{Int64}(0)
319319
local b1 = Ref{Int64}(0)
320320
gc_bytes(b0)
@@ -362,7 +362,7 @@ julia> stats.gcstats.total_time
362362
"""
363363
macro timed(ex)
364364
quote
365-
while false; end # compiler heuristic: compile this block (alter this if the heuristic changes)
365+
@compile
366366
local stats = gc_num()
367367
local elapsedtime = time_ns()
368368
local val = $(esc(ex))

src/toplevel.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ int jl_code_requires_compiler(jl_code_info_t *src)
378378
assert(jl_typeis(body, jl_array_any_type));
379379
size_t i;
380380
int has_intrinsics = 0, has_defs = 0, has_opaque = 0;
381+
if (jl_has_meta(body, compile_sym))
382+
return 1;
381383
for(i=0; i < jl_array_len(body); i++) {
382384
jl_value_t *stmt = jl_array_ptr_ref(body,i);
383385
expr_attributes(stmt, &has_intrinsics, &has_defs, &has_opaque);
@@ -387,7 +389,7 @@ int jl_code_requires_compiler(jl_code_info_t *src)
387389
return 0;
388390
}
389391

390-
static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs, int *has_loops, int *has_opaque)
392+
static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs, int *has_loops, int *has_opaque, int *has_compile)
391393
{
392394
size_t i;
393395
*has_loops = 0;
@@ -405,6 +407,7 @@ static void body_attributes(jl_array_t *body, int *has_intrinsics, int *has_defs
405407
}
406408
expr_attributes(stmt, has_intrinsics, has_defs, has_opaque);
407409
}
410+
*has_compile = jl_has_meta(body, compile_sym);
408411
}
409412

410413
static jl_module_t *call_require(jl_module_t *mod, jl_sym_t *var) JL_GLOBALLY_ROOTED
@@ -848,19 +851,20 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int
848851
return (jl_value_t*)ex;
849852
}
850853

851-
int has_intrinsics = 0, has_defs = 0, has_loops = 0, has_opaque = 0;
854+
int has_intrinsics = 0, has_defs = 0, has_loops = 0, has_opaque = 0, has_compile = 0;
852855
assert(head == thunk_sym);
853856
thk = (jl_code_info_t*)jl_exprarg(ex, 0);
854857
assert(jl_is_code_info(thk));
855858
assert(jl_typeis(thk->code, jl_array_any_type));
856-
body_attributes((jl_array_t*)thk->code, &has_intrinsics, &has_defs, &has_loops, &has_opaque);
859+
body_attributes((jl_array_t*)thk->code, &has_intrinsics, &has_defs, &has_loops, &has_opaque, &has_compile);
857860

858861
jl_value_t *result;
859862
if (has_intrinsics || (!has_defs && fast && has_loops &&
860863
jl_options.compile_enabled != JL_OPTIONS_COMPILE_OFF &&
861864
jl_options.compile_enabled != JL_OPTIONS_COMPILE_MIN &&
862865
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_OFF &&
863-
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN)) {
866+
jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN) ||
867+
has_compile) {
864868
// use codegen
865869
mfunc = method_instance_for_thunk(thk, m);
866870
jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0);

0 commit comments

Comments
 (0)