diff --git a/basis/compiler/cfg/branch-folding/branch-folding-tests.factor b/basis/compiler/cfg/branch-folding/branch-folding-tests.factor new file mode 100644 index 0000000000..1068954f9d --- /dev/null +++ b/basis/compiler/cfg/branch-folding/branch-folding-tests.factor @@ -0,0 +1,44 @@ +IN: compiler.cfg.branch-folding.tests +USING: compiler.cfg.branch-folding compiler.cfg.instructions +compiler.cfg compiler.cfg.registers compiler.cfg.debugger +arrays compiler.cfg.phi-elimination +compiler.cfg.predecessors kernel accessors +sequences classes namespaces tools.test cpu.architecture ; + +V{ T{ ##branch } } 0 test-bb + +V{ + T{ ##peek f V int-regs 0 D 0 } + T{ ##compare-branch f V int-regs 0 V int-regs 0 cc< } +} 1 test-bb + +V{ + T{ ##load-immediate f V int-regs 1 1 } + T{ ##branch } +} 2 test-bb + +V{ + T{ ##load-immediate f V int-regs 2 2 } + T{ ##branch } +} 3 test-bb + +V{ + T{ ##phi f V int-regs 3 { } } + T{ ##replace f V int-regs 3 D 0 } + T{ ##return } +} 4 test-bb + +4 get instructions>> first +2 get V int-regs 1 2array +3 get V int-regs 2 2array 2array +>>inputs drop + +test-diamond + +[ ] [ cfg new 0 get >>entry fold-branches compute-predecessors eliminate-phis drop ] unit-test + +[ 1 ] [ 1 get successors>> length ] unit-test +[ t ] [ 1 get successors>> first 3 get eq? ] unit-test + +[ T{ ##copy f V int-regs 3 V int-regs 2 } ] [ 3 get instructions>> second ] unit-test +[ 2 ] [ 4 get instructions>> length ] unit-test \ No newline at end of file diff --git a/basis/compiler/cfg/dce/dce.factor b/basis/compiler/cfg/dce/dce.factor index ea4a1d22ab..fdc6601de4 100644 --- a/basis/compiler/cfg/dce/dce.factor +++ b/basis/compiler/cfg/dce/dce.factor @@ -99,5 +99,5 @@ M: insn live-insn? drop t ; dup [ [ instructions>> [ build-liveness-graph ] each ] each-basic-block ] [ [ instructions>> [ compute-live-vregs ] each ] each-basic-block ] - [ [ [ [ live-insn? ] filter ] change-instructions drop ] each-basic-block ] + [ [ instructions>> [ live-insn? ] filter-here ] each-basic-block ] tri ; diff --git a/basis/compiler/cfg/def-use/def-use.factor b/basis/compiler/cfg/def-use/def-use.factor index 4ff9814e6d..43ea89f284 100644 --- a/basis/compiler/cfg/def-use/def-use.factor +++ b/basis/compiler/cfg/def-use/def-use.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008, 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays kernel compiler.cfg.instructions ; +USING: accessors arrays kernel assocs compiler.cfg.instructions ; IN: compiler.cfg.def-use GENERIC: defs-vregs ( insn -- seq ) @@ -43,7 +43,7 @@ M: ##dispatch uses-vregs src>> 1array ; M: ##alien-getter uses-vregs src>> 1array ; M: ##alien-setter uses-vregs [ src>> ] [ value>> ] bi 2array ; M: ##fixnum-overflow uses-vregs [ src1>> ] [ src2>> ] bi 2array ; -M: ##phi uses-vregs inputs>> ; +M: ##phi uses-vregs inputs>> values ; M: _conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ; M: _compare-imm-branch uses-vregs src1>> 1array ; M: _dispatch uses-vregs src>> 1array ; diff --git a/basis/compiler/cfg/liveness/liveness-tests.factor b/basis/compiler/cfg/liveness/liveness-tests.factor new file mode 100644 index 0000000000..271dc60d76 --- /dev/null +++ b/basis/compiler/cfg/liveness/liveness-tests.factor @@ -0,0 +1,15 @@ +USING: compiler.cfg compiler.cfg.instructions compiler.cfg.registers +compiler.cfg.liveness accessors tools.test cpu.architecture ; +IN: compiler.cfg.liveness.tests + +[ + H{ + { "A" H{ { V int-regs 1 V int-regs 1 } { V int-regs 4 V int-regs 4 } } } + { "B" H{ { V int-regs 3 V int-regs 3 } { V int-regs 2 V int-regs 2 } } } + } +] [ + V{ + T{ ##phi f V int-regs 0 { { "A" V int-regs 1 } { "B" V int-regs 2 } } } + T{ ##phi f V int-regs 1 { { "B" V int-regs 3 } { "A" V int-regs 4 } } } + } >>instructions compute-phi-live-in +] unit-test \ No newline at end of file diff --git a/basis/compiler/cfg/liveness/liveness.factor b/basis/compiler/cfg/liveness/liveness.factor index 6c40bb3782..8a46b32070 100644 --- a/basis/compiler/cfg/liveness/liveness.factor +++ b/basis/compiler/cfg/liveness/liveness.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel namespaces deques accessors sets sequences assocs fry -dlists compiler.cfg.def-use compiler.cfg.instructions +hashtables dlists compiler.cfg.def-use compiler.cfg.instructions compiler.cfg.rpo ; IN: compiler.cfg.liveness @@ -16,9 +16,7 @@ SYMBOL: live-ins ! is in conrrespondence with a predecessor SYMBOL: phi-live-ins -: phi-live-in ( predecessor basic-block -- set ) - [ predecessors>> index ] keep phi-live-ins get at - dup [ nth ] [ 2drop f ] if ; +: phi-live-in ( predecessor basic-block -- set ) phi-live-ins get at at ; ! Assoc mapping basic blocks to sets of vregs SYMBOL: live-outs @@ -45,9 +43,15 @@ SYMBOL: work-list [ nip kill-set ] 2bi assoc-diff ; +: conjoin-at ( value key assoc -- ) + [ dupd ?set-at ] change-at ; + : compute-phi-live-in ( basic-block -- phi-live-in ) - instructions>> [ ##phi? ] filter - [ f ] [ [ inputs>> ] map flip [ unique ] map ] if-empty ; + instructions>> [ ##phi? ] filter [ f ] [ + H{ } clone [ + '[ inputs>> [ swap _ conjoin-at ] assoc-each ] each + ] keep + ] if-empty ; : update-live-in ( basic-block -- changed? ) [ [ compute-live-in ] keep live-ins get maybe-set-at ] diff --git a/basis/compiler/cfg/phi-elimination/phi-elimination-tests.factor b/basis/compiler/cfg/phi-elimination/phi-elimination-tests.factor new file mode 100644 index 0000000000..4577e70997 --- /dev/null +++ b/basis/compiler/cfg/phi-elimination/phi-elimination-tests.factor @@ -0,0 +1,40 @@ +IN: compiler.cfg.phi-elimination.tests +USING: compiler.cfg.instructions compiler.cfg compiler.cfg.registers +compiler.cfg.debugger compiler.cfg.phi-elimination kernel accessors +sequences classes namespaces tools.test cpu.architecture arrays ; + +V{ T{ ##branch } } 0 test-bb + +V{ + T{ ##peek f V int-regs 0 D 0 } + T{ ##compare-branch f V int-regs 0 V int-regs 0 cc< } +} 1 test-bb + +V{ + T{ ##load-immediate f V int-regs 1 1 } + T{ ##branch } +} 2 test-bb + +V{ + T{ ##load-immediate f V int-regs 2 2 } + T{ ##branch } +} 3 test-bb + +V{ + T{ ##phi f V int-regs 3 { } } + T{ ##replace f V int-regs 3 D 0 } + T{ ##return } +} 4 test-bb + +4 get instructions>> first +2 get V int-regs 1 2array +3 get V int-regs 2 2array 2array +>>inputs drop + +test-diamond + +[ ] [ cfg new 0 get >>entry eliminate-phis drop ] unit-test + +[ T{ ##copy f V int-regs 3 V int-regs 1 } ] [ 2 get instructions>> second ] unit-test +[ T{ ##copy f V int-regs 3 V int-regs 2 } ] [ 3 get instructions>> second ] unit-test +[ 2 ] [ 4 get instructions>> length ] unit-test \ 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 index 3ebf553a45..9c2f0adafd 100644 --- a/basis/compiler/cfg/phi-elimination/phi-elimination.factor +++ b/basis/compiler/cfg/phi-elimination/phi-elimination.factor @@ -1,21 +1,17 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors compiler.cfg compiler.cfg.instructions -compiler.cfg.rpo fry kernel sequences ; +USING: accessors assocs fry kernel sequences +compiler.cfg compiler.cfg.instructions compiler.cfg.rpo ; 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 ( ##phi -- ) + [ inputs>> ] [ dst>> ] bi '[ _ insert-copy ] assoc-each ; : eliminate-phi-step ( bb -- ) - dup [ - [ ##phi? ] partition - [ [ eliminate-phi ] with each ] dip - ] change-instructions drop ; + instructions>> [ dup ##phi? [ eliminate-phi f ] [ drop t ] if ] filter-here ; : eliminate-phis ( cfg -- cfg' ) dup [ eliminate-phi-step ] each-basic-block ; \ No newline at end of file diff --git a/basis/compiler/cfg/stack-analysis/merge/merge-tests.factor b/basis/compiler/cfg/stack-analysis/merge/merge-tests.factor index e519308974..14a81958a9 100644 --- a/basis/compiler/cfg/stack-analysis/merge/merge-tests.factor +++ b/basis/compiler/cfg/stack-analysis/merge/merge-tests.factor @@ -17,7 +17,7 @@ sequences kernel classes ; H{ { D 0 V int-regs 0 } } >>locs>vregs H{ { D 0 V int-regs 1 } } >>locs>vregs 2array - [ merge-locs locs>vregs>> keys ] { } make first inputs>> + [ merge-locs locs>vregs>> keys ] { } make first inputs>> values ] unit-test [ diff --git a/basis/compiler/cfg/stack-analysis/merge/merge.factor b/basis/compiler/cfg/stack-analysis/merge/merge.factor index 04643a31f0..b6c443a2d3 100644 --- a/basis/compiler/cfg/stack-analysis/merge/merge.factor +++ b/basis/compiler/cfg/stack-analysis/merge/merge.factor @@ -48,8 +48,9 @@ IN: compiler.cfg.stack-analysis.merge : merge-loc ( predecessors vregs loc state -- vreg ) ! Insert a ##phi in the current block where the input ! is the vreg storing loc from each predecessor block + [ dup ] 3dip '[ [ ] [ _ _ insert-peek ] ?if ] 2map - dup all-equal? [ first ] [ ^^phi ] if ; + dup all-equal? [ nip first ] [ zip ^^phi ] if ; :: merge-locs ( state predecessors states -- state ) states [ locs>vregs>> ] map states collect-locs