Skip to content

Commit

Permalink
Defer code-compression until serialization
Browse files Browse the repository at this point in the history
During incremental compilation (aka, package precompilation),
wait to call `jl_compress_ir` until the moment of method
serialization. This increases the efficiency of potential
root-order transformations (e.g., #42016).  Aside from
possible memory constraints, there appears to be little downside
to waiting.
  • Loading branch information
timholy committed Jan 11, 2022
1 parent 13b3e77 commit 5589790
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
2 changes: 1 addition & 1 deletion base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ already_inferred_quick_test(interp::AbstractInterpreter, mi::MethodInstance) =
function maybe_compress_codeinfo(interp::AbstractInterpreter, linfo::MethodInstance, ci::CodeInfo)
def = linfo.def
toplevel = !isa(def, Method)
if toplevel
if toplevel || JLOptions().incremental != Int8(0) # defer compression until serialization
return ci
end
if may_discard_trees(interp)
Expand Down
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7574,7 +7574,7 @@ jl_compile_result_t jl_emit_codeinst(
jl_options.debug_level > 1) {
// update the stored code
if (codeinst->inferred != (jl_value_t*)src) {
if (jl_is_method(def))
if (jl_is_method(def) && !jl_options.incremental) // defer compression until serialization
src = (jl_code_info_t*)jl_compress_ir(def, src);
codeinst->inferred = (jl_value_t*)src;
jl_gc_wb(codeinst, src);
Expand Down
48 changes: 47 additions & 1 deletion src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,30 @@ static int jl_serialize_generic(jl_serializer_state *s, jl_value_t *v) JL_GC_DIS
return 0;
}

static void uncompress_code(jl_method_instance_t *mi)
{
jl_method_t *m = mi->def.method;
assert(jl_is_method(m));
jl_code_instance_t *codeinst = mi->cache;
while (codeinst) {
if (codeinst->inferred && jl_is_array(codeinst->inferred))
codeinst->inferred = (jl_value_t*)jl_uncompress_ir(m, codeinst, (jl_array_t*)codeinst->inferred);
codeinst = codeinst->next;
}
}

static void compress_code(jl_method_instance_t *mi)
{
jl_method_t *m = mi->def.method;
assert(jl_is_method(m));
jl_code_instance_t *codeinst = mi->cache;
while (codeinst) {
if (codeinst->inferred && jl_is_code_info(codeinst->inferred))
codeinst->inferred = (jl_value_t*)jl_compress_ir(m, (jl_code_info_t*)codeinst->inferred);
codeinst = codeinst->next;
}
}

static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_t *codeinst, int skip_partial_opaque) JL_GC_DISABLED
{
if (jl_serialize_generic(s, (jl_value_t*)codeinst)) {
Expand Down Expand Up @@ -662,7 +686,29 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
int serialization_mode = 0;
if (m->is_for_opaque_closure || module_in_worklist(m->module))
serialization_mode |= METHOD_INTERNAL;
if (!(serialization_mode & METHOD_INTERNAL)) {
if (serialization_mode & METHOD_INTERNAL) {
// defer compression until serialization
// Compression must occur before roots are serialized.
// However, because jl_compress_ir is externally callable, first check
// whether we need to decompress. This enables root-reordering transformations.
if (m->source && jl_is_array(m->source))
m->source = (jl_value_t*)jl_uncompress_ir(m, NULL, (jl_array_t*)m->source);
size_t l = jl_svec_len(m->specializations);
for (i = 0; i < l; i++) {
jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(m->specializations, i);
if ((jl_value_t*)mi != jl_nothing)
uncompress_code(mi);
}
// Perform root-reordering transformations here
// Compress
if (m->source && jl_is_code_info(m->source))
m->source = (jl_value_t*)jl_compress_ir(m, (jl_code_info_t*)m->source);
for (i = 0; i < l; i++) {
jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(m->specializations, i);
if ((jl_value_t*)mi != jl_nothing)
compress_code(mi);
}
} else {
// flag this in the backref table as special
uintptr_t *bp = (uintptr_t*)ptrhash_bp(&backref_table, v);
assert(*bp != (uintptr_t)HT_NOTFOUND);
Expand Down
8 changes: 6 additions & 2 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,12 @@ static void jl_method_set_source(jl_method_t *m, jl_code_info_t *src)
jl_gc_wb(m, m->slot_syms);
if (gen_only)
m->source = NULL;
else
m->source = (jl_value_t*)jl_compress_ir(m, src);
else {
if (jl_options.incremental) // defer compression until serialization
m->source = (jl_value_t*)src;
else
m->source = (jl_value_t*)jl_compress_ir(m, src);
}
jl_gc_wb(m, m->source);
JL_GC_POP();
}
Expand Down

0 comments on commit 5589790

Please sign in to comment.