Skip to content

Commit

Permalink
track all backedges
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Aug 23, 2016
1 parent 1f56e1d commit 855b846
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
10 changes: 10 additions & 0 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,12 @@ let _min_age = Symbol("min-age"), _max_age = Symbol("max-age")
global min_age(m::Method) = getfield(m, _min_age) % UInt
global max_age(m::Method) = getfield(m, _max_age) % UInt
end
function add_backedge(li::LambdaInfo, caller::LambdaInfo)
isdefined(caller, :def) || return # don't add backedges to toplevel exprs
isdefined(li, :backedges) || (li.backedges = []) # lazy-init the backedges array
in(caller, li.backedges) || push!(li.backedges, caller) # add a backedge from callee to caller
nothing
end
function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtree::Bool, optimize::Bool, cached::Bool, caller, world::UInt)
local code = nothing
local frame = nothing
Expand All @@ -1464,13 +1470,15 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
elseif isa(code, LambdaInfo)
# something existing
if code.inferred && !(needtree && code.code === nothing)
isa(caller, InferenceState) && add_backedge(code, caller.linfo)
return (code, code.rettype, true)
end
else
# sometimes just a return type is stored here. if a full AST
# is not needed, we can return it.
typeassert(code, Type)
if !needtree
# XXX: isa(caller, InferenceState) && add_backedge(method, atypes, caller)
return (nothing, code, true)
end
code = nothing
Expand Down Expand Up @@ -1576,6 +1584,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
end
end
typeinf_loop(frame)
isa(caller, InferenceState) && add_backedge(linfo, caller.linfo)
ccall(:jl_typeinf_end, Void, ())
return (frame.linfo, widenconst(frame.bestguess), frame.inferred)
end
Expand Down Expand Up @@ -2548,6 +2557,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
if linfo === nothing || !inferred || !linfo.inlineable || (ast = linfo.code) === nothing
return invoke_NF()
end
add_backedge(linfo, enclosing)

