Skip to content

Commit

Permalink
add edges metadata field to CodeInfo/CodeInstance, prepare for using
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Jun 23, 2024
1 parent 2bf4750 commit d0b35b0
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 23 deletions.
2 changes: 1 addition & 1 deletion base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter)
append!(s_edges, edges)
empty!(edges)
end
if me.src.edges !== nothing
if me.src.edges !== nothing && me.src.edges !== Core.svec()
append!(s_edges, me.src.edges::Vector)
end
# inspect whether our inference had a limited result accuracy,
Expand Down
2 changes: 1 addition & 1 deletion base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function copy(c::CodeInfo)
cnew.slottypes = copy(cnew.slottypes::Vector{Any})
end
cnew.ssaflags = copy(cnew.ssaflags)
cnew.edges = cnew.edges === nothing ? nothing : copy(cnew.edges::Vector)
cnew.edges = cnew.edges === nothing || cnew.edges === Core.svec() ? cnew.edges : copy(cnew.edges::Vector)
ssavaluetypes = cnew.ssavaluetypes
ssavaluetypes isa Vector{Any} && (cnew.ssavaluetypes = copy(ssavaluetypes))
return cnew
Expand Down
19 changes: 10 additions & 9 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ JL_DLLEXPORT jl_value_t *jl_call_in_typeinf_world(jl_value_t **args, int nargs)

JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred(
jl_method_instance_t *mi JL_PROPAGATES_ROOT, jl_value_t *rettype,
size_t min_world, size_t max_world, jl_debuginfo_t *edges)
size_t min_world, size_t max_world, jl_debuginfo_t *di /*jl_svec_t *edges*/)
{
jl_value_t *owner = jl_nothing; // TODO: owner should be arg
jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache);
Expand All @@ -489,21 +489,21 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred(
jl_atomic_load_relaxed(&codeinst->max_world) == max_world &&
jl_egal(codeinst->owner, owner) &&
jl_egal(codeinst->rettype, rettype)) {
if (edges == NULL)
if (di == NULL)
return codeinst;
jl_debuginfo_t *debuginfo = jl_atomic_load_relaxed(&codeinst->debuginfo);
if (edges == debuginfo)
if (di == debuginfo)
return codeinst;
if (debuginfo == NULL && jl_atomic_cmpswap_relaxed(&codeinst->debuginfo, &debuginfo, edges))
if (debuginfo == NULL && jl_atomic_cmpswap_relaxed(&codeinst->debuginfo, &debuginfo, di))
return codeinst;
if (debuginfo && jl_egal((jl_value_t*)debuginfo, (jl_value_t*)edges))
if (debuginfo && jl_egal((jl_value_t*)debuginfo, (jl_value_t*)di))
return codeinst;
}
codeinst = jl_atomic_load_relaxed(&codeinst->next);
}
codeinst = jl_new_codeinst(
mi, owner, rettype, (jl_value_t*)jl_any_type, NULL, NULL,
0, min_world, max_world, 0, jl_nothing, 0, edges);
0, min_world, max_world, 0, jl_nothing, 0, di);
jl_mi_cache_insert(mi, codeinst);
return codeinst;
}
Expand All @@ -527,14 +527,15 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst(
int32_t const_flags, size_t min_world, size_t max_world,
uint32_t effects, jl_value_t *analysis_results,
uint8_t relocatability,
jl_debuginfo_t *edges /* , int absolute_max*/)
jl_debuginfo_t *di /*, jl_svec_t *edges, int absolute_max*/)
{
jl_task_t *ct = jl_current_task;
assert(min_world <= max_world && "attempting to set invalid world constraints");
jl_code_instance_t *codeinst = (jl_code_instance_t*)jl_gc_alloc(ct->ptls, sizeof(jl_code_instance_t),
jl_code_instance_type);
codeinst->def = mi;
codeinst->owner = owner;
codeinst->edges = jl_emptysvec;
jl_atomic_store_relaxed(&codeinst->min_world, min_world);
jl_atomic_store_relaxed(&codeinst->max_world, max_world);
codeinst->rettype = rettype;
Expand All @@ -543,7 +544,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst(
if ((const_flags & 2) == 0)
inferred_const = NULL;
codeinst->rettype_const = inferred_const;
jl_atomic_store_relaxed(&codeinst->debuginfo, (jl_value_t*)edges == jl_nothing ? NULL : edges);
jl_atomic_store_relaxed(&codeinst->debuginfo, (jl_value_t*)di == jl_nothing ? NULL : di);
jl_atomic_store_relaxed(&codeinst->specptr.fptr, NULL);
jl_atomic_store_relaxed(&codeinst->invoke, NULL);
if ((const_flags & 1) != 0) {
Expand Down Expand Up @@ -615,7 +616,7 @@ JL_DLLEXPORT void jl_fill_codeinst(

JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_uninit(jl_method_instance_t *mi, jl_value_t *owner)
{
jl_code_instance_t *codeinst = jl_new_codeinst(mi, owner, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0, NULL);
jl_code_instance_t *codeinst = jl_new_codeinst(mi, owner, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL);
jl_atomic_store_relaxed(&codeinst->min_world, 1); // make temporarily invalid before returning, so that jl_fill_codeinst is valid later
return codeinst;
}
Expand Down
2 changes: 2 additions & 0 deletions src/ircode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,8 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t
jl_gc_wb(code, code->rettype);
code->min_world = jl_atomic_load_relaxed(&metadata->min_world);
code->max_world = jl_atomic_load_relaxed(&metadata->max_world);
code->edges = (jl_value_t*)metadata->edges;
jl_gc_wb(code, code->edges);
}

return code;
Expand Down
14 changes: 8 additions & 6 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -3467,7 +3467,7 @@ void jl_init_types(void) JL_GC_DISABLED
jl_code_instance_type =
jl_new_datatype(jl_symbol("CodeInstance"), core,
jl_any_type, jl_emptysvec,
jl_perm_symsvec(17,
jl_perm_symsvec(18,
"def",
"owner",
"next",
Expand All @@ -3477,13 +3477,14 @@ void jl_init_types(void) JL_GC_DISABLED
"exctype",
"rettype_const",
"inferred",
"debuginfo", // TODO: rename to edges?
"debuginfo",
"edges",
//"absolute_max",
"ipo_purity_bits",
"analysis_results",
"specsigflags", "precompile", "relocatability",
"invoke", "specptr"), // function object decls
jl_svec(17,
jl_svec(18,
jl_method_instance_type,
jl_any_type,
jl_any_type,
Expand All @@ -3494,6 +3495,7 @@ void jl_init_types(void) JL_GC_DISABLED
jl_any_type,
jl_any_type,
jl_debuginfo_type,
jl_simplevector_type,
//jl_bool_type,
jl_uint32_type,
jl_any_type,
Expand All @@ -3504,8 +3506,8 @@ void jl_init_types(void) JL_GC_DISABLED
jl_emptysvec,
0, 1, 1);
jl_svecset(jl_code_instance_type->types, 2, jl_code_instance_type);
const static uint32_t code_instance_constfields[1] = { 0b00000100011100011 }; // Set fields 1, 2, 6-8, 12 as const
const static uint32_t code_instance_atomicfields[1] = { 0b11011011100011100 }; // Set fields 3-5, 9, 10, 11, 13-14, 16-17 as atomic
const static uint32_t code_instance_constfields[1] = { 0b000001000011100011 }; // Set fields 1, 2, 6-8, 13 as const
const static uint32_t code_instance_atomicfields[1] = { 0b110110111100011100 }; // Set fields 3-5, 9-12, 14-15, 17-18 as atomic
// Fields 4-5 are only operated on by construction and deserialization, so are effectively const at runtime
// Fields ipo_purity_bits and analysis_results are not currently threadsafe or reliable, as they get mutated after optimization, but are not declared atomic
// and there is no way to tell (during inference) if their value is finalized yet (to wait for them to be narrowed if applicable)
Expand Down Expand Up @@ -3649,8 +3651,8 @@ void jl_init_types(void) JL_GC_DISABLED
jl_svecset(jl_method_type->types, 13, jl_method_instance_type);
//jl_svecset(jl_debuginfo_type->types, 0, jl_method_instance_type); // union(jl_method_instance_type, jl_method_type, jl_symbol_type)
jl_svecset(jl_method_instance_type->types, 4, jl_code_instance_type);
jl_svecset(jl_code_instance_type->types, 15, jl_voidpointer_type);
jl_svecset(jl_code_instance_type->types, 16, jl_voidpointer_type);
jl_svecset(jl_code_instance_type->types, 17, jl_voidpointer_type);
jl_svecset(jl_binding_type->types, 1, jl_globalref_type);
jl_svecset(jl_binding_type->types, 2, jl_binding_type);

Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ typedef struct _jl_code_instance_t {
// - null, indicating that inference was not yet completed or did not succeed
_Atomic(jl_value_t *) inferred;
_Atomic(jl_debuginfo_t *) debuginfo; // stored information about edges from this object (set once, with a happens-before both source and invoke)
jl_svec_t *edges; // forward edge info
//TODO: uint8_t absolute_max; // whether true max world is unknown

// purity results
Expand Down
22 changes: 16 additions & 6 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,10 +648,10 @@ JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void)
src->slotnames = NULL;
src->slottypes = jl_nothing;
src->rettype = (jl_value_t*)jl_any_type;
src->edges = (jl_value_t*)jl_emptysvec;
src->parent = (jl_method_instance_t*)jl_nothing;
src->min_world = 1;
src->max_world = ~(size_t)0;
src->edges = jl_nothing;
src->propagate_inbounds = 0;
src->has_fcall = 0;
src->nospecializeinfer = 0;
Expand Down Expand Up @@ -827,15 +827,25 @@ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *mi, size_t

if (uninferred->edges != jl_nothing) {
// N.B.: This needs to match `store_backedges` on the julia side
jl_array_t *edges = (jl_array_t*)uninferred->edges;
for (size_t i = 0; i < jl_array_len(edges); ++i) {
jl_value_t *kind = jl_array_ptr_ref(edges, i);
jl_value_t *edges = uninferred->edges;
size_t l;
jl_value_t **data;
if (jl_is_svec(edges)) {
l = jl_svec_len(edges);
data = jl_svec_data(edges);
}
else {
l = jl_array_dim0(edges);
data = jl_array_data(edges, jl_value_t*);
}
for (size_t i = 0; i < l; ++i) {
jl_value_t *kind = data[i];
if (jl_is_method_instance(kind)) {
jl_method_instance_add_backedge((jl_method_instance_t*)kind, jl_nothing, mi);
} else if (jl_is_mtable(kind)) {
jl_method_table_add_backedge((jl_methtable_t*)kind, jl_array_ptr_ref(edges, ++i), (jl_value_t*)mi);
jl_method_table_add_backedge((jl_methtable_t*)kind, data[++i], (jl_value_t*)mi);
} else {
jl_method_instance_add_backedge((jl_method_instance_t*)jl_array_ptr_ref(edges, ++i), kind, mi);
jl_method_instance_add_backedge((jl_method_instance_t*)data[++i], kind, mi);
}
}
}
Expand Down

0 comments on commit d0b35b0

Please sign in to comment.