Skip to content

Commit

Permalink
fix(func): avoid inlining self referenced funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
kollhof committed Oct 19, 2021
1 parent 74766e2 commit d1440ea
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 1 deletion.
23 changes: 23 additions & 0 deletions src/ir/func/init.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,29 @@ describe 'func', fn:
to_match_snapshot


it 'handles self ref', fn:
expect
fink2lir '
foo = fn:
count = fn start:
_iterable_ fn:
[start + 1, count start + 1]

count 0
'
to_match_snapshot

expect
fink2lir '
foo = fn:
count = fn start:
_iterable_ fn:
[start + 1, count start + 1]

count 0
', {optimize: {refs: true, tails: true, unused: true}}
to_match_snapshot


describe 'recursive funcs', fn:
it 'compiles recursive calls', fn:
Expand Down
73 changes: 73 additions & 0 deletions src/ir/func/init.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,79 @@ rec_e fn exports_0:
mod exports_1, drctvs_0, fn mod_0:"
`;

exports[`func handles self ref 1`] = `
"
rec_e fn exports_0:
id (fn args_0, ret_2: #fn
z (fn args_1, ret_1, count_0_0: #fn
lst_h args_1, fn start_0:
lst_t args_1, fn tail_0:
id _iterable_, fn callee_0:
lst_e fn cargs_0:
id (fn args_2, ret_0: #fn
lst_e fn lst_1:
id start_0, fn left_1:
int '1', fn right_1:
add left_1, right_1, fn item_1:
lst_a lst_1, item_1, fn lst_0:
id count_0_0, fn callee_1:
lst_e fn cargs_1:
id start_0, fn left_0:
int '1', fn right_0:
add left_0, right_0, fn arg_1:
lst_a cargs_1, arg_1, fn cargs_2:
af callee_1, cargs_2, fn item_0:
lst_a lst_0, item_0, fn result_2:
cc ret_0, result_2
), fn arg_0:
lst_a cargs_0, arg_0, fn cargs_3:
af callee_0, cargs_3, fn result_1:
cc ret_1, result_1
), fn count_0:
id count_0, fn callee_2:
lst_e fn cargs_4:
int '0', fn arg_2:
lst_a cargs_4, arg_2, fn cargs_5:
af callee_2, cargs_5, fn result_3:
cc ret_2, result_3
), fn foo_0:
str 'foo', fn key_0:
rec_s exports_0, key_0, foo_0, fn exports_1:
lst_e fn drctvs_0:
mod exports_1, drctvs_0, fn mod_0:"
`;

exports[`func handles self ref 2`] = `
"
rec_e fn exports_0:
id (fn args_0, ret_2: #fn
z (fn args_1, ret_1, count_0_0: #fn
tpl_i args_1, 0, fn start_0:
id (fn args_2, ret_0: #fn
int '1', fn right_1:
add start_0, right_1, fn item_1:
int '1', fn right_0:
add start_0, right_0, fn arg_1:
tpl arg_1, fn cargs_2:
af count_0_0, cargs_2, fn item_0:
tpl item_1, item_0, fn result_2:
cc ret_0, result_2
), fn arg_0:
tpl arg_0, fn cargs_3:
af _iterable_, cargs_3, fn result_1:
cc ret_1, result_1
), fn count_0:
int '0', fn arg_2:
tpl arg_2, fn cargs_5:
af count_0, cargs_5, fn result_3:
cc ret_2, result_3
), fn foo_0:
str 'foo', fn key_0:
rec_s exports_0, key_0, foo_0, fn exports_1:
tpl, fn drctvs_0:
mod exports_1, drctvs_0, fn mod_0:"
`;

exports[`func handles self-ref scoping 1`] = `
"
rec_e fn exports_0:
Expand Down
4 changes: 3 additions & 1 deletion src/js/func/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,16 @@ transform_normal_fn = fn expr, ctx:
self_ctx = set_js ret_id, ret, ctx

body_ctx = match self_id:
false: self_ctx
false:
self_ctx
else:
pipe self_ctx:
# set recursive calls to use res_id
# instead of using a Z-combinator and self_id
set_js self_id, (ident res_id), ?
# make sure calls to self_id always use res_id
update_value self_id, {ignore_refs: true}, ?
update_value res_id, {inline: false}, ?

[args, block, fn_ctx] = pipe body_ctx:
split_args_body fn_block, args_id, ?
Expand Down
11 changes: 11 additions & 0 deletions src/js/func/init.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ describe 'recursive functions', fn:
'
to_match_snapshot

expect
fink2js '
foo = fn:
count = fn start:
_iterable_ fn:
[start + 1, count start + 1]

count 0
'
to_match_snapshot


it 'compiles to while loop', fn:
expect
Expand Down
18 changes: 18 additions & 0 deletions src/js/func/init.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,21 @@ exports[`recursive functions compiles with self reference 1`] = `
export const foo = foo_0;"
`;
exports[`recursive functions compiles with self reference 2`] = `
"const foo_0 = () => {
const count_0 = start_0 => {
const result_1 = _iterable_(() => {
const item_0 = count_0(start_0 + 1);
return [start_0 + 1, item_0];
});
return result_1;
};
const result_3 = count_0(0);
return result_3;
};
export const foo = foo_0;"
`;

0 comments on commit d1440ea

Please sign in to comment.