Skip to content

Commit 4ed5bcd

Browse files
committed
track all backedges
1 parent b10ba43 commit 4ed5bcd

File tree

5 files changed

+37
-12
lines changed

5 files changed

+37
-12
lines changed

base/inference.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,12 @@ let _min_age = Symbol("min-age"), _max_age = Symbol("max-age")
14441444
global min_age(m::Method) = getfield(m, _min_age) % UInt
14451445
global max_age(m::Method) = getfield(m, _max_age) % UInt
14461446
end
1447+
function add_backedge(li::LambdaInfo, caller::LambdaInfo)
1448+
isdefined(caller, :def) || return # don't add backedges to toplevel exprs
1449+
isdefined(li, :backedges) || (li.backedges = []) # lazy-init the backedges array
1450+
in(caller, li.backedges) || push!(li.backedges, caller) # add a backedge from callee to caller
1451+
nothing
1452+
end
14471453
function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtree::Bool, optimize::Bool, cached::Bool, caller, world::UInt)
14481454
local code = nothing
14491455
local frame = nothing
@@ -1462,13 +1468,15 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14621468
elseif isa(code, LambdaInfo)
14631469
# something existing
14641470
if code.inferred && !(needtree && code.code === nothing)
1471+
isa(caller, InferenceState) && add_backedge(code, caller.linfo)
14651472
return (code, code.rettype, true)
14661473
end
14671474
else
14681475
# sometimes just a return type is stored here. if a full AST
14691476
# is not needed, we can return it.
14701477
typeassert(code, Type)
14711478
if !needtree
1479+
# XXX: isa(caller, InferenceState) && add_backedge(method, atypes, caller)
14721480
return (nothing, code, true)
14731481
end
14741482
code = nothing
@@ -1570,6 +1578,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
15701578
end
15711579
end
15721580
typeinf_loop(frame)
1581+
isa(caller, InferenceState) && add_backedge(linfo, caller.linfo)
15731582
ccall(:jl_typeinf_end, Void, ())
15741583
return (frame.linfo, widenconst(frame.bestguess), frame.inferred)
15751584
end
@@ -2553,6 +2562,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
25532562
if linfo === nothing || !inferred || !linfo.inlineable || (ast = linfo.code) === nothing
25542563
return invoke_NF()
25552564
end
2565+
add_backedge(linfo, enclosing)
25562566

25572567
na = linfo.nargs
25582568
# check for vararg function

src/alloc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_new_lambda_info_uninit(void)
399399
li->rettype = (jl_value_t*)jl_any_type;
400400
li->sparam_syms = jl_emptysvec;
401401
li->sparam_vals = jl_emptysvec;
402+
li->backedges = NULL;
402403
li->fptr = NULL;
403404
li->jlcall_api = 0;
404405
li->compile_traced = 0;

