From dadb9a2c5031da6abf792f50d0c416ad1b078b93 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 27 May 2009 18:58:01 -0500 Subject: [PATCH] Add phi elimination pass --- basis/compiler/cfg/cfg.factor | 14 +++++-- .../cfg/optimizer/optimizer-tests.factor | 8 ++++ basis/compiler/cfg/optimizer/optimizer.factor | 38 ++++++++++--------- .../compiler/cfg/phi-elimination/authors.txt | 1 + .../phi-elimination/phi-elimination.factor | 21 ++++++++++ .../stack-analysis-tests.factor | 3 +- .../cfg/stack-analysis/stack-analysis.factor | 18 ++------- 7 files changed, 67 insertions(+), 36 deletions(-) create mode 100644 basis/compiler/cfg/optimizer/optimizer-tests.factor create mode 100644 basis/compiler/cfg/phi-elimination/authors.txt create mode 100644 basis/compiler/cfg/phi-elimination/phi-elimination.factor diff --git a/basis/compiler/cfg/cfg.factor b/basis/compiler/cfg/cfg.factor index be047f0658..265cbb8f00 100644 --- a/basis/compiler/cfg/cfg.factor +++ b/basis/compiler/cfg/cfg.factor @@ -1,6 +1,7 @@ -! Copyright (C) 2008 Slava Pestov. +! Copyright (C) 2008, 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel arrays vectors accessors namespaces ; +USING: kernel arrays vectors accessors +namespaces make fry sequences ; IN: compiler.cfg TUPLE: basic-block < identity-tuple @@ -12,13 +13,20 @@ number M: basic-block hashcode* nip id>> ; -: ( -- basic-block ) +: ( -- bb ) basic-block new V{ } clone >>instructions V{ } clone >>successors V{ } clone >>predecessors \ basic-block counter >>id ; +: add-instructions ( bb quot -- ) + [ instructions>> building ] dip '[ + building get pop + _ dip + building get push + ] with-variable ; inline + TUPLE: cfg { entry basic-block } word label ; C: cfg diff --git a/basis/compiler/cfg/optimizer/optimizer-tests.factor b/basis/compiler/cfg/optimizer/optimizer-tests.factor new file mode 100644 index 0000000000..5cc01173ad --- /dev/null +++ b/basis/compiler/cfg/optimizer/optimizer-tests.factor @@ -0,0 +1,8 @@ +USING: arrays sequences tools.test compiler.cfg.checker compiler.cfg.debugger +compiler.cfg.def-use sets kernel ; +IN: compiler.cfg.optimizer.tests + +! Miscellaneous tests + +[ ] [ [ 1array ] test-mr first check-mr ] unit-test +[ ] [ [ 1 2 ? ] test-mr first check-mr ] unit-test \ No newline at end of file diff --git a/basis/compiler/cfg/optimizer/optimizer.factor b/basis/compiler/cfg/optimizer/optimizer.factor index 41cd3c4b90..f59e9e0b83 100644 --- a/basis/compiler/cfg/optimizer/optimizer.factor +++ b/basis/compiler/cfg/optimizer/optimizer.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008, 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences accessors combinators +USING: kernel sequences accessors combinators namespaces compiler.cfg.predecessors compiler.cfg.useless-blocks compiler.cfg.height @@ -10,23 +10,27 @@ compiler.cfg.value-numbering compiler.cfg.dce compiler.cfg.write-barrier compiler.cfg.liveness -compiler.cfg.rpo ; +compiler.cfg.rpo +compiler.cfg.phi-elimination ; IN: compiler.cfg.optimizer : optimize-cfg ( cfg -- cfg ) [ - [ compute-predecessors ] - [ delete-useless-blocks ] - [ delete-useless-conditionals ] tri - ] [ - reverse-post-order - { - [ compute-liveness ] - [ normalize-height ] - [ stack-analysis ] - [ alias-analysis ] - [ value-numbering ] - [ eliminate-dead-code ] - [ eliminate-write-barriers ] - } cleave - ] [ ] tri ; + [ + [ compute-predecessors ] + [ delete-useless-blocks ] + [ delete-useless-conditionals ] tri + ] [ + reverse-post-order + { + [ normalize-height ] + [ stack-analysis ] + [ compute-liveness ] + [ alias-analysis ] + [ value-numbering ] + [ eliminate-dead-code ] + [ eliminate-write-barriers ] + [ eliminate-phis ] + } cleave + ] [ ] tri + ] with-scope ; diff --git a/basis/compiler/cfg/phi-elimination/authors.txt b/basis/compiler/cfg/phi-elimination/authors.txt new file mode 100644 index 0000000000..d4f5d6b3ae --- /dev/null +++ b/basis/compiler/cfg/phi-elimination/authors.txt @@ -0,0 +1 @@ +Slava Pestov \ No newline at end of file diff --git a/basis/compiler/cfg/phi-elimination/phi-elimination.factor b/basis/compiler/cfg/phi-elimination/phi-elimination.factor new file mode 100644 index 0000000000..d94e57f378 --- /dev/null +++ b/basis/compiler/cfg/phi-elimination/phi-elimination.factor @@ -0,0 +1,21 @@ +! Copyright (C) 2009 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors compiler.cfg compiler.cfg.instructions fry +kernel sequences ; +IN: compiler.cfg.phi-elimination + +: insert-copy ( predecessor input output -- ) + '[ _ _ swap ##copy ] add-instructions ; + +: eliminate-phi ( bb ##phi -- ) + [ predecessors>> ] [ [ inputs>> ] [ dst>> ] bi ] bi* + '[ _ insert-copy ] 2each ; + +: eliminate-phi-step ( bb -- ) + dup [ + [ ##phi? ] partition + [ [ eliminate-phi ] with each ] dip + ] change-instructions drop ; + +: eliminate-phis ( rpo -- ) + [ eliminate-phi-step ] each ; \ No newline at end of file diff --git a/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor b/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor index 8c941f4539..d43900018e 100644 --- a/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor +++ b/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor @@ -100,7 +100,8 @@ IN: compiler.cfg.stack-analysis.tests ] unit-test ! Sync before a back-edge, not after +! ##peeks should be inserted before a ##loop-entry [ 1 ] [ [ 1000 [ ] times ] test-stack-analysis dup eliminate-dead-code linearize-basic-blocks [ ##add-imm? ] count -] unit-test \ No newline at end of file +] unit-test diff --git a/basis/compiler/cfg/stack-analysis/stack-analysis.factor b/basis/compiler/cfg/stack-analysis/stack-analysis.factor index 6d602ede76..0aa402ed66 100644 --- a/basis/compiler/cfg/stack-analysis/stack-analysis.factor +++ b/basis/compiler/cfg/stack-analysis/stack-analysis.factor @@ -184,10 +184,6 @@ M: ##dispatch-label visit , ; ! Maps basic-blocks to states SYMBOLS: state-in state-out ; -: modify-instructions ( predecessor quot -- ) - [ instructions>> building ] dip - '[ building get pop _ dip building get push ] with-variable ; inline - : with-state ( state quot -- ) [ state ] dip with-variable ; inline @@ -203,22 +199,14 @@ ERROR: must-equal-failed seq ; : insert-peek ( predecessor loc -- vreg ) ! XXX critical edges - '[ _ ^^peek ] modify-instructions ; - -SYMBOL: phi-nodes - -: find-phis ( insns -- assoc ) - [ ##phi? ] filter [ [ inputs>> ] [ dst>> ] bi ] H{ } map>assoc ; - -: insert-phi ( inputs -- vreg ) - phi-nodes get [ ^^phi ] cache ; + '[ _ ^^peek ] add-instructions ; : merge-loc ( predecessors locs>vregs loc -- vreg ) ! Insert a ##phi in the current block where the input ! is the vreg storing loc from each predecessor block [ '[ [ _ ] dip at ] map ] keep '[ [ ] [ _ insert-peek ] ?if ] 2map - dup all-equal? [ first ] [ insert-phi ] if ; + dup all-equal? [ first ] [ ^^phi ] if ; : (merge-locs) ( predecessors assocs -- assoc ) dup [ keys ] map concat prune @@ -263,7 +251,7 @@ ERROR: cannot-merge-poisoned states ; cannot-merge-poisoned ] [ [ state new ] 2dip - [ [ instructions>> find-phis phi-nodes set ] [ predecessors>> ] bi ] dip + [ predecessors>> ] dip { [ merge-locs ] [ merge-actual-locs ]