Skip to content

Commit

Permalink
fix: list optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
kollhof committed Oct 1, 2021
1 parent 9b76dba commit d91c5c7
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 58 deletions.
8 changes: 8 additions & 0 deletions src/ir/call/pipe.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,11 @@ describe 'pipe', fn:
'
to_match_snapshot

expect
fink2lir '
foo = bar fn:
pipe:
spam
?.shrub 123
'
to_match_snapshot
34 changes: 34 additions & 0 deletions src/ir/call/pipe.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,37 @@ rec_e fn exports_0:
lst_e fn drctvs_0:
mod exports_0, drctvs_0, fn mod_0:"
`;

exports[`pipe compiles with partials 2`] = `
"
rec_e fn exports_0:
id bar, fn callee_0:
lst_e fn cargs_0:
id (fn args_0, ret_1: #fn
id spam, fn pfn_0:
lst_e fn args_1:
af pfn_0, args_1, fn ppr_0:
id (fn args_2, ret_0: #fn
lst_h args_2, fn prtl_0:
id prtl_0, fn left_0:
str 'shrub', fn key_0:
rec_g left_0, key_0, fn callee_1:
lst_e fn cargs_1:
int '123', fn arg_1:
lst_a cargs_1, arg_1, fn cargs_2:
af callee_1, cargs_2, fn pfn_2:
cc ret_0, pfn_2
), fn pfn_1:
lst_e fn args_3:
lst_a args_3, ppr_0, fn args_4:
af pfn_1, args_4, fn ppr_1:
id ppr_1, fn result_0:
cc ret_1, result_0
), fn arg_0:
lst_a cargs_0, arg_0, fn cargs_3:
af callee_0, cargs_3, fn foo_0:
str 'foo', fn key_1:
rec_s exports_0, key_1, foo_0, fn exports_1:
lst_e fn drctvs_0:
mod exports_1, drctvs_0, fn mod_0:"
`;
15 changes: 14 additions & 1 deletion src/ir/literals/list.test.fnk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{fink2lir} = import '../../testing/generate.fnk'
{fink2lir, fink2js} = import '../../testing/generate.fnk'
{skip, describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk'


Expand Down Expand Up @@ -103,6 +103,19 @@ describe 'optimizations', fn:
to_match_snapshot


it 'optimizes spreads', fn:
expect
fink2js '
y = [1, 2]
[..., spam] = y
[...sp, shrub] = [1, 2, 3]
[x] = sp
[...spl] = lala
log x, y, spl, lala, sp, shrub
', {optimize: {refs: true, tails: true, unused: true}}
to_match_snapshot


it 'ignores empty concats', fn:
expect
fink2lir '
Expand Down
7 changes: 7 additions & 0 deletions src/ir/literals/list.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ rec_e fn exports_0:
mod exports_3, drctvs_0, fn mod_0:"
`;

exports[`optimizations optimizes spreads 1`] = `
"const y_0 = [1, 2];
const item_4 = 1;
log(item_4, y_0, lala, lala, [item_4, 2], 3);
export const y = y_0;"
`;

exports[`optimizations reuses item refs 1`] = `
"
rec_e fn exports_0:
Expand Down
3 changes: 1 addition & 2 deletions src/ir/module/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ transform_exprs = fn [expr=false, ...rest], exp_id, ctx, out:


transform_directives = fn expr, ctx:
# TODO: directives should be handled as separate AST node

# TODO: directives should be handled as separate AST node in larix
[drctvs, dirs_id, next_ctx] = lst 'drctvs', expr, ctx

{exprs: [{comments}]} = expr
Expand Down
1 change: 0 additions & 1 deletion src/js/call/call.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ transform_continue_with_cont = fn expr, ctx:
false:
match ret:
{type: 'ReturnStatement'}:
# TODO remove if this is the last expr in a func
[[ret], ctx]
else:
[[], ctx]
Expand Down
4 changes: 1 addition & 3 deletions src/js/call/pipe.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ describe 'pipe', fn:
'
to_match_snapshot

# TODO: move or copy to ir/
describe 'TODO', fn:
it 'compiles', fn:
expect
fink2js '
foo = bar fn:
Expand All @@ -34,6 +31,7 @@ describe 'TODO', fn:
to_match_snapshot



describe 'small pipe |', fn:
it 'pipes', fn:
expect
Expand Down
28 changes: 14 additions & 14 deletions src/js/call/pipe.test.fnk.snap
Original file line number Diff line number Diff line change
@@ -1,19 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TODO compiles 1`] = `
"const foo_0 = bar(() => {
const ppr_0 = spam();
const ppr_1 = (prtl_0 => {
const pfn_2 = prtl_0.shrub(123);
return pfn_2;
})(ppr_0);
return ppr_1;
});
export const foo = foo_0;"
`;

