diff --git a/basis/compiler/cfg/dominance/dominance-tests.factor b/basis/compiler/cfg/dominance/dominance-tests.factor index 3da98a5e87..07bcd7bc84 100644 --- a/basis/compiler/cfg/dominance/dominance-tests.factor +++ b/basis/compiler/cfg/dominance/dominance-tests.factor @@ -6,9 +6,7 @@ compiler.cfg.predecessors ; : test-dominance ( -- ) cfg new 0 get >>entry compute-predecessors - dup compute-dominance - dup compute-dom-frontiers - compute-dfs ; + compute-dominance ; ! Example with no back edges V{ } 0 test-bb @@ -35,11 +33,6 @@ V{ } 5 test-bb [ t ] [ 0 get dom-children 1 get 2 get 4 get 3array set= ] unit-test -[ { 4 } ] [ 1 get dom-frontier [ number>> ] map ] unit-test -[ { 4 } ] [ 2 get dom-frontier [ number>> ] map ] unit-test -[ { } ] [ 0 get dom-frontier ] unit-test -[ { } ] [ 4 get dom-frontier ] unit-test - [ t ] [ 0 get 3 get dominates? ] unit-test [ f ] [ 3 get 4 get dominates? ] unit-test [ f ] [ 1 get 4 get dominates? ] unit-test @@ -81,25 +74,3 @@ V{ } 5 test-bb [ ] [ test-dominance ] unit-test [ t ] [ 0 5 [a,b] [ get dom-parent 0 get eq? ] all? ] unit-test - -V{ } 0 test-bb -V{ } 1 test-bb -V{ } 2 test-bb -V{ } 3 test-bb -V{ } 4 test-bb -V{ } 5 test-bb -V{ } 6 test-bb - -0 get 1 get 5 get V{ } 2sequence >>successors drop -1 get 2 get 3 get V{ } 2sequence >>successors drop -2 get 4 get 1vector >>successors drop -3 get 4 get 1vector >>successors drop -4 get 6 get 1vector >>successors drop -5 get 6 get 1vector >>successors drop - -[ ] [ test-dominance ] unit-test - -[ t ] [ - 2 get 3 get 2array iterated-dom-frontier - 4 get 6 get 2array set= -] unit-test \ No newline at end of file diff --git a/basis/compiler/cfg/dominance/dominance.factor b/basis/compiler/cfg/dominance/dominance.factor index ebd3a981d7..325bed74ff 100644 --- a/basis/compiler/cfg/dominance/dominance.factor +++ b/basis/compiler/cfg/dominance/dominance.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs combinators sets math fry kernel math.order -dlists deques namespaces sequences sorting compiler.cfg.rpo ; +dlists deques vectors namespaces sequences sorting locals +compiler.cfg.rpo ; IN: compiler.cfg.dominance ! Reference: @@ -60,60 +61,6 @@ PRIVATE> [ '[ 2dup eq? [ 2drop ] [ _ push-at ] if ] assoc-each ] keep dom-childrens set ; -PRIVATE> - -: compute-dominance ( cfg -- ) - compute-dom-parents compute-dom-children ; - - DF(bb) -SYMBOL: dom-frontiers - -: compute-dom-frontier ( bb pred -- ) - 2dup [ dom-parent ] dip eq? [ 2drop ] [ - [ dom-frontiers get conjoin-at ] - [ dom-parent compute-dom-frontier ] 2bi - ] if ; - -PRIVATE> - -: dom-frontier ( bb -- set ) dom-frontiers get at keys ; - -: compute-dom-frontiers ( cfg -- ) - H{ } clone dom-frontiers set - [ - dup predecessors>> dup length 2 >= [ - [ compute-dom-frontier ] with each - ] [ 2drop ] if - ] each-basic-block ; - - - -: iterated-dom-frontier ( bbs -- bbs' ) - [ - work-list set - H{ } clone visited set - [ add-to-work-list ] each - work-list get [ iterated-dom-frontier-step ] slurp-deque - visited get keys - ] with-scope ; - - @@ -131,13 +78,25 @@ PRIVATE> [ dupd maxpreorder get set-at ] tri ; -PRIVATE> - : compute-dfs ( cfg -- ) H{ } clone preorder set H{ } clone maxpreorder set [ 0 ] dip entry>> (compute-dfs) drop ; +PRIVATE> + +: compute-dominance ( cfg -- ) + [ compute-dom-parents compute-dom-children ] [ compute-dfs ] bi ; + : dominates? ( bb1 bb2 -- ? ) - ! Requires DFS to be computed - swap [ pre-of ] [ [ pre-of ] [ maxpre-of ] bi ] bi* between? ; \ No newline at end of file + swap [ pre-of ] [ [ pre-of ] [ maxpre-of ] bi ] bi* between? ; + +:: breadth-first-order ( cfg -- bfo ) + :> work-list + cfg post-order length :> accum + cfg entry>> work-list push-front + work-list [ + [ accum push ] + [ dom-children work-list push-all-front ] bi + ] slurp-deque + accum ; \ No newline at end of file diff --git a/basis/compiler/cfg/ssa/construction/construction.factor b/basis/compiler/cfg/ssa/construction/construction.factor index 23bed8bce0..3f131f4782 100644 --- a/basis/compiler/cfg/ssa/construction/construction.factor +++ b/basis/compiler/cfg/ssa/construction/construction.factor @@ -9,7 +9,8 @@ compiler.cfg.renaming compiler.cfg.liveness compiler.cfg.registers compiler.cfg.dominance -compiler.cfg.instructions ; +compiler.cfg.instructions +compiler.cfg.ssa.construction.tdmsc ; IN: compiler.cfg.ssa.construction ! SSA construction. Predecessors must be computed first. @@ -34,9 +35,9 @@ SYMBOL: inserting-phi-nodes : compute-phi-nodes-for ( vreg bbs -- ) dup length 2 >= [ - iterated-dom-frontier [ + [ insert-phi-node-later - ] with each + ] with merge-set-each ] [ 2drop ] if ; : compute-phi-nodes ( -- ) @@ -113,7 +114,7 @@ PRIVATE> [ ] [ compute-live-sets ] [ compute-dominance ] - [ compute-dom-frontiers ] + [ compute-merge-sets ] [ compute-defs compute-phi-nodes insert-phi-nodes ] [ rename ] } cleave ; \ No newline at end of file diff --git a/basis/compiler/cfg/ssa/construction/tdmsc/tdmsc-tests.factor b/basis/compiler/cfg/ssa/construction/tdmsc/tdmsc-tests.factor new file mode 100644 index 0000000000..7691d0e6ce --- /dev/null +++ b/basis/compiler/cfg/ssa/construction/tdmsc/tdmsc-tests.factor @@ -0,0 +1,75 @@ +USING: accessors arrays compiler.cfg compiler.cfg.debugger +compiler.cfg.dominance compiler.cfg.predecessors +compiler.cfg.ssa.construction.tdmsc kernel namespaces sequences +tools.test vectors sets ; +IN: compiler.cfg.ssa.construction.tdmsc.tests + +: test-tdmsc ( -- ) + cfg new 0 get >>entry + compute-predecessors + dup compute-dominance + compute-merge-sets ; + +V{ } 0 test-bb +V{ } 1 test-bb +V{ } 2 test-bb +V{ } 3 test-bb +V{ } 4 test-bb +V{ } 5 test-bb + +0 get 1 get 2 get V{ } 2sequence >>successors drop +1 get 3 get 1vector >>successors drop +2 get 4 get 1vector >>successors drop +3 get 4 get 1vector >>successors drop +4 get 5 get 1vector >>successors drop + +[ ] [ test-tdmsc ] unit-test + +[ V{ 4 } ] [ 1 get 1array merge-set [ number>> ] map ] unit-test +[ V{ 4 } ] [ 2 get 1array merge-set [ number>> ] map ] unit-test +[ V{ } ] [ 0 get 1array merge-set ] unit-test +[ V{ } ] [ 4 get 1array merge-set ] unit-test + +V{ } 0 test-bb +V{ } 1 test-bb +V{ } 2 test-bb +V{ } 3 test-bb +V{ } 4 test-bb +V{ } 5 test-bb +V{ } 6 test-bb + +0 get 1 get 5 get V{ } 2sequence >>successors drop +1 get 2 get 3 get V{ } 2sequence >>successors drop +2 get 4 get 1vector >>successors drop +3 get 4 get 1vector >>successors drop +4 get 6 get 1vector >>successors drop +5 get 6 get 1vector >>successors drop + +[ ] [ test-tdmsc ] unit-test + +[ t ] [ + 2 get 3 get 2array merge-set + 4 get 6 get 2array set= +] unit-test + +V{ } 0 test-bb +V{ } 1 test-bb +V{ } 2 test-bb +V{ } 3 test-bb +V{ } 4 test-bb +V{ } 5 test-bb +V{ } 6 test-bb +V{ } 7 test-bb + +0 get 1 get 1vector >>successors drop +1 get 2 get 1vector >>successors drop +2 get 3 get 6 get V{ } 2sequence >>successors drop +3 get 4 get 1vector >>successors drop +6 get 7 get 1vector >>successors drop +4 get 5 get 1vector >>successors drop +5 get 2 get 1vector >>successors drop + +[ ] [ test-tdmsc ] unit-test + +[ V{ 2 } ] [ { 2 3 4 5 } [ get ] map merge-set [ number>> ] map ] unit-test +[ V{ } ] [ { 0 1 6 7 } [ get ] map merge-set ] unit-test \ No newline at end of file diff --git a/basis/compiler/cfg/ssa/construction/tdmsc/tdmsc.factor b/basis/compiler/cfg/ssa/construction/tdmsc/tdmsc.factor new file mode 100644 index 0000000000..1c1abefe1b --- /dev/null +++ b/basis/compiler/cfg/ssa/construction/tdmsc/tdmsc.factor @@ -0,0 +1,109 @@ +! Copyright (C) 2009 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays assocs bit-arrays bit-sets fry +hashtables hints kernel locals math namespaces sequences sets +compiler.cfg compiler.cfg.dominance compiler.cfg.rpo ; +IN: compiler.cfg.ssa.construction.tdmsc + +! TDMSC-I algorithm from "A Practical and Fast Iterative Algorithm for +! Phi-Function Computation Using DJ Graphs" + +! http://portal.acm.org/citation.cfm?id=1065887.1065890 + + ] H{ } map>assoc merge-sets set ; + +: compute-levels ( cfg -- ) + 0 over entry>> associate [ + '[ + _ [ [ dom-parent ] dip at 1 + ] 2keep set-at + ] each-basic-block + ] keep levels set ; + +: j-edge? ( from to -- ? ) + 2dup eq? [ 2drop f ] [ dominates? not ] if ; + +: level ( bb -- n ) levels get at ; inline + +: set-bit ( bit-array n -- ) + [ t ] 2dip swap set-nth ; + +: update-merge-set ( tmp to -- ) + [ merge-sets get ] dip + '[ + _ + [ merge-sets get at bit-set-union ] + [ dupd number>> set-bit ] + bi + ] change-at ; + +:: walk ( tmp to lnode -- lnode ) + tmp level to level >= [ + tmp to update-merge-set + tmp dom-parent to tmp walk + ] [ lnode ] if ; + +: each-incoming-j-edge ( bb quot: ( from to -- ) -- ) + [ [ predecessors>> ] keep ] dip + '[ _ 2dup j-edge? _ [ 2drop ] if ] each ; inline + +: visited? ( pair -- ? ) visited get key? ; + +: consistent? ( snode lnode -- ? ) + [ merge-sets get at ] bi@ swap bit-set-subset? ; + +: (process-edge) ( from to -- ) + f walk [ + 2dup 2array visited? [ + consistent? [ again? on ] unless + ] [ 2drop ] if + ] each-incoming-j-edge ; + +: process-edge ( from to -- ) + 2dup 2array dup visited? [ 3drop ] [ + visited get conjoin + (process-edge) + ] if ; + +: process-block ( bb -- ) + [ process-edge ] each-incoming-j-edge ; + +: compute-merge-set-step ( bfo -- ) + visited get clear-assoc + [ process-block ] each ; + +: compute-merge-set-loop ( cfg -- ) + breadth-first-order + '[ again? off _ compute-merge-set-step again? get ] + loop ; + +: (merge-set) ( bbs -- flags rpo ) + merge-sets get '[ _ at ] [ bit-set-union ] map-reduce + cfg get reverse-post-order ; inline + +: filter-by ( flags seq -- seq' ) + [ drop ] pusher [ 2each ] dip ; + +HINTS: filter-by { bit-array object } ; + +PRIVATE> + +: compute-merge-sets ( cfg -- ) + dup cfg set + H{ } clone visited set + [ compute-levels ] + [ init-merge-sets ] + [ compute-merge-set-loop ] + tri ; + +: merge-set-each ( bbs quot: ( bb -- ) -- ) + [ (merge-set) ] dip '[ + swap _ [ drop ] if + ] 2each ; inline + +: merge-set ( bbs -- bbs' ) + (merge-set) filter-by ; \ No newline at end of file diff --git a/basis/compiler/cfg/ssa/destruction/destruction.factor b/basis/compiler/cfg/ssa/destruction/destruction.factor index 2d0cd26798..00f461d6f2 100644 --- a/basis/compiler/cfg/ssa/destruction/destruction.factor +++ b/basis/compiler/cfg/ssa/destruction/destruction.factor @@ -54,7 +54,6 @@ SYMBOL: seen dup split-critical-edges dup compute-def-use dup compute-dominance - dup compute-dfs dup compute-live-ranges dup process-blocks break-interferences diff --git a/basis/compiler/cfg/ssa/destruction/forest/forest-tests.factor b/basis/compiler/cfg/ssa/destruction/forest/forest-tests.factor index a74947e5df..64c04b79f2 100644 --- a/basis/compiler/cfg/ssa/destruction/forest/forest-tests.factor +++ b/basis/compiler/cfg/ssa/destruction/forest/forest-tests.factor @@ -31,8 +31,7 @@ V{ T{ ##peek f V int-regs 6 D 0 } } clone 6 test-bb cfg new 0 get >>entry compute-predecessors dup compute-dominance - dup compute-def-use - compute-dfs + compute-def-use compute-dom-forest clean-up-forest ; diff --git a/basis/compiler/cfg/ssa/destruction/forest/forest.factor b/basis/compiler/cfg/ssa/destruction/forest/forest.factor index fa0aa6e6d3..8226e2787b 100644 --- a/basis/compiler/cfg/ssa/destruction/forest/forest.factor +++ b/basis/compiler/cfg/ssa/destruction/forest/forest.factor @@ -3,7 +3,7 @@ USING: accessors assocs fry kernel math math.order namespaces sequences sorting vectors compiler.cfg.def-use compiler.cfg.dominance compiler.cfg.registers ; -IN: compiler.cfg.coalescing.forest +IN: compiler.cfg.ssa.destruction.forest TUPLE: dom-forest-node vreg bb children ; @@ -31,7 +31,6 @@ TUPLE: dom-forest-node vreg bb children ; PRIVATE> : compute-dom-forest ( vregs -- forest ) - ! compute-dfs must be called on the CFG first [ 1vector [ sort-vregs-by-bb ] dip