Skip to content

Commit 923cdd2

Browse files
committed
delete IR for non-inlineable functions after codegen to save memory
1 parent 85d098c commit 923cdd2

File tree

12 files changed

+73
-47
lines changed

12 files changed

+73
-47
lines changed

base/inference.jl

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14211421
# something completely new
14221422
elseif isa(code, LambdaInfo)
14231423
# something existing
1424-
if code.inferred
1424+
if code.inferred && !(needtree && code.code === nothing)
14251425
return (code, code.rettype, true)
14261426
end
14271427
else
@@ -1457,7 +1457,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14571457
# inference not started yet, make a new frame for a new lambda
14581458
# add lam to be inferred and record the edge
14591459

1460-
if caller === nothing && needtree && in_typeinf_loop
1460+
if caller === nothing && in_typeinf_loop
14611461
# if the caller needed the ast, but we are already in the typeinf loop
14621462
# then just return early -- we can't fulfill this request
14631463
# if the client was inlining, then this means we decided not to try to infer this
@@ -1486,7 +1486,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14861486
end
14871487
end
14881488

1489-
if isa(code, LambdaInfo)
1489+
if isa(code, LambdaInfo) && code.code !== nothing
14901490
# reuse the existing code object
14911491
linfo = code
14921492
@assert typeseq(linfo.specTypes, atypes)
@@ -2412,11 +2412,10 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
24122412
# end
24132413
# end
24142414

2415-
(linfo, ty, inferred) = typeinf(method, metharg, methsp, true)
2416-
if is(linfo,nothing) || !inferred
2415+
(linfo, ty, inferred) = typeinf(method, metharg, methsp, false)
2416+
if !inferred || linfo === nothing
24172417
return NF
2418-
end
2419-
if !linfo.inlineable
2418+
elseif !linfo.inlineable
24202419
# TODO
24212420
#=
24222421
if incompletematch
@@ -2443,6 +2442,11 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
24432442
end
24442443
=#
24452444
return NF
2445+
elseif linfo.code === nothing
2446+
(linfo, ty, inferred) = typeinf(method, metharg, methsp, true)
2447+
end
2448+
if linfo === nothing || !inferred || !linfo.inlineable
2449+
return NF
24462450
end
24472451

24482452
na = linfo.nargs
@@ -2483,7 +2487,9 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
24832487
nm = length(methargs)
24842488

24852489
ast = linfo.code
2486-
if !isa(ast,Array{Any,1})
2490+
if ast === nothing
2491+
return NF
2492+
elseif !isa(ast,Array{Any,1})
24872493
ast = ccall(:jl_uncompress_ast, Any, (Any,Any), linfo, ast)
24882494
else
24892495
ast = copy_exprargs(ast)

base/reflection.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ isempty(mt::MethodTable) = (mt.defs === nothing)
300300

301301
uncompressed_ast(l::Method) = uncompressed_ast(l.lambda_template)
302302
uncompressed_ast(l::LambdaInfo) =
303-
isa(l.code,Array{Any,1}) ? l.code::Array{Any,1} : ccall(:jl_uncompress_ast, Array{Any,1}, (Any,Any), l, l.code)
303+
isa(l.code,Array{UInt8,1}) ? ccall(:jl_uncompress_ast, Array{Any,1}, (Any,Any), l, l.code) : l.code
304304

305305
# Printing code representations in IR and assembly
306306
function _dump_function(f, t::ANY, native, wrapper, strip_ir_metadata, dump_module)

base/serialize.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,8 @@ end
637637
function deserialize(s::SerializationState, ::Type{LambdaInfo})
638638
linfo = ccall(:jl_new_lambda_info_uninit, Ref{LambdaInfo}, (Ptr{Void},), C_NULL)
639639
deserialize_cycle(s, linfo)
640-
linfo.code = deserialize(s)::Array{Any, 1}
641-
linfo.slotnames = deserialize(s)::Array{Any, 1}
640+
linfo.code = deserialize(s)
641+
linfo.slotnames = deserialize(s)
642642
linfo.slottypes = deserialize(s)
643643
linfo.slotflags = deserialize(s)
644644
linfo.ssavaluetypes = deserialize(s)