exports[`pipe compiles 1`] = `
"const ppr_0 = foo();
Expand Down Expand Up @@ -50,6 +36,20 @@ export const p1 = ppr_5,
p2 = ppr_7;"
`;

exports[`pipe compiles 2`] = `
"const foo_0 = bar(() => {
const ppr_0 = spam();
const ppr_1 = (prtl_0 => {
const pfn_2 = prtl_0.shrub(123);
return pfn_2;
})(ppr_0);
return ppr_1;
});
export const foo = foo_0;"
`;

exports[`small pipe | handles precedence 1`] = `
"export const foo = (ˆpartial => matches(rx\`[a-z]\`, ˆpartial))(\`foo\`);
export const bar = [ham(spam), ni(shrub)];"
Expand Down
7 changes: 4 additions & 3 deletions src/js/func/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ types = import '@babel/types'
labeledStatement, doWhileStatement, booleanLiteral
} = types

{map} = import '@fink/std-lib/iter.fnk'
{map, is_empty} = import '@fink/std-lib/iter.fnk'

{get_refs, update_value} = import '../../ir/context.fnk'
{transform_exprs} = import '../transform.fnk'
Expand All @@ -15,8 +15,7 @@ types = import '@babel/types'

clean_args = fn args_id, args, body, ctx:
fn_args = match [args, get_refs args_id, ctx]:
# TODO use is_empty
[{length: 0}, ? > 0]:
[(is_empty ?), ? > 0]:
[with_loc args_id, restElement ident args_id, ctx]
else:
[..., last] = args
Expand All @@ -29,6 +28,8 @@ clean_args = fn args_id, args, body, ctx:

[fn_args, body, ctx]



# These are mostly ir transformations, should this be done as a prep step
split_args_body = fn [expr=false, ...exprs], args_id, ctx, args=[], body=[]:
match expr:
Expand Down
6 changes: 3 additions & 3 deletions src/optimize/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@




maybe_opt_refs = fn ir, ctx:
match ctx:
{optimize.refs: true}:
Expand All @@ -16,6 +15,7 @@ maybe_opt_refs = fn ir, ctx:
[ir, ctx]



maybe_opt_tails = fn ir, ctx:
match ctx:
{optimize.tails: true}:
Expand All @@ -25,6 +25,7 @@ maybe_opt_tails = fn ir, ctx:
[ir, ctx]



maybe_opt_unused = fn ir, ctx:
match ctx:
{optimize.unused: true}:
Expand All @@ -34,6 +35,7 @@ maybe_opt_unused = fn ir, ctx:
[ir, ctx]



maybe_opt_names = fn ir, ctx:
match ctx:
{optimize.names: true}:
Expand All @@ -43,8 +45,6 @@ maybe_opt_names = fn ir, ctx:





optimize = fn exprs, options:
pipe [exprs, init_ctx exprs, options]:
maybe_opt_refs ...?
Expand Down
2 changes: 2 additions & 0 deletions src/optimize/init.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk'



describe 'optimize', fn:
it 'foo', fn:
expect
Expand All @@ -14,6 +15,7 @@ describe 'optimize', fn:
', {optimize: {refs: true, tails: true, unused: true}}
to_match_snapshot


it 'optimizes values', fn:
expect
fink2lir '
Expand Down
29 changes: 15 additions & 14 deletions src/optimize/init.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -198,18 +198,19 @@ rec_e fn exports_0:
int '1', fn item_9:
int '2', fn item_8:
int '3', fn item_7:
lst_a sp_0_2, item_9, fn sp_0_1:
lst_a sp_0_1, item_8, fn sp_0:
lst_e fn cargs_0:
lst_a cargs_0, item_6, fn cargs_1:
lst_a cargs_1, x_0, fn cargs_2:
lst_a cargs_2, item_4, fn cargs_3:
lst_a cargs_3, y_0, fn cargs_4:
lst_a cargs_4, item_7, fn cargs_5:
lst_a cargs_5, sp_0, fn cargs_6:
lst_a cargs_6, item_9, fn cargs_7:
lst_a cargs_7, lala, fn cargs_8:
af log, cargs_8, fn mex_5:
lst_e fn drctvs_0:
mod exports_2, drctvs_0, fn mod_0:"
lst_e fn sp_0_1:
lst_a sp_0_1, item_9, fn sp_0_0:
lst_a sp_0_0, item_8, fn sp_0:
lst_e fn cargs_0:
lst_a cargs_0, item_6, fn cargs_1:
lst_a cargs_1, x_0, fn cargs_2:
lst_a cargs_2, item_4, fn cargs_3:
lst_a cargs_3, y_0, fn cargs_4:
lst_a cargs_4, item_7, fn cargs_5:
lst_a cargs_5, sp_0, fn cargs_6:
lst_a cargs_6, item_9, fn cargs_7:
lst_a cargs_7, lala, fn cargs_8:
af log, cargs_8, fn mex_5:
lst_e fn drctvs_0:
mod exports_2, drctvs_0, fn mod_0:"
`;
23 changes: 8 additions & 15 deletions src/optimize/refs.fnk
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{reverse} = import '@fink/std-lib/iter.fnk'

