git.iko.soy/rowtype-yoga/purescript-backend-optimizer
on main help sign in
Fix mutual TCO call arguments (#15)
commit13ff93f7bd14cc6db6708c440e8ac9e6b8c64c1d authorNathan Faubion <natefaubion@users.noreply.github.com> dateFri 26 Aug 2022, 12:24 (4 years ago) parentecd3a9b
4 files changed+62−24
backend-es/src/PureScript/Backend/Optimizer/Codegen/EcmaScript.purs+15−6 backend-es/test/snapshots-out/Snapshot.Tco04.js+18−18 backend-es/test/snapshots-out/Snapshot.Tco06.js+23 backend-es/test/snapshots/Snapshot.Tco06.purs+6
backend-es/src/PureScript/Backend/Optimizer/Codegen/EcmaScript.purs+15−6
@@ -616,10 +616,10 @@ esCodegenTcoMutualLoopBinding mode env tcoIdent bindings = case NonEmptyArray.to
616616 esCodegenTcoLoopBinding mode (noPure env) ident tco
617617 bindings' -> do
618618 let maxArgs = fromMaybe 0 $ maximum $ NonEmptyArray.length <<< _.arguments <<< snd <$> bindings
619− let argIdents = esTcoArgIdent tcoIdent <$> NonEmptyArray.range 0 maxArgs
619+ let argIdents = esTcoArgIdent tcoIdent <$> NonEmptyArray.range 0 (maxArgs - 1)
620620 let branchIdent = esTcoBranchIdent tcoIdent
621621 esSepStatements $
622− [ esBinding tcoIdent $ esTcoFn tcoIdent (NonEmptyArray.cons branchIdent argIdents) $ esBranches
622+ [ esBinding tcoIdent $ esMutualTcoFn tcoIdent (NonEmptyArray.cons branchIdent argIdents) $ esBranches
623623 ( mapWithIndex
624624 ( \ix (Tuple _ tco) -> do
625625 let { value: argNames, accum: env' } = freshNames RefStrict env tco.arguments
@@ -634,8 +634,11 @@ esCodegenTcoMutualLoopBinding mode env tcoIdent bindings = case NonEmptyArray.to
634634 ]
635635 <>
636636 mapWithIndex
637− ( \ix (Tuple ident _) ->
638− esBinding ident $ esPure $ esApp (esIdent tcoIdent) [ esInt ix ]
637+ ( \ix (Tuple ident { arguments: args }) -> do
638+ let { value: idents } = freshNames RefStrict env args
639+ esBinding ident $ esCurriedFn idents
640+ [ Return $ esApp (esIdent tcoIdent) $ Array.cons (esInt ix) (esIdent <$> NonEmptyArray.toArray idents)
641+ ]
639642 )
640643 bindings'
641644
@@ -903,7 +906,7 @@ esForeignModulePath (ModuleName _) = "./foreign.js"
903906esTcoMutualIdent :: NonEmptyArray Ident -> Ident
904907esTcoMutualIdent idents = case NonEmptyArray.toArray idents of
905908 [ ident ] -> ident
906− _ -> Ident $ foldMap (String.take 5 <<< unwrap) idents
909+ _ -> Ident $ "$" <> foldMap (String.take 5 <<< unwrap) idents
907910
908911esTcoLoopIdent :: Ident -> Ident
909912esTcoLoopIdent (Ident tcoIdent) = Ident (tcoIdent <> "$c")
@@ -921,7 +924,13 @@ esTcoCopyIdent :: Ident -> Ident
921924esTcoCopyIdent (Ident tcoIdent) = Ident (tcoIdent <> "$copy")
922925
923926esTcoFn :: forall a. Ident -> NonEmptyArray Ident -> Dodo.Doc a -> Dodo.Doc a
924−esTcoFn tcoIdent args body = esCurriedFn (esTcoCopyIdent <$> args)
927+esTcoFn tcoIdent args body = esCurriedFn (esTcoCopyIdent <$> args) (esTcoFnBody tcoIdent args body)
928+
929+esMutualTcoFn :: forall a. Ident -> NonEmptyArray Ident -> Dodo.Doc a -> Dodo.Doc a
930+esMutualTcoFn tcoIdent args body = esFn (esTcoCopyIdent <$> NonEmptyArray.toArray args) (esTcoFnBody tcoIdent args body)
931+
932+esTcoFnBody :: forall a. Ident -> NonEmptyArray Ident -> Dodo.Doc a -> Array (EsStatement (Dodo.Doc a))
933+esTcoFnBody tcoIdent args body =
925934 [ Statement $ esLetBindings $ NonEmptyArray.appendArray bindings
926935 [ Tuple (esTcoLoopIdent tcoIdent) (Just (esBoolean true))
927936 , Tuple (esTcoReturnIdent tcoIdent) Nothing
backend-es/test/snapshots-out/Snapshot.Tco04.js+18−18
@@ -1,32 +1,32 @@
11import * as $runtime from "../runtime.js";
2−const test2test1 = test2test1$b$copy => test2test1$a0$copy => test2test1$a1$copy => {
3− let test2test1$b = test2test1$b$copy, test2test1$a0 = test2test1$a0$copy, test2test1$a1 = test2test1$a1$copy, test2test1$c = true, test2test1$r;
4− while (test2test1$c) {
5− if (test2test1$b === 0) {
6− const m = test2test1$a0;
2+const $test2test1 = ($test2test1$b$copy, $test2test1$a0$copy) => {
3+ let $test2test1$b = $test2test1$b$copy, $test2test1$a0 = $test2test1$a0$copy, $test2test1$c = true, $test2test1$r;
4+ while ($test2test1$c) {
5+ if ($test2test1$b === 0) {
6+ const m = $test2test1$a0;
77 if (m === 2) {
8− test2test1$c = false;
9− test2test1$r = m;
8+ $test2test1$c = false;
9+ $test2test1$r = m;
1010 continue;
1111 }
12− test2test1$b = 1;
13− test2test1$a0 = m - 2 | 0;
12+ $test2test1$b = 1;
13+ $test2test1$a0 = m - 2 | 0;
1414 continue;
1515 }
16− if (test2test1$b === 1) {
17− const n = test2test1$a0;
16+ if ($test2test1$b === 1) {
17+ const n = $test2test1$a0;
1818 if (n === 1) {
19− test2test1$c = false;
20− test2test1$r = n;
19+ $test2test1$c = false;
20+ $test2test1$r = n;
2121 continue;
2222 }
23− test2test1$b = 0;
24− test2test1$a0 = n - 1 | 0;
23+ $test2test1$b = 0;
24+ $test2test1$a0 = n - 1 | 0;
2525 continue;
2626 }
2727 };
28− return test2test1$r;
28+ return $test2test1$r;
2929};
30−const test2 = /* #__PURE__ */ test2test1(0);
31−const test1 = /* #__PURE__ */ test2test1(1);
30+const test2 = m => $test2test1(0, m);
31+const test1 = n => $test2test1(1, n);
3232export {test1, test2};
backend-es/test/snapshots-out/Snapshot.Tco06.jsnew file+23
@@ -0,0 +1,23 @@
1+import * as $runtime from "../runtime.js";
2+const $gf = ($gf$b$copy, $gf$a0$copy, $gf$a1$copy) => {
3+ let $gf$b = $gf$b$copy, $gf$a0 = $gf$a0$copy, $gf$a1 = $gf$a1$copy, $gf$c = true, $gf$r;
4+ while ($gf$c) {
5+ if ($gf$b === 0) {
6+ const a = $gf$a0;
7+ $gf$b = 1;
8+ $gf$a0 = a;
9+ $gf$a1 = a + 1 | 0;
10+ continue;
11+ }
12+ if ($gf$b === 1) {
13+ const a = $gf$a0, b = $gf$a1;
14+ $gf$b = 0;
15+ $gf$a0 = a + b | 0;
16+ continue;
17+ }
18+ };
19+ return $gf$r;
20+};
21+const g = a => $gf(0, a);
22+const f = a => b => $gf(1, a, b);
23+export {f, g};
backend-es/test/snapshots/Snapshot.Tco06.pursnew file+6
@@ -0,0 +1,6 @@
1+module Snapshot.Tco06 where
2+
3+import Prelude
4+
5+f a b = g (a + b)
6+g a = f a (a + 1)