src/alloc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ void jl_lambda_info_set_ast(jl_lambda_info_t *li, jl_expr_t *ast)
314314
jl_expr_t *bodyex = (jl_expr_t*)jl_exprarg(ast, 2);
315315
assert(jl_is_expr(bodyex));
316316
jl_array_t *body = bodyex->args;
317-
li->code = body; jl_gc_wb(li, li->code);
317+
li->code = (jl_value_t*)body; jl_gc_wb(li, li->code);
318318
if (has_meta(body, pure_sym))
319319
li->pure = 1;
320320
jl_array_t *vinfo = (jl_array_t*)jl_exprarg(ast, 1);
@@ -473,7 +473,7 @@ static jl_lambda_info_t *jl_instantiate_staged(jl_method_t *generator, jl_tuplet
473473
func->specTypes = tt;
474474
jl_gc_wb(func, tt);
475475

476-
jl_array_t *stmts = func->code;
476+
jl_array_t *stmts = (jl_array_t*)func->code;
477477
for(i = 0, l = jl_array_len(stmts); i < l; i++) {
478478
jl_array_ptr_set(stmts, i, jl_resolve_globals(jl_array_ptr_ref(stmts, i), func));
479479
}
@@ -541,7 +541,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_get_specialized(jl_method_t *m, jl_tupletype_t
541541
JL_DLLEXPORT void jl_method_init_properties(jl_method_t *m)
542542
{
543543
jl_lambda_info_t *li = m->lambda_template;
544-
jl_value_t *body1 = skip_meta(li->code);
544+
jl_value_t *body1 = skip_meta((jl_array_t*)li->code);
545545
if (jl_is_linenode(body1)) {
546546
m->line = jl_linenode_line(body1);
547547
}
@@ -614,7 +614,7 @@ jl_method_t *jl_new_method(jl_lambda_info_t *definition, jl_sym_t *name, jl_tupl
614614
m->called = oldm->called;
615615
}
616616
else {
617-
jl_array_t *stmts = definition->code;
617+
jl_array_t *stmts = (jl_array_t*)definition->code;
618618
int i, l;
619619
for(i = 0, l = jl_array_len(stmts); i < l; i++) {
620620
jl_array_ptr_set(stmts, i, jl_resolve_globals(jl_array_ptr_ref(stmts, i), definition));

src/codegen.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,16 @@ static void to_function(jl_lambda_info_t *li)
874874
// mark the pointer calling convention
875875
li->jlcall_api = (f->getFunctionType() == jl_func_sig ? 0 : 1);
876876

877+
// if not inlineable, code won't be needed again
878+
if (JL_DELETE_NON_INLINEABLE &&
879+
li->def && li->inferred && !li->inlineable && !jl_options.outputji) {
880+
li->code = jl_nothing;
881+
li->slottypes = jl_nothing;
882+
li->ssavaluetypes = jl_box_long(jl_array_len(li->ssavaluetypes)); jl_gc_wb(li, li->ssavaluetypes);
883+
li->slotflags = NULL;
884+
li->slotnames = NULL;
885+
}
886+
877887
// done compiling: restore global state
878888
if (old != NULL) {
879889
builder.SetInsertPoint(old);
@@ -1115,6 +1125,15 @@ void *jl_get_llvmf(jl_tupletype_t *tt, bool getwrapper, bool getdeclarations)
11151125
return NULL;
11161126
}
11171127

1128+
if (linfo->code == jl_nothing) {
1129+
// re-infer if we've deleted the code
1130+
jl_type_infer(linfo, 0);
1131+
if (linfo->code == jl_nothing) {
1132+
JL_GC_POP();
1133+
return NULL;
1134+
}
1135+
}
1136+
11181137
if (!getdeclarations) {
11191138
// emit this function into a new module
11201139
Function *f, *specf;
@@ -3946,7 +3965,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
39463965
assert(declarations && "Capturing declarations is always required");
39473966

39483967
// step 1. unpack AST and allocate codegen context for this function
3949-
jl_array_t *code = lam->code;
3968+
jl_array_t *code = (jl_array_t*)lam->code;
39503969
JL_GC_PUSH1(&code);
39513970
if (!jl_typeis(code,jl_array_any_type))
39523971
code = jl_uncompress_ast(lam, code);

src/dump.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -467,15 +467,12 @@ static int module_in_worklist(jl_module_t *mod)
467467

468468
static int jl_prune_tcache(jl_typemap_entry_t *ml, void *closure)
469469
{
470-
if (!jl_is_leaf_type((jl_value_t*)ml->sig)) {
471-
jl_value_t *ret = ml->func.value;
472-
if (jl_is_lambda_info(ret)) {
473-
jl_array_t *code = ((jl_lambda_info_t*)ret)->code;
474-
if (jl_is_array(code) && jl_array_len(code) > 500) {
475-
ml->func.value = ((jl_lambda_info_t*)ret)->rettype;
476-
jl_gc_wb(ml, ml->func.value);
477-
}
478-
}
470+
jl_value_t *ret = ml->func.value;
471+
if (jl_is_lambda_info(ret) &&
472+
((!jl_is_leaf_type((jl_value_t*)ml->sig) && !((jl_lambda_info_t*)ret)->inlineable) ||
473+
((jl_lambda_info_t*)ret)->code == jl_nothing)) {
474+
ml->func.value = ((jl_lambda_info_t*)ret)->rettype;
475+
jl_gc_wb(ml, ml->func.value);
479476
}
480477
return 1;
481478
}
@@ -1476,7 +1473,7 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t
14761473
NWORDS(sizeof(jl_lambda_info_t)));
14771474
if (usetable)
14781475
arraylist_push(&backref_list, li);
1479-
li->code = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&li->code); jl_gc_wb(li, li->code);
1476+
li->code = jl_deserialize_value(s, &li->code); jl_gc_wb(li, li->code);
14801477
li->slotnames = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&li->slotnames); jl_gc_wb(li, li->slotnames);
14811478
li->slottypes = jl_deserialize_value(s, &li->slottypes); jl_gc_wb(li, li->slottypes);
14821479
li->slotflags = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&li->slotflags); jl_gc_wb(li, li->slotflags);
@@ -2076,6 +2073,7 @@ JL_DLLEXPORT jl_array_t *jl_compress_ast(jl_lambda_info_t *li, jl_array_t *ast)
20762073
{
20772074
JL_LOCK(&dump_lock); // Might GC
20782075
assert(jl_is_lambda_info(li));
2076+
assert(jl_is_array(ast));
20792077
DUMP_MODES last_mode = mode;
20802078
mode = MODE_AST;
20812079
ios_t dest;

src/gf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ jl_value_t *jl_mk_builtin_func(const char *name, jl_fptr_t fptr)
143143
jl_value_t *f = jl_new_generic_function_with_supertype(sname, jl_core_module, jl_builtin_type, 0);
144144
jl_lambda_info_t *li = jl_new_lambda_info_uninit();
145145
li->fptr = fptr;
146-
// TODO jb/functions: what should li->ast be?
147-
li->code = (jl_array_t*)jl_an_empty_vec_any; jl_gc_wb(li, li->code);
146+
// TODO jb/functions: what should li->code be?
147+
li->code = jl_nothing; jl_gc_wb(li, li->code);
148148
li->def = jl_new_method_uninit();
149149
li->def->name = sname;
150150
li->def->lambda_template = li;
@@ -164,7 +164,7 @@ jl_lambda_info_t *jl_get_unspecialized(jl_lambda_info_t *method)
164164
return method->unspecialized_ducttape;
165165
if (method->sparam_syms != jl_emptysvec) {
166166
if (def->needs_sparam_vals_ducttape == 2) {
167-
jl_array_t *code = method->code;
167+
jl_array_t *code = (jl_array_t*)method->code;
168168
JL_GC_PUSH1(&code);
169169
if (!jl_typeis(code, jl_array_any_type))
170170
code = jl_uncompress_ast(def->lambda_template, code);

src/interpreter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s, int start,
514514

515515
jl_value_t *jl_interpret_call(jl_lambda_info_t *lam, jl_value_t **args, uint32_t nargs, jl_svec_t *sparam_vals)
516516
{
517-
jl_array_t *stmts = lam->code;
517+
jl_array_t *stmts = (jl_array_t*)lam->code;
518518
assert(jl_typeis(stmts, jl_array_any_type));
519519
jl_value_t **locals;
520520
JL_GC_PUSHARGS(locals, jl_linfo_nslots(lam) + jl_linfo_nssavalues(lam));

src/jltypes.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3630,15 +3630,15 @@ void jl_init_types(void)
36303630
jl_new_datatype(jl_symbol("LambdaInfo"),
36313631
jl_any_type, jl_emptysvec,
36323632
jl_svec(25,
3633-
jl_symbol("code"),
3634-
jl_symbol("slotnames"),
3635-
jl_symbol("slottypes"),
3636-
jl_symbol("slotflags"),
3637-
jl_symbol("ssavaluetypes"),
36383633
jl_symbol("rettype"),
36393634
jl_symbol("sparam_syms"),
36403635
jl_symbol("sparam_vals"),
36413636
jl_symbol("specTypes"),
3637+
jl_symbol("code"),
3638+
jl_symbol("slottypes"),
3639+
jl_symbol("ssavaluetypes"),
3640+
jl_symbol("slotnames"),
3641+
jl_symbol("slotflags"),
36423642
jl_symbol("unspecialized_ducttape"),
36433643
jl_symbol("def"),
36443644
jl_symbol("nargs"),
@@ -3655,14 +3655,14 @@ void jl_init_types(void)
36553655
jl_symbol(""), jl_symbol("")),
36563656
jl_svec(25,
36573657
jl_any_type,
3658-
jl_array_any_type,
3658+
jl_simplevector_type,
3659+
jl_simplevector_type,
36593660
jl_any_type,
3660-
jl_array_uint8_type,
36613661
jl_any_type,
36623662
jl_any_type,
3663-
jl_simplevector_type,
3664-
jl_simplevector_type,
36653663
jl_any_type,
3664+
jl_array_any_type,
3665+
jl_array_uint8_type,
36663666
jl_any_type,
36673667
jl_method_type,
36683668
jl_int32_type,
@@ -3677,7 +3677,7 @@ void jl_init_types(void)
36773677
jl_any_type,
36783678
jl_any_type, jl_any_type,
36793679
jl_int32_type, jl_int32_type),
3680-
0, 1, 10);
3680+
0, 1, 7);
36813681
jl_svecset(jl_lambda_info_type->types, 9, jl_lambda_info_type);
36823682
jl_svecset(jl_method_type->types, 8, jl_lambda_info_type);
36833683

src/julia.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,15 @@ typedef struct _jl_method_t {
228228
// a function pointer.
229229
typedef struct _jl_lambda_info_t {
230230
JL_DATA_TYPE
231-
jl_array_t *code; // compressed uint8 array, or Any array of statements
232-
jl_array_t *slotnames; // names of local variables
233-
jl_value_t *slottypes;
234-
jl_array_t *slotflags; // local var bit flags
235-
jl_value_t *ssavaluetypes; // types of ssa values
236231
jl_value_t *rettype;
237232
jl_svec_t *sparam_syms; // sparams is a vector of values indexed by symbols
238233
jl_svec_t *sparam_vals;
239234
jl_tupletype_t *specTypes; // argument types this was specialized for
235+
jl_value_t *code; // compressed uint8 array, or Any array of statements
236+
jl_value_t *slottypes;
237+
jl_value_t *ssavaluetypes; // types of ssa values
238+
jl_array_t *slotnames; // names of local variables
239+
jl_array_t *slotflags; // local var bit flags
240240
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
241241
jl_method_t *def; // method this is specialized from, (null if this is a toplevel thunk)
242242
int32_t nargs;

0 commit comments

Comments
 (0)