Add phi elimination pass

db4
Slava Pestov 2009-05-27 18:58:01 -05:00
parent 3b79d61496
commit dadb9a2c50
7 changed files with 67 additions and 36 deletions

View File

@ -1,6 +1,7 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! 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 IN: compiler.cfg
TUPLE: basic-block < identity-tuple TUPLE: basic-block < identity-tuple
@ -12,13 +13,20 @@ number
M: basic-block hashcode* nip id>> ; M: basic-block hashcode* nip id>> ;
: <basic-block> ( -- basic-block ) : <basic-block> ( -- bb )
basic-block new basic-block new
V{ } clone >>instructions V{ } clone >>instructions
V{ } clone >>successors V{ } clone >>successors
V{ } clone >>predecessors V{ } clone >>predecessors
\ basic-block counter >>id ; \ 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 ; TUPLE: cfg { entry basic-block } word label ;
C: <cfg> cfg C: <cfg> cfg

View File

@ -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

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008, 2009 Slava Pestov. ! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! 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.predecessors
compiler.cfg.useless-blocks compiler.cfg.useless-blocks
compiler.cfg.height compiler.cfg.height
@ -10,10 +10,12 @@ compiler.cfg.value-numbering
compiler.cfg.dce compiler.cfg.dce
compiler.cfg.write-barrier compiler.cfg.write-barrier
compiler.cfg.liveness compiler.cfg.liveness
compiler.cfg.rpo ; compiler.cfg.rpo
compiler.cfg.phi-elimination ;
IN: compiler.cfg.optimizer IN: compiler.cfg.optimizer
: optimize-cfg ( cfg -- cfg ) : optimize-cfg ( cfg -- cfg )
[
[ [
[ compute-predecessors ] [ compute-predecessors ]
[ delete-useless-blocks ] [ delete-useless-blocks ]
@ -21,12 +23,14 @@ IN: compiler.cfg.optimizer
] [ ] [
reverse-post-order reverse-post-order
{ {
[ compute-liveness ]
[ normalize-height ] [ normalize-height ]
[ stack-analysis ] [ stack-analysis ]
[ compute-liveness ]
[ alias-analysis ] [ alias-analysis ]
[ value-numbering ] [ value-numbering ]
[ eliminate-dead-code ] [ eliminate-dead-code ]
[ eliminate-write-barriers ] [ eliminate-write-barriers ]
[ eliminate-phis ]
} cleave } cleave
] [ ] tri ; ] [ ] tri
] with-scope ;

View File

@ -0,0 +1 @@
Slava Pestov

View File

@ -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 ;

View File

@ -100,6 +100,7 @@ IN: compiler.cfg.stack-analysis.tests
] unit-test ] unit-test
! Sync before a back-edge, not after ! Sync before a back-edge, not after
! ##peeks should be inserted before a ##loop-entry
[ 1 ] [ [ 1 ] [
[ 1000 [ ] times ] test-stack-analysis dup eliminate-dead-code linearize-basic-blocks [ 1000 [ ] times ] test-stack-analysis dup eliminate-dead-code linearize-basic-blocks
[ ##add-imm? ] count [ ##add-imm? ] count

View File

@ -184,10 +184,6 @@ M: ##dispatch-label visit , ;
! Maps basic-blocks to states ! Maps basic-blocks to states
SYMBOLS: state-in state-out ; 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 -- ) : with-state ( state quot -- )
[ state ] dip with-variable ; inline [ state ] dip with-variable ; inline
@ -203,22 +199,14 @@ ERROR: must-equal-failed seq ;
: insert-peek ( predecessor loc -- vreg ) : insert-peek ( predecessor loc -- vreg )
! XXX critical edges ! XXX critical edges
'[ _ ^^peek ] modify-instructions ; '[ _ ^^peek ] add-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 ;
: merge-loc ( predecessors locs>vregs loc -- vreg ) : merge-loc ( predecessors locs>vregs loc -- vreg )
! Insert a ##phi in the current block where the input ! Insert a ##phi in the current block where the input
! is the vreg storing loc from each predecessor block ! is the vreg storing loc from each predecessor block
[ '[ [ _ ] dip at ] map ] keep [ '[ [ _ ] dip at ] map ] keep
'[ [ ] [ _ insert-peek ] ?if ] 2map '[ [ ] [ _ insert-peek ] ?if ] 2map
dup all-equal? [ first ] [ insert-phi ] if ; dup all-equal? [ first ] [ ^^phi ] if ;
: (merge-locs) ( predecessors assocs -- assoc ) : (merge-locs) ( predecessors assocs -- assoc )
dup [ keys ] map concat prune dup [ keys ] map concat prune
@ -263,7 +251,7 @@ ERROR: cannot-merge-poisoned states ;
cannot-merge-poisoned cannot-merge-poisoned
] [ ] [
[ state new ] 2dip [ state new ] 2dip
[ [ instructions>> find-phis phi-nodes set ] [ predecessors>> ] bi ] dip [ predecessors>> ] dip
{ {
[ merge-locs ] [ merge-locs ]
[ merge-actual-locs ] [ merge-actual-locs ]