src/dump.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ static void jl_update_all_fptrs(void)
431431
jl_lambda_info_t **linfos = (jl_lambda_info_t**)malloc(sizeof(jl_lambda_info_t*) * sysimg_fvars_max);
432432
for (i = 0; i < delayed_fptrs_n; i++) {
433433
jl_lambda_info_t *li = delayed_fptrs[i].li;
434+
if (li->def == NULL) continue;
434435
int32_t func = delayed_fptrs[i].func - 1;
435436
if (func >= 0) {
436437
jl_fptr_to_llvm((jl_fptr_t)fvars[func], li, 0);
@@ -893,17 +894,20 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v)
893894
jl_serialize_value(s, (jl_value_t*)li->sparam_syms);
894895
jl_serialize_value(s, (jl_value_t*)li->sparam_vals);
895896
jl_serialize_value(s, (jl_value_t*)li->specTypes);
897+
jl_serialize_value(s, (jl_value_t*)li->backedges);
896898
write_int8(s->s, li->inferred);
897899
write_int8(s->s, li->pure);
898900
write_int8(s->s, li->inlineable);
899901
write_int8(s->s, li->isva);
900902
write_int32(s->s, li->nargs);
901903
jl_serialize_value(s, (jl_value_t*)li->def);
902904
jl_serialize_value(s, li->constval);
903-
jl_serialize_fptr(s, (void*)(uintptr_t)li->fptr);
904905
// save functionObject pointers
905-
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.functionObject));
906-
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.specFunctionObject));
906+
if (li->def) {
907+
jl_serialize_fptr(s, (void*)(uintptr_t)li->fptr);
908+
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.functionObject));
909+
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.specFunctionObject));
910+
}
907911
write_int8(s->s, li->jlcall_api);
908912
}
909913
else if (jl_typeis(v, jl_module_type)) {
@@ -1512,6 +1516,8 @@ static jl_value_t *jl_deserialize_value_(jl_serializer_state *s, jl_value_t *vta
15121516
jl_gc_wb(li, li->sparam_vals);
15131517
li->specTypes = (jl_tupletype_t*)jl_deserialize_value(s, (jl_value_t**)&li->specTypes);
15141518
if (li->specTypes) jl_gc_wb(li, li->specTypes);
1519+
li->backedges = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&li->backedges);
1520+
if (li->backedges) jl_gc_wb(li, li->backedges);
15151521
li->unspecialized_ducttape = NULL;
15161522
li->inferred = read_int8(s->s);
15171523
li->pure = read_int8(s->s);
@@ -1527,11 +1533,16 @@ static jl_value_t *jl_deserialize_value_(jl_serializer_state *s, jl_value_t *vta
15271533
li->functionObjectsDecls.specFunctionObject = NULL;
15281534
li->inInference = 0;
15291535
li->inCompile = 0;
1530-
li->fptr = jl_deserialize_fptr(s);
1531-
int32_t cfunc_llvm, func_llvm;
1532-
func_llvm = read_int32(s->s);
1533-
cfunc_llvm = read_int32(s->s);
1534-
jl_delayed_fptrs(li, func_llvm, cfunc_llvm);
1536+
if (li->def) {
1537+
li->fptr = jl_deserialize_fptr(s);
1538+
int32_t cfunc_llvm, func_llvm;
1539+
func_llvm = read_int32(s->s);
1540+
cfunc_llvm = read_int32(s->s);
1541+
jl_delayed_fptrs(li, func_llvm, cfunc_llvm);
1542+
}
1543+
else {
1544+
li->fptr = NULL;
1545+
}
15351546
li->jlcall_api = read_int8(s->s);
15361547
li->compile_traced = 0;
15371548
return (jl_value_t*)li;

src/jltypes.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3880,7 +3880,7 @@ void jl_init_types(void)
38803880
jl_lambda_info_type =
38813881
jl_new_datatype(jl_symbol("LambdaInfo"),
38823882
jl_any_type, jl_emptysvec,
3883-
jl_svec(24,
3883+
jl_svec(25,
38843884
jl_symbol("rettype"),
38853885
jl_symbol("sparam_syms"),
38863886
jl_symbol("sparam_vals"),
@@ -3890,6 +3890,7 @@ void jl_init_types(void)
38903890
jl_symbol("ssavaluetypes"),
38913891
jl_symbol("slotnames"),
38923892
jl_symbol("slotflags"),
3893+
jl_symbol("backedges"),
38933894
jl_symbol("unspecialized_ducttape"),
38943895
jl_symbol("def"),
38953896
jl_symbol("constval"),
@@ -3904,7 +3905,7 @@ void jl_init_types(void)
39043905
jl_symbol(""),
39053906
jl_symbol("fptr"),
39063907
jl_symbol(""), jl_symbol("")),
3907-
jl_svec(24,
3908+
jl_svec(25,
39083909
jl_any_type,
39093910
jl_simplevector_type,
39103911
jl_simplevector_type,
@@ -3914,6 +3915,7 @@ void jl_init_types(void)
39143915
jl_any_type,
39153916
jl_array_any_type,
39163917
jl_array_uint8_type,
3918+
jl_array_any_type,
39173919
jl_any_type,
39183920
jl_method_type,
39193921
jl_any_type,
@@ -3929,7 +3931,7 @@ void jl_init_types(void)
39293931
jl_any_type,
39303932
jl_any_type, jl_any_type),
39313933
0, 1, 7);
3932-
jl_svecset(jl_lambda_info_type->types, 9, jl_lambda_info_type);
3934+
jl_svecset(jl_lambda_info_type->types, 10, jl_lambda_info_type);
39333935
jl_svecset(jl_method_type->types, 10, jl_lambda_info_type);
39343936

39353937
jl_typector_type =
@@ -3991,9 +3993,9 @@ void jl_init_types(void)
39913993
jl_svecset(jl_methtable_type->types, 6, jl_int32_type); // DWORD
39923994
#endif
39933995
jl_svecset(jl_methtable_type->types, 7, jl_int32_type); // uint32_t
3994-
jl_svecset(jl_lambda_info_type->types, 21, jl_voidpointer_type);
39953996
jl_svecset(jl_lambda_info_type->types, 22, jl_voidpointer_type);
39963997
jl_svecset(jl_lambda_info_type->types, 23, jl_voidpointer_type);
3998+
jl_svecset(jl_lambda_info_type->types, 24, jl_voidpointer_type);
39973999

39984000
jl_compute_field_offsets(jl_datatype_type);
39994001
jl_compute_field_offsets(jl_typename_type);

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ typedef struct _jl_lambda_info_t {
254254
jl_value_t *ssavaluetypes; // types of ssa values
255255
jl_array_t *slotnames; // names of local variables
256256
jl_array_t *slotflags; // local var bit flags
257+
jl_array_t *backedges; // backedges
257258
struct _jl_lambda_info_t *unspecialized_ducttape; // if template can't be compiled due to intrinsics, an un-inferred executable copy may get stored here
258259
jl_method_t *def; // method this is specialized from, (null if this is a toplevel thunk)
259260
jl_value_t *constval; // value of the function if jlcall_api==2

0 commit comments

Comments
 (0)