{update_value, get_value} = import '../ir/context.fnk'
{update_value, get_value, unique_name} = import '../ir/context.fnk'



Expand Down Expand Up @@ -110,21 +110,15 @@ optimize_lst_c = fn [expr, res], ctx:



create_lst = fn [id=false, ...ids], lst_id, idx=0, out=[]:
create_lst = fn [id=false, ...ids], lst_id, tmp_id, ctx, out=[]:
match id:
# TODO gen unique ids
false:
nid = {i: '${lst_id.i}_${idx + 1}', loc: lst_id.loc}
[[{f: 'lst', args: [], loc: lst_id.loc}, [nid]], ...out]
[[[{f: 'lst', args: [], loc: lst_id.loc}, [tmp_id]], ...out], ctx]

else:
res_id = match idx:
0: lst_id
else: {i: '${lst_id.i}_${idx}', loc: lst_id.loc}

next_lst_id = {i: '${lst_id.i}_${idx + 1}'}
lst = [{f: 'lst_a', args: [next_lst_id, id], loc: id.loc}, [res_id]]
create_lst ids, lst_id, idx + 1, [lst, ...out]
[next_tmp_id, end_ctx] = unique_name lst_id.i, lst_id, ctx
lst = [{f: 'lst_a', args: [next_tmp_id, id], loc: id.loc}, [tmp_id]]
create_lst ids, lst_id, next_tmp_id, end_ctx, [lst, ...out]



Expand All @@ -144,9 +138,8 @@ optimize_lst_r = fn [expr, res], ctx:
{item_aliases: rev_aliases} = info
# find existing tpl instead of creating
item_aliases = reverse rev_aliases
next_ctx = update_value res_id, {item_aliases, tpr: lst_id}, ctx
next_lst = create_lst rev_aliases, res_id
[next_lst, next_ctx]
lst_ctx = update_value res_id, {item_aliases, tpr: lst_id}, ctx
create_lst rev_aliases, res_id, res_id, lst_ctx

else:
next_ctx = update_value res_id, {tpr: lst_id}, ctx
Expand Down
2 changes: 0 additions & 2 deletions src/optimize/tail-calls.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ optimize_af = fn [expr, res], exprs, ctx:

match [callee_id.i, next_expr]:
[curr_fn_id.i, [{f: 'cc', args: [{i: ret_id.i}]}]]:
# TODO: if cc would have an id, we could just store opt info for it and
# convert it separately instead of using exprs
opt_expr = {...expr, f: 'cf', args: [callee_id, ...args]}
next_ctx = update_value curr_fn_id, {tco: true}, ctx
[[[opt_expr, []]], rest_exprs, next_ctx]
Expand Down

0 comments on commit d91c5c7

Please sign in to comment.