Skip to content

Commit ba6a84c

Browse files
authored
feat(compiler): Reduce closure sizes by utilizing $self argument when possible (#1152)
1 parent ee1abcd commit ba6a84c

File tree

3 files changed

+719
-2
lines changed

3 files changed

+719
-2
lines changed

compiler/src/codegen/transl_anf.re

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,14 @@ let compile_lambda =
558558
(~name=?, id, env, args, body, attrs, loc): Mashtree.closure_data => {
559559
register_function(id);
560560
let (body, return_type) = body;
561-
let used_var_set = Anf_utils.anf_free_vars(body);
561+
// NOTE: we special-case `id`, since we want to
562+
// have simply-recursive uses of identifiers use
563+
// argument 0 ("$self") rather than do the self-reference
564+
// via a closure variable (this enables a large class
565+
// of recursive functions to be garbage-collectible, since
566+
// Grain's garbage collector does not currently collect
567+
// cyclic reference chains)
568+
let used_var_set = Ident.Set.remove(id, Anf_utils.anf_free_vars(body));
562569
let arg_vars = List.map(((arg, _)) => arg, args);
563570
let global_vars =
564571
Ident.fold_all((id, _, acc) => [id, ...acc], global_table^, []);
@@ -587,7 +594,8 @@ let compile_lambda =
587594
},
588595
free_binds,
589596
new_args,
590-
);
597+
)
598+
|> Ident.add(id, MArgBind(Int32.of_int(0), Types.HeapAllocated));
591599
let idx = next_lift();
592600
let args = List.map(((_, ty)) => ty, new_args);
593601
let arity = List.length(args);

0 commit comments

Comments
 (0)