Skip to content

Commit 7ecc4f6

Browse files
committed
Add _predeclare_call built-in
1 parent c6d5570 commit 7ecc4f6

File tree

5 files changed

+50
-10
lines changed

5 files changed

+50
-10
lines changed

Compiler/src/typeinfer.jl

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,21 +1324,32 @@ function collectinvokes!(workqueue::CompilationQueue, ci::CodeInfo, sptypes::Vec
13241324
invokelatest_queue === nothing && continue
13251325
if isexpr(stmt, :call)
13261326
farg = stmt.args[1]
1327+
1328+
invokelatest_queue === nothing && continue
13271329
!applicable(argextype, farg, ci, sptypes) && continue # TODO: Why is this failing during bootstrap
1330+
13281331
ftyp = widenconst(argextype(farg, ci, sptypes))
13291332

13301333
if ftyp === typeof(Core.finalizer) && length(stmt.args) == 3
1331-
finalizer = argextype(stmt.args[2], ci, sptypes)
1332-
obj = argextype(stmt.args[3], ci, sptypes)
1333-
atype = argtypes_to_type(Any[finalizer, obj])
1334+
finalizer_fn = argextype(stmt.args[2], ci, sptypes)
1335+
object = argextype(stmt.args[3], ci, sptypes)
1336+
atype = argtypes_to_type(Any[finalizer_fn, object])
1337+
elseif ftyp === typeof(Core._predeclare_call) && length(stmt.args) > 1
1338+
atype = argtypes_to_type(Any[
1339+
argextype(stmt.args[i], ci, sptypes)
1340+
for i in 2:length(stmt.args)
1341+
])
1342+
else
1343+
# No dynamic dispatch to resolve / enqueue
1344+
continue
1345+
end
13341346

1335-
let workqueue = invokelatest_queue
1336-
# make a best-effort attempt to enqueue the relevant code for the finalizer
1337-
mi = compileable_specialization_for_call(workqueue.interp, atype)
1338-
mi === nothing && continue
1347+
let workqueue = invokelatest_queue
1348+
# make a best-effort attempt to enqueue the relevant code for the finalizer
1349+
mi = compileable_specialization_for_call(workqueue.interp, atype)
1350+
mi === nothing && continue
13391351

1340-
push!(workqueue, mi)
1341-
end
1352+
push!(workqueue, mi)
13421353
end
13431354
end
13441355
# TODO: handle other StmtInfo like @cfunction and OpaqueClosure?

Compiler/src/verifytrim.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ function may_dispatch(@nospecialize ftyp)
154154
return Core._apply isa ftyp ||
155155
Core._apply_iterate isa ftyp ||
156156
Core._call_in_world_total isa ftyp ||
157+
Core._predeclare_call isa ftyp ||
157158
Core.invoke isa ftyp ||
158159
Core.invoke_in_world isa ftyp ||
159160
Core.invokelatest isa ftyp ||
@@ -233,6 +234,21 @@ function verify_codeinstance!(codeinst::CodeInstance, codeinfo::CodeInfo, inspec
233234

234235
error = "unresolved finalizer registered"
235236
end
237+
elseif Core._predeclare_call isa ftyp
238+
if length(stmt.args) > 1
239+
atype = argtypes_to_type(Any[
240+
argextype(stmt.args[i], codeinfo, sptypes)
241+
for i in 2:length(stmt.args)
242+
])
243+
244+
mi = compileable_specialization_for_call(interp, atype)
245+
if mi !== nothing
246+
ci = get(caches, mi, nothing)
247+
ci isa CodeInstance && continue
248+
end
249+
250+
error = "unresolved pre-declared call"
251+
end
236252
else
237253
error = "unresolved call to builtin"
238254
end

src/builtin_proto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ DECLARE_BUILTIN(_call_in_world_total);
2727
DECLARE_BUILTIN(invokelatest);
2828
DECLARE_BUILTIN(_compute_sparams);
2929
DECLARE_BUILTIN(_expr);
30+
DECLARE_BUILTIN(_predeclare_call);
3031
DECLARE_BUILTIN(_svec_ref);
3132
DECLARE_BUILTIN(_typebody);
3233
DECLARE_BUILTIN(_typevar);

src/builtins.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,17 @@ JL_CALLABLE(jl_f_invoke)
16241624
return jl_gf_invoke(argtypes, args[0], &args[2], nargs - 1);
16251625
}
16261626

1627+
JL_CALLABLE(jl_f__predeclare_call)
1628+
{
1629+
JL_NARGSV(_predeclare_call, 1);
1630+
1631+
// jl_datatype_t *tt = jl_inst_arg_tuple_type(args[0], &args[1], nargs, 1);
1632+
// JL_GC_PROMISE_ROOTED(tt); // it is a concrete type
1633+
// jl_compile_hint(tt)
1634+
1635+
return jl_nothing;
1636+
}
1637+
16271638
// Expr constructor for internal use ------------------------------------------
16281639

16291640
jl_expr_t *jl_exprn(jl_sym_t *head, size_t n)
@@ -2510,6 +2521,7 @@ void jl_init_primitives(void) JL_GC_DISABLED
25102521
add_builtin_func("invokelatest", jl_f_invokelatest);
25112522
add_builtin_func("invoke_in_world", jl_f_invoke_in_world);
25122523
add_builtin_func("_call_in_world_total", jl_f__call_in_world_total);
2524+
add_builtin_func("_predeclare_call", jl_f__predeclare_call);
25132525
add_builtin_func("_typevar", jl_f__typevar);
25142526
add_builtin_func("_structtype", jl_f__structtype);
25152527
add_builtin_func("_abstracttype", jl_f__abstracttype);

src/staticdata.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ static htable_t bits_replace;
522522
// This is a manually constructed dual of the fvars array, which would be produced by codegen for Julia code, for C.
523523
static const jl_fptr_args_t id_to_fptrs[] = {
524524
&jl_f_throw, &jl_f_throw_methoderror, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa,
525-
&jl_f_typeassert, &jl_f__apply_iterate,
525+
&jl_f_typeassert, &jl_f__apply_iterate, &jl_f__predeclare_call,
526526
&jl_f_invokelatest, &jl_f_invoke_in_world, &jl_f__call_in_world_total, &jl_f_isdefined, &jl_f_isdefinedglobal,
527527
&jl_f_tuple, &jl_f_svec, &jl_f_intrinsic_call,
528528
&jl_f_getfield, &jl_f_setfield, &jl_f_swapfield, &jl_f_modifyfield, &jl_f_setfieldonce,

0 commit comments

Comments
 (0)