]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler.cfg.coalescing: more work done
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Mon, 27 Jul 2009 05:31:21 +0000 (00:31 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Mon, 27 Jul 2009 05:31:21 +0000 (00:31 -0500)
basis/compiler/cfg/coalescing/coalescing.factor
basis/compiler/cfg/coalescing/copies/copies.factor
basis/compiler/cfg/coalescing/forest/forest.factor
basis/compiler/cfg/coalescing/interference/interference.factor
basis/compiler/cfg/coalescing/process-blocks/process-blocks.factor
basis/compiler/cfg/coalescing/renaming/renaming.factor [new file with mode: 0644]
basis/compiler/cfg/coalescing/state/state.factor
basis/compiler/cfg/dominance/dominance.factor
basis/compiler/cfg/liveness/liveness.factor
basis/compiler/cfg/liveness/ssa/ssa.factor [new file with mode: 0644]

index 5a09b59749b6e25c36fcec7df7b82b963da232b6..05a67a230b98e498c256a85570931c6fe622eadc 100644 (file)
@@ -3,10 +3,13 @@
 USING: accessors assocs fry kernel locals math math.order
 sequences
 compiler.cfg.rpo
-compiler.cfg.instructions
+compiler.cfg.utilities
 compiler.cfg.dominance
+compiler.cfg.instructions
 compiler.cfg.coalescing.state
 compiler.cfg.coalescing.forest
+compiler.cfg.coalescing.copies
+compiler.cfg.coalescing.renaming
 compiler.cfg.coalescing.process-blocks ;
 IN: compiler.cfg.coalescing
 
@@ -18,14 +21,8 @@ IN: compiler.cfg.coalescing
 : process-blocks ( cfg -- )
     [ [ process-block ] if-has-phis ] each-basic-block ;
 
-: schedule-copies ( bb -- ) drop ;
-
 : break-interferences ( -- ) ;
 
-: insert-copies ( cfg -- ) drop ;
-
-: perform-renaming ( cfg -- ) drop ;
-
 : remove-phis-from-block ( bb -- )
     instructions>> [ ##phi? not ] filter-here ;
 
@@ -38,5 +35,5 @@ IN: compiler.cfg.coalescing
     dup process-blocks
     break-interferences
     dup insert-copies
-    dup perform-renaming
+    perform-renaming
     dup remove-phis ;
\ No newline at end of file
index c0a3ed892307eb7ad461ceff9f60e0a9a00a7208..7293bcc8025bb63c0596dacb294de5ab5fb03073 100644 (file)
@@ -1,8 +1,39 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: ;
+USING: accessors assocs combinators fry kernel namespaces sequences
+compiler.cfg.def-use compiler.cfg.dominance compiler.cfg.instructions
+compiler.cfg.renaming ;
 IN: compiler.cfg.coalescing.copies
 
-: schedule-copies ( bb -- ) drop ;
+SYMBOLS: stacks visited pushed ;
 
-: insert-copies ( cfg -- ) drop ;
+: compute-renaming ( insn -- assoc )
+    uses-vregs stacks get
+    '[ dup dup _ at [ nip last ] unless-empty ]
+    H{ } map>assoc ;
+
+: rename-operands ( bb -- )
+    instructions>> [
+        dup ##phi? [ drop ] [
+            dup compute-renaming renamings set
+            [ rename-insn-uses ] [ rename-insn-defs ] bi
+        ] if
+    ] each ;
+
+: schedule-copies ( bb -- )
+    ! FIXME
+    drop ;
+
+: pop-stacks ( -- )
+    pushed get stacks get '[ drop _ at pop* ] assoc-each ;
+
+: (insert-copies) ( bb -- )
+    H{ } clone pushed [
+        [ rename-operands ]
+        [ schedule-copies ]
+        [ dom-children [ (insert-copies) ] each ] tri
+        pop-stacks
+    ] with-variable ;
+
+: insert-copies ( cfg -- )
+    entry>> (insert-copies) ;
\ No newline at end of file
index f1f8334975f596eb43e2a080c750ee2387605b5c..fa0aa6e6d3ca73cebb768f841da70fbb99f0d655 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs fry kernel math math.order
 namespaces sequences sorting vectors compiler.cfg.def-use
-compiler.cfg.dominance ;
+compiler.cfg.dominance compiler.cfg.registers ;
 IN: compiler.cfg.coalescing.forest
 
 TUPLE: dom-forest-node vreg bb children ;
index 36dea6f0a0d49c91ac85620e29f91942f1b784c8..9fdf06bcb4344f89ba7df3113fbab50417ffefef 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs combinators combinators.short-circuit
-kernel math namespaces sequences compiler.cfg.def-use
-compiler.cfg.liveness ;
+kernel math namespaces sequences locals compiler.cfg.def-use
+compiler.cfg.liveness compiler.cfg.dominance ;
 IN: compiler.cfg.coalescing.interference
 
 ! Local interference testing. Requires live-out information
@@ -27,30 +27,30 @@ SYMBOLS: def-index kill-index ;
     ! If first register is killed after second one is defined, they interfere
     [ kill-index get at ] [ def-index get at ] bi* >= ;
 
-: interferes-same-block? ( vreg1 vreg2 -- ? )
+: interferes-same-block? ( vreg1 vreg2 bb1 bb2 -- ? )
     ! If both are defined in the same basic block, they interfere if their
     ! local live ranges intersect.
+    drop compute-local-live-ranges
     { [ kill-after-def? ] [ swap kill-after-def? ] } 2|| ;
 
-: interferes-first-dominates? ( vreg1 vreg2 -- ? )
+: interferes-first-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
     ! If vreg1 dominates vreg2, then they interfere if vreg2's definition
     ! occurs before vreg1 is killed.
+    nip compute-local-live-ranges
     kill-after-def? ;
 
-: interferes-second-dominates? ( vreg1 vreg2 -- ? )
+: interferes-second-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
     ! If vreg2 dominates vreg1, then they interfere if vreg1's definition
     ! occurs before vreg2 is killed.
+    drop compute-local-live-ranges
     swap kill-after-def? ;
 
 PRIVATE>
 
-SYMBOLS: +same-block+ +first-dominates+ +second-dominates+ ;
-
-: interferes? ( vreg1 vreg2 bb mode -- ? )
-    ! local interference test - mode is one of the above symbols
-    [ compute-local-live-ranges ] dip
-    {
-        { +same-block+ [ interferes-same-block? ] }
-        { +first-dominates+ [ interferes-first-dominates? ] }
-        { +second-dominates+ [ interferes-second-dominates? ] }
-    } case ;
\ No newline at end of file
+: interferes? ( vreg1 vreg2 -- ? )
+    2dup [ def-of ] bi@ {
+        { [ 2dup eq? ] [ interferes-same-block? ] }
+        { [ 2dup dominates? ] [ interferes-first-dominates? ] }
+        { [ 2dup swap dominates? ] [ interferes-second-dominates? ] }
+        [ 2drop 2drop f ]
+    } cond ;
index 6e73bb5e2fb49c26634bb40b93bf9e12aad80e43..005c71f3574277a6b3e6d27a9aa91d54d0464d4c 100644 (file)
@@ -12,6 +12,11 @@ compiler.cfg.coalescing.forest
 compiler.cfg.coalescing.interference ;
 IN: compiler.cfg.coalescing.process-blocks
 
+! phi-union maps a vreg to the predecessor block
+! that carries it to the phi node's block
+
+! unioned-blocks is a set of bb's which defined
+! the source vregs above
 SYMBOLS: phi-union unioned-blocks ;
 
 :: operand-live-into-phi-node's-block? ( bb src dst -- ? )
@@ -46,7 +51,7 @@ SYMBOLS: phi-union unioned-blocks ;
     src used-by-another get push ;
 
 :: add-to-renaming-set ( bb src dst -- )
-    src phi-union get conjoin
+    bb src phi-union get set-at
     src def-of unioned-blocks get conjoin ;
 
 : process-phi-operand ( bb src dst -- )
@@ -101,12 +106,22 @@ SYMBOLS: visited work-list ;
     dup children>> [ process-df-child ] with with map
     [ ] any? [ work-list get pop-back* ] unless ;
 
+: process-df-nodes ( ##phi work-list -- )
+    dup deque-empty? [ 2drop ] [
+        [ peek-back process-df-node ]
+        [ process-df-nodes ]
+        2bi
+    ] if ;
+
 : process-phi-union ( ##phi dom-forest -- )
     H{ } clone visited set
     <dlist> [ push-all-front ] keep
-    [ work-list set ] [ [ process-df-node ] with slurp-deque ] bi ;
+    [ work-list set ] [ process-df-nodes ] bi ;
 
 :: add-local-interferences ( bb ##phi -- )
+    ! bb contains the phi node. If the input is defined in the same
+    ! block as the phi node, we have to check for interference.
+    ! This can only happen if the value is carried by a back edge.
     phi-union get [
         drop dup def-of bb eq?
         [ ##phi dst>> 2array , ] [ drop ] if
@@ -114,7 +129,7 @@ SYMBOLS: visited work-list ;
 
 : compute-local-interferences ( bb ##phi -- pairs )
     [
-        [ phi-union get compute-dom-forest process-phi-union drop ]
+        [ phi-union get keys compute-dom-forest process-phi-union drop ]
         [ add-local-interferences ]
         2bi
     ] { } make ;
@@ -124,25 +139,10 @@ SYMBOLS: visited work-list ;
         src src' eq? [ bb src ##phi dst>> insert-copy ] when
     ] assoc-each ;
 
-:: same-block ( ##phi vreg1 vreg2 bb1 bb2 -- )
-    vreg1 vreg2 bb1 +same-block+ interferes?
-    [ ##phi vreg1 insert-copies-for-interference ] when ;
-
-:: first-dominates ( ##phi vreg1 vreg2 bb1 bb2 -- )
-    vreg1 vreg2 bb2 +first-dominates+ interferes?
-    [ ##phi vreg1 insert-copies-for-interference ] when ;
-
-:: second-dominates ( ##phi vreg1 vreg2 bb1 bb2 -- )
-    vreg1 vreg2 bb1 +second-dominates+ interferes?
-    [ ##phi vreg1 insert-copies-for-interference ] when ;
-
 : process-local-interferences ( ##phi pairs -- )
     [
-        first2 2dup [ def-of ] bi@ {
-            { [ 2dup eq? ] [ same-block ] }
-            { [ 2dup dominates? ] [ first-dominates ] }
-            [ second-dominates ]
-        } cond
+        first2 2dup interferes?
+        [ drop insert-copies-for-interference ] [ 3drop ] if
     ] with each ;
 
 : add-renaming-set ( ##phi -- )
@@ -150,11 +150,12 @@ SYMBOLS: visited work-list ;
     phi-union get [ drop processed-name ] assoc-each ;
 
 :: process-phi ( bb ##phi -- )
-    H{ } phi-union set
-    H{ } unioned-blocks set
+    H{ } clone phi-union set
+    H{ } clone unioned-blocks set
     ##phi inputs>> ##phi dst>> '[ _ process-phi-operand ] assoc-each
     ##phi bb ##phi compute-local-interferences process-local-interferences
     ##phi add-renaming-set ;
 
 : process-block ( bb -- )
-    dup [ dup ##phi? [ process-phi t ] [ 2drop f ] if ] with all? drop ;
+    dup instructions>>
+    [ dup ##phi? [ process-phi t ] [ 2drop f ] if ] with all? drop ;
diff --git a/basis/compiler/cfg/coalescing/renaming/renaming.factor b/basis/compiler/cfg/coalescing/renaming/renaming.factor
new file mode 100644 (file)
index 0000000..3b26c09
--- /dev/null
@@ -0,0 +1,10 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel ;
+IN: compiler.cfg.coalescing.renaming
+
+: perform-renaming ( -- )
+    renaming-sets get [
+        ! XXX
+        2drop
+    ] assoc-each ;
index b2c2f59e4583011dfe5528cf20d975d176943d68..6174945ccb2d0487f3c2a659563949490602630d 100644 (file)
@@ -6,6 +6,7 @@ IN: compiler.cfg.coalescing.state
 SYMBOLS: processed-names waiting used-by-another renaming-sets ;
 
 : init-coalescing ( -- )
+    H{ } clone renaming-sets set
     H{ } clone processed-names set
     H{ } clone waiting set
     V{ } clone used-by-another set ;
index 6a73b349deb44150fa382f4e145628d1893f9701..6eeeacd6f1703adebdb6f613dc67f4cc3deda1a6 100644 (file)
@@ -118,10 +118,14 @@ PRIVATE>
 
 SYMBOLS: preorder maxpreorder ;
 
+PRIVATE>
+
 : pre-of ( bb -- n ) [ preorder get at ] [ -1/0. ] if* ;
 
 : maxpre-of ( bb -- n ) [ maxpreorder get at ] [ 1/0. ] if* ;
 
+<PRIVATE
+
 : (compute-dfs) ( n bb -- n )
     [ 1 + ] dip
     [ dupd preorder get set-at ]
index c1793842a2ad06b74020503080616dbfa875551f..30b145332f22f49608717d6af7fc9bd1a1c0d79c 100644 (file)
@@ -10,14 +10,16 @@ IN: compiler.cfg.liveness
 
 BACKWARD-ANALYSIS: live
 
+GENERIC: insn-liveness ( live-set insn -- )
+
 : transfer-liveness ( live-set instructions -- live-set' )
     [ clone ] [ <reversed> ] bi* [
-        [ uses-vregs [ over conjoin ] each ]
+        [ dup ##phi? [ drop ] [ uses-vregs [ over conjoin ] each ] if ]
         [ defs-vregs [ over delete-at ] each ] bi
     ] each ;
 
 : local-live-in ( instructions -- live-set )
-    [ ##phi? not ] filter [ H{ } ] dip transfer-liveness keys ;
+    [ H{ } ] dip transfer-liveness keys ;
 
 M: live-analysis transfer-set
     drop instructions>> transfer-liveness ;
diff --git a/basis/compiler/cfg/liveness/ssa/ssa.factor b/basis/compiler/cfg/liveness/ssa/ssa.factor
new file mode 100644 (file)
index 0000000..9fa22d2
--- /dev/null
@@ -0,0 +1,57 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel namespaces deques accessors sets sequences assocs fry
+hashtables dlists compiler.cfg.def-use compiler.cfg.instructions
+compiler.cfg.rpo compiler.cfg.liveness ;
+IN: compiler.cfg.liveness.ssa
+
+! TODO: merge with compiler.cfg.liveness
+
+! Assoc mapping basic blocks to sequences of sets of vregs; each sequence
+! is in conrrespondence with a predecessor
+SYMBOL: phi-live-ins
+
+: phi-live-in ( predecessor basic-block -- set ) phi-live-ins get at at ;
+
+SYMBOL: work-list
+
+: add-to-work-list ( basic-blocks -- )
+    work-list get '[ _ push-front ] each ;
+
+: compute-live-in ( basic-block -- live-in )
+    [ live-out ] keep instructions>> transfer-liveness ;
+
+: compute-phi-live-in ( basic-block -- phi-live-in )
+    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 ]
+    [ [ compute-phi-live-in ] keep phi-live-ins get maybe-set-at ]
+    bi and ; 
+
+: compute-live-out ( basic-block -- live-out )
+    [ successors>> [ live-in ] map ]
+    [ dup successors>> [ phi-live-in ] with map ] bi
+    append assoc-combine ;
+
+: update-live-out ( basic-block -- changed? )
+    [ compute-live-out ] keep
+    live-outs get maybe-set-at ;
+
+: liveness-step ( basic-block -- )
+    dup update-live-out [
+        dup update-live-in
+        [ predecessors>> add-to-work-list ] [ drop ] if
+    ] [ drop ] if ;
+
+: compute-ssa-live-sets ( cfg -- cfg' )
+    <hashed-dlist> work-list set
+    H{ } clone live-ins set
+    H{ } clone phi-live-ins set
+    H{ } clone live-outs set
+    dup post-order add-to-work-list
+    work-list get [ liveness-step ] slurp-deque ;