na = linfo.nargs
# check for vararg function
Expand Down
1 change: 1 addition & 0 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_new_lambda_info_uninit(void)
li->rettype = (jl_value_t*)jl_any_type;
li->sparam_syms = jl_emptysvec;
li->sparam_vals = jl_emptysvec;
li->backedges = NULL;
li->fptr = NULL;
li->jlcall_api = 0;
li->compile_traced = 0;
Expand Down
27 changes: 19 additions & 8 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ static void jl_update_all_fptrs(void)
jl_lambda_info_t **linfos = (jl_lambda_info_t**)malloc(sizeof(jl_lambda_info_t*) * sysimg_fvars_max);
for (i = 0; i < delayed_fptrs_n; i++) {
jl_lambda_info_t *li = delayed_fptrs[i].li;
if (li->def == NULL) continue;
int32_t func = delayed_fptrs[i].func - 1;
if (func >= 0) {
jl_fptr_to_llvm((jl_fptr_t)fvars[func], li, 0);
Expand Down Expand Up @@ -893,17 +894,20 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v)
jl_serialize_value(s, (jl_value_t*)li->sparam_syms);
jl_serialize_value(s, (jl_value_t*)li->sparam_vals);
jl_serialize_value(s, (jl_value_t*)li->specTypes);
jl_serialize_value(s, (jl_value_t*)li->backedges);
write_int8(s->s, li->inferred);
write_int8(s->s, li->pure);
write_int8(s->s, li->inlineable);
write_int8(s->s, li->isva);
write_int32(s->s, li->nargs);
jl_serialize_value(s, (jl_value_t*)li->def);
jl_serialize_value(s, li->constval);
jl_serialize_fptr(s, (void*)(uintptr_t)li->fptr);
// save functionObject pointers
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.functionObject));
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.specFunctionObject));
if (li->def) {
jl_serialize_fptr(s, (void*)(uintptr_t)li->fptr);
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.functionObject));
write_int32(s->s, jl_assign_functionID(li->functionObjectsDecls.specFunctionObject));
}
write_int8(s->s, li->jlcall_api);
}
else if (jl_typeis(v, jl_module_type)) {
Expand Down Expand Up @@ -1512,6 +1516,8 @@ static jl_value_t *jl_deserialize_value_(jl_serializer_state *s, jl_value_t *vta
jl_gc_wb(li, li->sparam_vals);
li->specTypes = (jl_tupletype_t*)jl_deserialize_value(s, (jl_value_t**)&li->specTypes);
if (li->specTypes) jl_gc_wb(li, li->specTypes);
li->backedges = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&li->backedges);
if (li->backedges) jl_gc_wb(li, li->backedges);
li->unspecialized_ducttape = NULL;
li->inferred = read_int8(s->s);
li->pure = read_int8(s->s);
Expand All @@ -1527,11 +1533,16 @@ static jl_value_t *jl_deserialize_value_(jl_serializer_state *s, jl_value_t *vta
li->functionObjectsDecls.specFunctionObject = NULL;
li->inInference = 0;
li->inCompile = 0;
li->fptr = jl_deserialize_fptr(s);
int32_t cfunc_llvm, func_llvm;
func_llvm = read_int32(s->s);
cfunc_llvm = read_int32(s->s);
jl_delayed_fptrs(li, func_llvm, cfunc_llvm);
if (li->def) {
li->fptr = jl_deserialize_fptr(s);
int32_t cfunc_llvm, func_llvm;
func_llvm = read_int32(s->s);
cfunc_llvm = read_int32(s->s);
jl_delayed_fptrs(li, func_llvm, cfunc_llvm);
}
else {
li->fptr = NULL;
}
li->jlcall_api = read_int8(s->s);
li->compile_traced = 0;
return (jl_value_t*)li;
Expand Down
10 changes: 6 additions & 4 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -3890,7 +3890,7 @@ void jl_init_types(void)
jl_lambda_info_type =
jl_new_datatype(jl_symbol("LambdaInfo"),
jl_any_type, jl_emptysvec,
jl_svec(24,
jl_svec(25,
jl_symbol("rettype"),
jl_symbol("sparam_syms"),
jl_symbol("sparam_vals"),
Expand All @@ -3900,6 +3900,7 @@ void jl_init_types(void)
jl_symbol("ssavaluetypes"),
jl_symbol("slotnames"),
jl_symbol("slotflags"),
jl_symbol("backedges"),
jl_symbol("unspecialized_ducttape"),
jl_symbol("def"),
jl_symbol("constval"),
Expand All @@ -3914,7 +3915,7 @@ void jl_init_types(void)
jl_symbol(""),
jl_symbol("fptr"),
jl_symbol(""), jl_symbol("")),
jl_svec(24,
jl_svec(25,
jl_any_type,
jl_simplevector_type,
jl_simplevector_type,
Expand All @@ -3924,6 +3925,7 @@ void jl_init_types(void)
jl_any_type,
jl_array_any_type,
jl_array_uint8_type,
jl_array_any_type,
jl_any_type,
jl_method_type,
jl_any_type,
Expand All @@ -3939,7 +3941,7 @@ void jl_init_types(void)
jl_any_type,
jl_any_type, jl_any_type),
0, 1, 7);
jl_svecset(jl_lambda_info_type->types, 9, jl_lambda_info_type);
jl_svecset(jl_lambda_info_type->types, 10, jl_lambda_info_type);
jl_svecset(jl_method_type->types, 10, jl_lambda_info_type);

jl_typector_type =
Expand Down Expand Up @@ -4001,9 +4003,9 @@ void jl_init_types(void)
jl_svecset(jl_methtable_type->types, 6, jl_int32_type); // DWORD
#endif
jl_svecset(jl_methtable_type->types, 7, jl_int32_type); // uint32_t
jl_svecset(jl_lambda_info_type->types, 21, jl_voidpointer_type);
jl_svecset(jl_lambda_info_type->types, 22, jl_voidpointer_type);
jl_svecset(jl_lambda_info_type->types, 23, jl_voidpointer_type);
jl_svecset(jl_lambda_info_type->types, 24, jl_voidpointer_type);

jl_compute_field_offsets(jl_datatype_type);
jl_compute_field_offsets(jl_typename_type);
Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ typedef struct _jl_lambda_info_t {
jl_value_t *ssavaluetypes; // types of ssa values
jl_array_t *slotnames; // names of local variables
jl_array_t *slotflags; // local var bit flags
jl_array_t *backedges; // backedges
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
jl_method_t *def; // method this is specialized from, (null if this is a toplevel thunk)
jl_value_t *constval; // value of the function if jlcall_api==2
Expand Down

0 comments on commit 855b846

Please sign in to comment.