From eb2981c9e9c62d9fc5e857bfafc6f00dc1d1109e Mon Sep 17 00:00:00 2001 From: jackbackrack Date: Tue, 14 Sep 2021 23:15:59 -0700 Subject: [PATCH 1/3] control-fold --- compiler/stz-el.stanza | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/compiler/stz-el.stanza b/compiler/stz-el.stanza index 14ee622bf..ef9b9ee3e 100644 --- a/compiler/stz-el.stanza +++ b/compiler/stz-el.stanza @@ -92,6 +92,7 @@ defn lower (epackage:EPackage, optimize?:True|False) -> EPackage : run-pass("Within Package Inline", within-package-inline{_, false}, "wp-inlined1", false) run-pass("Cleanup Labels", cleanup-labels, "cleanup-labels1", false) run-pass("Beta Reduce", beta-reduce, "beta-reduce1", false) + run-pass("Control Fold", control-fold, "control-fold1", false) run-pass("Box Unbox", box-unbox-fold, "box-unbox1", false) run-pass("Eliminate Dead Code", eliminate-dead-code, "dead-code1", false) ;Phase 2 @@ -99,6 +100,7 @@ defn lower (epackage:EPackage, optimize?:True|False) -> EPackage : run-pass("Within Package Inline", within-package-inline{_, false}, "wp-inlined2", false) run-pass("Cleanup Labels", cleanup-labels, "cleanup-labels2", false) run-pass("Beta Reduce", beta-reduce, "beta-reduce2", false) + run-pass("Control Fold", control-fold, "control-fold2", false) run-pass("Box Unbox", box-unbox-fold, "box-unbox2", false) run-pass("Eliminate Dead Code", eliminate-dead-code, "dead-code2", false) run-pass("Resolve Matches", resolve-matches, "resolved-matches", false) @@ -2777,6 +2779,54 @@ defn eliminate-dead-code (epackage:EPackage) -> EPackage : else : eliminate-in-item(e, elim-vars) as ETExp sub-exps(epackage, texps*) +;============================================================ +;==================== CONTROL FOLD ========================== +;============================================================ +;Inline single control flow instruction blocks into goto's +;setting up box-unbox of match/if's to fold away overhead +;Also prune unreachable blocks by walking basic-blocks +defn control-fold (epackage:EPackage) -> EPackage : + defn fold-body (body:EBody) -> EBody : + val block-table = analyze-basic-blocks(ins(body)) + val buffer = BodyBuffer(body) + val inlineable-blocks = IntTable() + + ;Find blocks with a single control flow instruction + for block in block-table do : + val insts = to-tuple $ instructions(block) + if length(insts) == 2 : + match(insts[0],insts[1]) : + (i0:ELabel,i1:EGoto|EIf|EMatch) : + inlineable-blocks[n(i0)] = i1 + (i0,i1) : false + + ;Inline single control flow blocks into goto instructions + for block in block-table do : + for i in instructions(block) do : + match(i) : + (g:EGoto) : + val ib = get?(inlineable-blocks, n(g)) + val i* = match(ib:EIns) : ib + else : i + emit(buffer, i*) + (i) : + emit(buffer, i) + + val body* = to-body(buffer) + body* + + defn fold-exp (e:ETExp) -> ETExp : + defn fold-in-bodies (e:ELBigItem) : + match(map(fold-in-bodies, e)) : + (e:EBody) : fold-body(e) + (e) : e + fold-in-bodies(e) as ETExp + + val texps* = for e in exps(epackage) map : + fold-exp(e) as ETExp + + sub-exps(epackage, texps*) + ;============================================================ ;=================== RESOLVE MATCHES ======================== ;============================================================ From 4da9adf95213c4f11d2ececf0d9c687f7a9e3e64 Mon Sep 17 00:00:00 2001 From: jackbackrack Date: Tue, 14 Sep 2021 23:17:04 -0700 Subject: [PATCH 2/3] reorder opt --- compiler/stz-el.stanza | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/stz-el.stanza b/compiler/stz-el.stanza index ef9b9ee3e..60b929914 100644 --- a/compiler/stz-el.stanza +++ b/compiler/stz-el.stanza @@ -92,17 +92,17 @@ defn lower (epackage:EPackage, optimize?:True|False) -> EPackage : run-pass("Within Package Inline", within-package-inline{_, false}, "wp-inlined1", false) run-pass("Cleanup Labels", cleanup-labels, "cleanup-labels1", false) run-pass("Beta Reduce", beta-reduce, "beta-reduce1", false) - run-pass("Control Fold", control-fold, "control-fold1", false) run-pass("Box Unbox", box-unbox-fold, "box-unbox1", false) run-pass("Eliminate Dead Code", eliminate-dead-code, "dead-code1", false) + run-pass("Control Fold", control-fold, "control-fold1", false) ;Phase 2 run-pass("Simple Inline", simple-inline, "inlined2", false) run-pass("Within Package Inline", within-package-inline{_, false}, "wp-inlined2", false) run-pass("Cleanup Labels", cleanup-labels, "cleanup-labels2", false) run-pass("Beta Reduce", beta-reduce, "beta-reduce2", false) - run-pass("Control Fold", control-fold, "control-fold2", false) run-pass("Box Unbox", box-unbox-fold, "box-unbox2", false) run-pass("Eliminate Dead Code", eliminate-dead-code, "dead-code2", false) + run-pass("Control Fold", control-fold, "control-fold2", false) run-pass("Resolve Matches", resolve-matches, "resolved-matches", false) run-pass("Lift Closures", lift-closures, "closurelifted", false) run-pass("Lift Type Objects", lift-type-objects, "typelifted", false) From 8d0c4675b87b2c06aaa4b4727f08be396e84abbe Mon Sep 17 00:00:00 2001 From: jackbackrack Date: Wed, 15 Sep 2021 15:24:34 -0700 Subject: [PATCH 3/3] make control-fold rebust against elive instructions --- compiler/stz-el.stanza | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/stz-el.stanza b/compiler/stz-el.stanza index 60b929914..2902121cb 100644 --- a/compiler/stz-el.stanza +++ b/compiler/stz-el.stanza @@ -2789,15 +2789,15 @@ defn control-fold (epackage:EPackage) -> EPackage : defn fold-body (body:EBody) -> EBody : val block-table = analyze-basic-blocks(ins(body)) val buffer = BodyBuffer(body) - val inlineable-blocks = IntTable() + val inlineable-blocks = IntTable>() ;Find blocks with a single control flow instruction for block in block-table do : - val insts = to-tuple $ instructions(block) + val insts = to-tuple $ for i in instructions(block) filter : i is-not ELive if length(insts) == 2 : match(insts[0],insts[1]) : (i0:ELabel,i1:EGoto|EIf|EMatch) : - inlineable-blocks[n(i0)] = i1 + inlineable-blocks[n(i0)] = tail(to-list $ instructions(block)) (i0,i1) : false ;Inline single control flow blocks into goto instructions @@ -2805,10 +2805,8 @@ defn control-fold (epackage:EPackage) -> EPackage : for i in instructions(block) do : match(i) : (g:EGoto) : - val ib = get?(inlineable-blocks, n(g)) - val i* = match(ib:EIns) : ib - else : i - emit(buffer, i*) + for i in get?(inlineable-blocks, n(g), List(i)) do : + emit(buffer, i) (i) : emit(buffer, i)