Skip to content

Commit 855b846

Browse files
committed
track all backedges
1 parent 1f56e1d commit 855b846

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
@@ -1446,6 +1446,12 @@ let _min_age = Symbol("min-age"), _max_age = Symbol("max-age")
14461446
global min_age(m::Method) = getfield(m, _min_age) % UInt
14471447
global max_age(m::Method) = getfield(m, _max_age) % UInt
14481448
end
1449+
function add_backedge(li::LambdaInfo, caller::LambdaInfo)
1450+
isdefined(caller, :def) || return # don't add backedges to toplevel exprs
1451+
isdefined(li, :backedges) || (li.backedges = []) # lazy-init the backedges array
1452+
in(caller, li.backedges) || push!(li.backedges, caller) # add a backedge from callee to caller
1453+
nothing
1454+
end
14491455
function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtree::Bool, optimize::Bool, cached::Bool, caller, world::UInt)
14501456
local code = nothing
14511457
local frame = nothing
@@ -1464,13 +1470,15 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14641470
elseif isa(code, LambdaInfo)
14651471
# something existing
14661472
if code.inferred && !(needtree && code.code === nothing)
1473+
isa(caller, InferenceState) && add_backedge(code, caller.linfo)
14671474
return (code, code.rettype, true)
14681475
end
14691476
else
14701477
# sometimes just a return type is stored here. if a full AST
14711478
# is not needed, we can return it.
14721479
typeassert(code, Type)
14731480
if !needtree
1481+
# XXX: isa(caller, InferenceState) && add_backedge(method, atypes, caller)
14741482
return (nothing, code, true)
14751483
end
14761484
code = nothing
@@ -1576,6 +1584,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
15761584
end
15771585
end
15781586
typeinf_loop(frame)
1587+
isa(caller, InferenceState) && add_backedge(linfo, caller.linfo)
15791588
ccall(:jl_typeinf_end, Void, ())
15801589
return (frame.linfo, widenconst(frame.bestguess), frame.inferred)
15811590
end
@@ -2548,6 +2557,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
25482557
if linfo === nothing || !inferred || !linfo.inlineable || (ast = linfo.code) === nothing
25492558
return invoke_NF()
25502559
end
2560+
add_backedge(linfo, enclosing)
25512561

25522562
na = linfo.nargs
25532563
# check for vararg function

src/alloc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_new_lambda_info_uninit(void)
417417
li->rettype = (jl_value_t*)jl_any_type;
418418
li->sparam_syms = jl_emptysvec;
419419
li->sparam_vals = jl_emptysvec;
420+
li->backedges = NULL;
420421
li->fptr = NULL;
421422
li->jlcall_api = 0;
422423
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
@@ -3890,7 +3890,7 @@ void jl_init_types(void)
38903890
jl_lambda_info_type =
38913891
jl_new_datatype(jl_symbol("LambdaInfo"),
38923892
jl_any_type, jl_emptysvec,
3893-
jl_svec(24,
3893+
jl_svec(25,
38943894
jl_symbol("rettype"),
38953895
jl_symbol("sparam_syms"),
38963896
jl_symbol("sparam_vals"),
@@ -3900,6 +3900,7 @@ void jl_init_types(void)
39003900
jl_symbol("ssavaluetypes"),
39013901
jl_symbol("slotnames"),
39023902
jl_symbol("slotflags"),
3903+
jl_symbol("backedges"),
39033904
jl_symbol("unspecialized_ducttape"),
39043905
jl_symbol("def"),
39053906
jl_symbol("constval"),
@@ -3914,7 +3915,7 @@ void jl_init_types(void)
39143915
jl_symbol(""),
39153916
jl_symbol("fptr"),
39163917
jl_symbol(""), jl_symbol("")),
3917-
jl_svec(24,
3918+
jl_svec(25,
39183919
jl_any_type,
39193920
jl_simplevector_type,
39203921
jl_simplevector_type,
@@ -3924,6 +3925,7 @@ void jl_init_types(void)
39243925
jl_any_type,
39253926
jl_array_any_type,
39263927
jl_array_uint8_type,
3928+
jl_array_any_type,
39273929
jl_any_type,
39283930
jl_method_type,
39293931
jl_any_type,
@@ -3939,7 +3941,7 @@ void jl_init_types(void)
39393941
jl_any_type,
39403942
jl_any_type, jl_any_type),
39413943
0, 1, 7);
3942-
jl_svecset(jl_lambda_info_type->types, 9, jl_lambda_info_type);
3944+
jl_svecset(jl_lambda_info_type->types, 10, jl_lambda_info_type);
39433945
jl_svecset(jl_method_type->types, 10, jl_lambda_info_type);
39443946

39453947
jl_typector_type =
@@ -4001,9 +4003,9 @@ void jl_init_types(void)
40014003
jl_svecset(jl_methtable_type->types, 6, jl_int32_type); // DWORD
40024004
#endif
40034005
jl_svecset(jl_methtable_type->types, 7, jl_int32_type); // uint32_t
4004-
jl_svecset(jl_lambda_info_type->types, 21, jl_voidpointer_type);
40054006
jl_svecset(jl_lambda_info_type->types, 22, jl_voidpointer_type);
40064007
jl_svecset(jl_lambda_info_type->types, 23, jl_voidpointer_type);
4008+
jl_svecset(jl_lambda_info_type->types, 24, jl_voidpointer_type);
40074009

40084010
jl_compute_field_offsets(jl_datatype_type);
40094011
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)