]> gitweb.factorcode.org Git - factor.git/commitdiff
Refactoring low-level optimizer to support stack analysis pass
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 27 May 2009 00:31:19 +0000 (19:31 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 27 May 2009 00:31:19 +0000 (19:31 -0500)
21 files changed:
basis/compiler/cfg/alias-analysis/alias-analysis-tests.factor
basis/compiler/cfg/alias-analysis/alias-analysis.factor
basis/compiler/cfg/checker/checker.factor
basis/compiler/cfg/dce/dce.factor
basis/compiler/cfg/dominance/dominance.factor
basis/compiler/cfg/height/height.factor
basis/compiler/cfg/instructions/instructions.factor
basis/compiler/cfg/linearization/linearization.factor
basis/compiler/cfg/liveness/authors.txt [new file with mode: 0644]
basis/compiler/cfg/liveness/liveness.factor [new file with mode: 0644]
basis/compiler/cfg/optimizer/optimizer.factor
basis/compiler/cfg/predecessors/predecessors.factor
basis/compiler/cfg/rpo/rpo.factor
basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor
basis/compiler/cfg/stack-analysis/stack-analysis.factor
basis/compiler/cfg/useless-blocks/useless-blocks.factor
basis/compiler/cfg/value-numbering/expressions/expressions.factor
basis/compiler/cfg/value-numbering/value-numbering-tests.factor
basis/compiler/cfg/value-numbering/value-numbering.factor
basis/compiler/cfg/write-barrier/write-barrier-tests.factor
basis/compiler/cfg/write-barrier/write-barrier.factor

index 81359690dbbbd7680e58b555ce0fa3bbb4dcaa19..79165f2c96a3487c84c45bba83ead1d073c595a3 100644 (file)
@@ -1,56 +1 @@
-USING: compiler.cfg.instructions compiler.cfg.registers
-compiler.cfg.alias-analysis compiler.cfg.debugger
-cpu.architecture tools.test kernel ;
 IN: compiler.cfg.alias-analysis.tests
-
-[ ] [
-    {
-        T{ ##peek f V int-regs 2 D 1 f }
-        T{ ##box-alien f V int-regs 1 V int-regs 2 }
-        T{ ##slot-imm f V int-regs 3 V int-regs 1 0 3 }
-    } alias-analysis drop
-] unit-test
-
-[ ] [
-    {
-        T{ ##load-reference f V int-regs 1 "hello" }
-        T{ ##slot-imm f V int-regs 0 V int-regs 1 0 3 }
-    } alias-analysis drop
-] unit-test
-
-[
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##peek f V int-regs 2 D 2 f }
-        T{ ##replace f V int-regs 1 D 0 f }
-    }
-] [
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##peek f V int-regs 2 D 2 f }
-        T{ ##replace f V int-regs 2 D 0 f }
-        T{ ##replace f V int-regs 1 D 0 f }
-    } alias-analysis
-] unit-test
-
-[
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##peek f V int-regs 2 D 0 f }
-        T{ ##copy f V int-regs 3 V int-regs 2 f }
-        T{ ##copy f V int-regs 4 V int-regs 1 f }
-        T{ ##replace f V int-regs 3 D 0 f }
-        T{ ##replace f V int-regs 4 D 1 f }
-    }
-] [
-    {
-        T{ ##peek f V int-regs 1 D 1 f }
-        T{ ##peek f V int-regs 2 D 0 f }
-        T{ ##replace f V int-regs 1 D 0 f }
-        T{ ##replace f V int-regs 2 D 1 f }
-        T{ ##peek f V int-regs 3 D 1 f }
-        T{ ##peek f V int-regs 4 D 0 f }
-        T{ ##replace f V int-regs 3 D 0 f }
-        T{ ##replace f V int-regs 4 D 1 f }
-    } alias-analysis
-] unit-test
index ec8fe62dfbf05326078cef474c288f67beb4f639..3a153740d5eb9e95271c152d59c5d05432ea8d7f 100644 (file)
@@ -1,15 +1,13 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math namespaces assocs hashtables sequences arrays
 accessors vectors combinators sets classes compiler.cfg
 compiler.cfg.registers compiler.cfg.instructions
-compiler.cfg.copy-prop ;
+compiler.cfg.copy-prop compiler.cfg.rpo
+compiler.cfg.liveness ;
 IN: compiler.cfg.alias-analysis
 
-! Alias analysis -- assumes compiler.cfg.height has already run.
-!
-! We try to eliminate redundant slot and stack
-! traffic using some simple heuristics.
+! We try to eliminate redundant slot operations using some simple heuristics.
 ! 
 ! All heap-allocated objects which are loaded from the stack, or
 ! other object slots are pessimistically assumed to belong to
@@ -17,9 +15,6 @@ IN: compiler.cfg.alias-analysis
 !
 ! Freshly-allocated objects get their own alias class.
 !
-! The data and retain stack pointer registers are treated
-! uniformly, and each one gets its own alias class.
-! 
 ! Simple pseudo-C example showing load elimination:
 ! 
 ! int *x, *y, z: inputs
@@ -189,23 +184,19 @@ SYMBOL: constants
 GENERIC: insn-slot# ( insn -- slot#/f )
 GENERIC: insn-object ( insn -- vreg )
 
-M: ##peek insn-slot# loc>> n>> ;
-M: ##replace insn-slot# loc>> n>> ;
 M: ##slot insn-slot# slot>> constant ;
 M: ##slot-imm insn-slot# slot>> ;
 M: ##set-slot insn-slot# slot>> constant ;
 M: ##set-slot-imm insn-slot# slot>> ;
 M: ##alien-global insn-slot# [ library>> ] [ symbol>> ] bi 2array ;
 
-M: ##peek insn-object loc>> class ;
-M: ##replace insn-object loc>> class ;
 M: ##slot insn-object obj>> resolve ;
 M: ##slot-imm insn-object obj>> resolve ;
 M: ##set-slot insn-object obj>> resolve ;
 M: ##set-slot-imm insn-object obj>> resolve ;
 M: ##alien-global insn-object drop \ ##alien-global ;
 
-: init-alias-analysis ( -- )
+: init-alias-analysis ( basic-block -- )
     H{ } clone histories set
     H{ } clone vregs>acs set
     H{ } clone acs>vregs set
@@ -213,11 +204,10 @@ M: ##alien-global insn-object drop \ ##alien-global ;
     H{ } clone constants set
     H{ } clone copies set
 
+    live-in keys [ set-heap-ac ] each
+    
     0 ac-counter set
-    next-ac heap-ac set
-
-    ds-loc next-ac set-ac
-    rs-loc next-ac set-ac ;
+    next-ac heap-ac set ;
 
 GENERIC: analyze-aliases* ( insn -- insn' )
 
@@ -292,15 +282,6 @@ GENERIC: eliminate-dead-stores* ( insn -- insn' )
         ] unless
     ] when ;
 
-M: ##replace eliminate-dead-stores*
-    #! Writes to above the top of the stack can be pruned also.
-    #! This is sound since any such writes are not observable
-    #! after the basic block, and any reads of those locations
-    #! will have been converted to copies by analyze-slot,
-    #! and the final stack height of the basic block is set at
-    #! the beginning by compiler.cfg.stack.
-    dup loc>> n>> 0 < [ drop f ] [ (eliminate-dead-stores) ] if ;
-
 M: ##set-slot eliminate-dead-stores* (eliminate-dead-stores) ;
 
 M: ##set-slot-imm eliminate-dead-stores* (eliminate-dead-stores) ;
@@ -310,8 +291,13 @@ M: insn eliminate-dead-stores* ;
 : eliminate-dead-stores ( insns -- insns' )
     [ insn# set eliminate-dead-stores* ] map-index sift ;
 
-: alias-analysis ( insns -- insns' )
-    init-alias-analysis
-    analyze-aliases
-    compute-live-stores
-    eliminate-dead-stores ;
+: alias-analysis-step ( basic-block -- )
+    dup init-alias-analysis
+    [
+        analyze-aliases
+        compute-live-stores
+        eliminate-dead-stores
+    ] change-instructions drop ;
+
+: alias-analysis ( rpo -- )
+    [ alias-analysis-step ] each ;
\ No newline at end of file
index ac3d133fe6a44c605a7715beb607d29792e4dc6c..3a9d4a2b902976e2d7c9794029a4f810a0a2ac4c 100644 (file)
@@ -22,4 +22,4 @@ ERROR: last-insn-not-a-jump insn ;
     [ instructions>> check-basic-block ] each ;
 
 : check-cfg ( cfg -- )
-    entry>> reverse-post-order check-rpo ;
\ No newline at end of file
+    reverse-post-order check-rpo ;
\ No newline at end of file
index ed9b48f7c6fd1d11de0d11f1dc7b608368ac2ac8..5db760e861a18b5bad22a50a480984a755c682ed 100644 (file)
@@ -14,9 +14,9 @@ SYMBOL: live-vregs
     H{ } clone liveness-graph set
     H{ } clone live-vregs set ;
 
-GENERIC: compute-liveness ( insn -- )
+GENERIC: update-liveness-graph ( insn -- )
 
-M: ##flushable compute-liveness
+M: ##flushable update-liveness-graph
     [ uses-vregs ] [ dst>> ] bi liveness-graph get set-at ;
 
 : record-live ( vregs -- )
@@ -28,7 +28,7 @@ M: ##flushable compute-liveness
         ] if
     ] each ;
 
-M: insn compute-liveness uses-vregs record-live ;
+M: insn update-liveness-graph uses-vregs record-live ;
 
 GENERIC: live-insn? ( insn -- ? )
 
@@ -36,9 +36,8 @@ M: ##flushable live-insn? dst>> live-vregs get key? ;
 
 M: insn live-insn? drop t ;
 
-: eliminate-dead-code ( rpo -- rpo )
+: eliminate-dead-code ( rpo -- )
     init-dead-code
-    [ [ instructions>> [ compute-liveness ] each ] each ]
+    [ [ instructions>> [ update-liveness-graph ] each ] each ]
     [ [ [ [ live-insn? ] filter ] change-instructions drop ] each ]
-    [ ]
-    tri ;
\ No newline at end of file
+    bi ;
\ No newline at end of file
index 9d11fdf5b70498bb42948947008ecdb484ed866d..750a46ee6cf06dfaf7532afe23c074bfc3842626 100644 (file)
@@ -37,5 +37,5 @@ PRIVATE>
 
 : compute-dominance ( cfg -- cfg )
     H{ } clone idoms set
-    dup entry>> reverse-post-order
+    dup reverse-post-order
     unclip dup set-idom drop '[ _ iterate ] loop ;
\ No newline at end of file
index 9312f6f133a55495ee53c6709ef4a08676eda478..9c305442e5ba7f173cecdf15d5c527b87c5c0168 100644 (file)
@@ -1,7 +1,8 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors math namespaces sequences kernel fry
-compiler.cfg compiler.cfg.registers compiler.cfg.instructions ;
+compiler.cfg compiler.cfg.registers compiler.cfg.instructions
+compiler.cfg.rpo ;
 IN: compiler.cfg.height
 
 ! Combine multiple stack height changes into one at the
@@ -42,10 +43,15 @@ M: ##replace normalize-height* normalize-peek/replace ;
 
 M: insn normalize-height* ;
 
-: normalize-height ( insns -- insns' )
+: height-step ( insns -- insns' )
     0 ds-height set
     0 rs-height set
-    [ [ compute-heights ] each ]
-    [ [ [ normalize-height* ] map sift ] with-scope ] bi
-    ds-height get dup zero? [ drop ] [ f \ ##inc-d boa prefix ] if
-    rs-height get dup zero? [ drop ] [ f \ ##inc-r boa prefix ] if ;
+    [
+        [ [ compute-heights ] each ]
+        [ [ [ normalize-height* ] map sift ] with-scope ] bi
+        ds-height get dup zero? [ drop ] [ f \ ##inc-d boa prefix ] if
+        rs-height get dup zero? [ drop ] [ f \ ##inc-r boa prefix ] if
+    ] change-instructions drop ;
+
+: normalize-height ( rpo -- )
+    [ height-step ] each ;
index 6ebf064a946be396d9f8cfb04d3da7367033b513..650bcb57951362165f83f67b631250ec11a3be2f 100644 (file)
@@ -44,8 +44,8 @@ M: fixnum ##load-literal tag-fixnum ##load-immediate ;
 M: f ##load-literal drop \ f tag-number ##load-immediate ;
 M: object ##load-literal ##load-reference ;
 
-INSN: ##peek < ##read { loc loc } ;
-INSN: ##replace < ##write { loc loc } ;
+INSN: ##peek < ##flushable { loc loc } ;
+INSN: ##replace < ##effect { loc loc } ;
 INSN: ##inc-d { n integer } ;
 INSN: ##inc-r { n integer } ;
 
index 8ef3abda3956d06a26d3538519079acafa19bf56..9d80a2b28e90f8c67e2b7a837b01fc093de8da9b 100755 (executable)
@@ -75,6 +75,6 @@ M: ##compare-float-branch linearize-insn
     [ [ linearize-basic-block ] each ] { } make ;
 
 : build-mr ( cfg -- mr )
-    [ entry>> reverse-post-order linearize-basic-blocks ]
+    [ reverse-post-order linearize-basic-blocks ]
     [ word>> ] [ label>> ]
     tri <mr> ;
diff --git a/basis/compiler/cfg/liveness/authors.txt b/basis/compiler/cfg/liveness/authors.txt
new file mode 100644 (file)
index 0000000..d4f5d6b
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/compiler/cfg/liveness/liveness.factor b/basis/compiler/cfg/liveness/liveness.factor
new file mode 100644 (file)
index 0000000..66a584c
--- /dev/null
@@ -0,0 +1,55 @@
+! 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.rpo ;
+IN: compiler.cfg.liveness
+
+! This is a backward dataflow analysis. See http://en.wikipedia.org/wiki/Liveness_analysis
+
+! Assoc mapping basic blocks to sets of vregs
+SYMBOL: live-ins
+
+: live-in ( basic-block -- set ) live-ins get at ;
+
+! Assoc mapping basic blocks to sets of vregs
+SYMBOL: live-outs
+
+: live-out ( basic-block -- set ) live-outs get at ;
+
+SYMBOL: work-list
+
+: add-to-work-list ( basic-blocks -- )
+    work-list get '[ _ push-front ] each ;
+
+: map-unique ( seq quot -- assoc )
+    map concat unique ; inline
+
+: gen-set ( basic-block -- seq )
+    instructions>> [ uses-vregs ] map-unique ;
+
+: kill-set ( basic-block -- seq )
+    instructions>> [ defs-vregs ] map-unique ;
+
+: update-live-in ( basic-block -- changed? )
+    [
+        [ [ gen-set ] [ live-out ] bi assoc-union ]
+        [ kill-set ]
+        bi assoc-diff
+    ] keep live-ins get maybe-set-at ;
+
+: update-live-out ( basic-block -- changed? )
+    [ successors>> [ live-in ] map assoc-combine ] 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-liveness ( rpo -- )
+    <hashed-dlist> work-list set
+    H{ } clone live-ins set
+    H{ } clone live-outs set
+    <reversed> add-to-work-list
+    work-list get [ liveness-step ] slurp-deque ;
\ No newline at end of file
index 7887faeb613da9a37a129c4603af8b6885f073ac..41cd3c4b9098b3a23cd20619d5fe15d2bd2aef73 100644 (file)
@@ -1,29 +1,32 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences compiler.cfg.rpo
-compiler.cfg.instructions
+USING: kernel sequences accessors combinators
 compiler.cfg.predecessors
 compiler.cfg.useless-blocks
 compiler.cfg.height
+compiler.cfg.stack-analysis
 compiler.cfg.alias-analysis
 compiler.cfg.value-numbering
-compiler.cfg.dead-code
-compiler.cfg.write-barrier ;
+compiler.cfg.dce
+compiler.cfg.write-barrier
+compiler.cfg.liveness
+compiler.cfg.rpo ;
 IN: compiler.cfg.optimizer
 
-: trivial? ( insns -- ? )
-    dup length 2 = [ first ##call? ] [ drop f ] if ;
-
-: optimize-cfg ( cfg -- cfg' )
-    compute-predecessors
-    delete-useless-blocks
-    delete-useless-conditionals
+: optimize-cfg ( cfg -- cfg )
     [
-        dup trivial? [
-            normalize-height
-            alias-analysis
-            value-numbering
-            eliminate-dead-code
-            eliminate-write-barriers
-        ] unless
-    ] change-basic-blocks ;
+        [ 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 ;
index 01a2a771bc224131642ebf00e7a4a37e431588e1..9bc3a08f63dd965bc8f9f236b38ba48ddda4f560 100644 (file)
@@ -1,10 +1,10 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors sequences compiler.cfg.rpo ;
 IN: compiler.cfg.predecessors
 
-: (compute-predecessors) ( bb -- )
+: predecessors-step ( bb -- )
     dup successors>> [ predecessors>> push ] with each ;
 
-: compute-predecessors ( cfg -- cfg' )
-    dup [ (compute-predecessors) ] each-basic-block ;
+: compute-predecessors ( cfg -- )
+    [ predecessors-step ] each-basic-block ;
index bb4153da784d49374bfe7f80b5f5487af3d0f5d5..766373175cfd12659eaa7ad308804fda2680fba0 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors namespaces make math sequences sets
 assocs fry compiler.cfg compiler.cfg.instructions ;
@@ -7,29 +7,24 @@ IN: compiler.cfg.rpo
 SYMBOL: visited
 
 : post-order-traversal ( bb -- )
-    dup id>> visited get key? [ drop ] [
-        dup id>> visited get conjoin
+    dup visited get key? [ drop ] [
+        dup visited get conjoin
         [
             successors>> <reversed>
             [ post-order-traversal ] each
         ] [ , ] bi
     ] if ;
 
-: post-order ( bb -- blocks )
-    [ post-order-traversal ] { } make ;
+: post-order ( cfg -- blocks )
+    [ entry>> post-order-traversal ] { } make ;
 
 : number-blocks ( blocks -- )
     [ >>number drop ] each-index ;
 
-: reverse-post-order ( bb -- blocks )
+: reverse-post-order ( cfg -- blocks )
     H{ } clone visited [
         post-order <reversed> dup number-blocks
     ] with-variable ; inline
 
 : each-basic-block ( cfg quot -- )
-    [ entry>> reverse-post-order ] dip each ; inline
-
-: change-basic-blocks ( cfg quot -- cfg' )
-    [ '[ _ change-instructions drop ] each-basic-block ]
-    [ drop ]
-    2bi ; inline
+    [ reverse-post-order ] dip each ; inline
index c89a8b1cfd9e7d970ca3da28a831e86b5e8fd295..8c941f45393bc79d34aee2cc8b9911cb39924c27 100644 (file)
@@ -6,10 +6,6 @@ compiler.cfg.checker compiler.cfg.height compiler.cfg.rpo
 compiler.cfg.dce compiler.cfg.registers sets ;
 IN: compiler.cfg.stack-analysis.tests
 
-[ f ] [ 1 2 H{ { 2 1 } } maybe-set-at ] unit-test
-[ t ] [ 1 3 H{ { 2 1 } } clone maybe-set-at ] unit-test
-[ t ] [ 3 2 H{ { 2 1 } } clone maybe-set-at ] unit-test
-
 ! Fundamental invariant: a basic block should not load or store a value more than once
 : check-for-redundant-ops ( rpo -- )
     [
@@ -25,11 +21,12 @@ IN: compiler.cfg.stack-analysis.tests
 
 : test-stack-analysis ( quot -- mr )
     dup cfg? [ test-cfg first ] unless
-    compute-predecessors
-    entry>> reverse-post-order
-    optimize-stack
-    dup [ [ normalize-height ] change-instructions drop ] each
-    dup check-rpo dup check-for-redundant-ops ;
+    dup compute-predecessors
+    reverse-post-order
+    dup stack-analysis
+    dup normalize-height
+    dup check-rpo
+    dup check-for-redundant-ops ;
 
 [ ] [ [ ] test-stack-analysis drop ] unit-test
 
@@ -81,13 +78,13 @@ IN: compiler.cfg.stack-analysis.tests
 
 ! Make sure the replace stores a value with the right height
 [ ] [
-    [ [ . ] [ 2drop 1 ] if ] test-stack-analysis eliminate-dead-code linearize-basic-blocks
+    [ [ . ] [ 2drop 1 ] if ] test-stack-analysis dup eliminate-dead-code linearize-basic-blocks
     [ ##replace? ] filter [ length 1 assert= ] [ first loc>> D 0 assert= ] bi
 ] unit-test
 
 ! translate-loc was the wrong way round
 [ ] [
-    [ 1 2 rot ] test-stack-analysis eliminate-dead-code linearize-basic-blocks
+    [ 1 2 rot ] test-stack-analysis dup eliminate-dead-code linearize-basic-blocks
     [ [ ##load-immediate? ] count 2 assert= ]
     [ [ ##peek? ] count 1 assert= ]
     [ [ ##replace? ] count 3 assert= ]
@@ -95,7 +92,7 @@ IN: compiler.cfg.stack-analysis.tests
 ] unit-test
 
 [ ] [
-    [ 1 2 ? ] test-stack-analysis eliminate-dead-code linearize-basic-blocks
+    [ 1 2 ? ] test-stack-analysis dup eliminate-dead-code linearize-basic-blocks
     [ [ ##load-immediate? ] count 2 assert= ]
     [ [ ##peek? ] count 1 assert= ]
     [ [ ##replace? ] count 1 assert= ]
@@ -104,6 +101,6 @@ IN: compiler.cfg.stack-analysis.tests
 
 ! Sync before a back-edge, not after
 [ 1 ] [
-    [ 1000 [ ] times ] test-stack-analysis eliminate-dead-code linearize-basic-blocks
+    [ 1000 [ ] times ] test-stack-analysis dup eliminate-dead-code linearize-basic-blocks
     [ ##add-imm? ] count
 ] unit-test
\ No newline at end of file
index bce3064a9e0725b9bb0bf22d60bf4ce623a41598..6d602ede7601e1d752ae74d678cc14b4bd4e0161 100644 (file)
@@ -10,15 +10,15 @@ IN: compiler.cfg.stack-analysis
 
 ! If 'poisoned' is set, disregard height information. This is set if we don't have
 ! height change information for an instruction.
-TUPLE: state locs>vregs actual-locs>vregs changed-locs d-height r-height poisoned? ;
+TUPLE: state locs>vregs actual-locs>vregs changed-locs ds-height rs-height poisoned? ;
 
 : <state> ( -- state )
     state new
         H{ } clone >>locs>vregs
         H{ } clone >>actual-locs>vregs
         H{ } clone >>changed-locs
-        0 >>d-height
-        0 >>r-height ;
+        0 >>ds-height
+        0 >>rs-height ;
 
 M: state clone
     call-next-method
@@ -39,8 +39,8 @@ M: state clone
 
 GENERIC: height-for ( loc -- n )
 
-M: ds-loc height-for drop state get d-height>> ;
-M: rs-loc height-for drop state get r-height>> ;
+M: ds-loc height-for drop state get ds-height>> ;
+M: rs-loc height-for drop state get rs-height>> ;
 
 : (translate-loc) ( loc -- n height ) [ n>> ] [ height-for ] bi ; inline
 
@@ -105,11 +105,11 @@ M: sync-if-back-edge visit
     [ sync-state ] when
     , ;
 
-: adjust-d ( n -- ) state get [ + ] change-d-height drop ;
+: adjust-d ( n -- ) state get [ + ] change-ds-height drop ;
 
 M: ##inc-d visit [ , ] [ n>> adjust-d ] bi ;
 
-: adjust-r ( n -- ) state get [ + ] change-r-height drop ;
+: adjust-r ( n -- ) state get [ + ] change-rs-height drop ;
 
 M: ##inc-r visit [ , ] [ n>> adjust-r ] bi ;
 
@@ -198,8 +198,8 @@ ERROR: must-equal-failed seq ;
 
 : merge-heights ( state predecessors states -- state )
     nip
-    [ [ d-height>> ] map must-equal >>d-height ]
-    [ [ r-height>> ] map must-equal >>r-height ] bi ;
+    [ [ ds-height>> ] map must-equal >>ds-height ]
+    [ [ rs-height>> ] map must-equal >>rs-height ] bi ;
 
 : insert-peek ( predecessor loc -- vreg )
     ! XXX critical edges
@@ -300,10 +300,10 @@ ERROR: cannot-merge-poisoned states ;
         ] 2bi
     ] V{ } make >>instructions drop ;
 
-: optimize-stack ( rpo -- rpo )
+: stack-analysis ( rpo -- )
     [
         H{ } clone copies set
         H{ } clone state-in set
         H{ } clone state-out set
-        dup [ visit-block ] each
+        [ visit-block ] each
     ] with-scope ;
index f543aa4036d816c3216c049ccd00c0a0815a2946..b4999a8074396d6437083efe05fbce3b9b234cd0 100644 (file)
@@ -1,7 +1,7 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors sequences combinators classes vectors
-compiler.cfg compiler.cfg.rpo compiler.cfg.instructions ;
+compiler.cfg compiler.cfg.instructions compiler.cfg.rpo ;
 IN: compiler.cfg.useless-blocks
 
 : update-predecessor-for-delete ( bb -- )
@@ -30,8 +30,8 @@ IN: compiler.cfg.useless-blocks
         [ t ]
     } cond nip ;
 
-: delete-useless-blocks ( cfg -- cfg' )
-    dup [
+: delete-useless-blocks ( cfg -- )
+    [
         dup delete-basic-block? [ delete-basic-block ] [ drop ] if
     ] each-basic-block ;
 
@@ -49,7 +49,7 @@ IN: compiler.cfg.useless-blocks
     [ but-last f \ ##branch boa suffix ] change-instructions
     drop ;
 
-: delete-useless-conditionals ( cfg -- cfg' )
-    dup [
+: delete-useless-conditionals ( cfg -- )
+    [
         dup delete-conditional? [ delete-conditional ] [ drop ] if
     ] each-basic-block ;
index cc790c6c0a3725579447373309c2563dc6a6e75a..bf750231c7586893c6fd1f7bcb9288988539b4cb 100644 (file)
@@ -22,17 +22,17 @@ M: constant-expr equal?
         and
     ] [ 2drop f ] if ;
 
-SYMBOL: input-expr-counter
-
-: next-input-expr ( -- n )
-    input-expr-counter [ dup 1 + ] change ;
-
 ! Expressions whose values are inputs to the basic block. We
 ! can eliminate a second computation having the same 'n' as
 ! the first one; we can also eliminate input-exprs whose
 ! result is not used.
 TUPLE: input-expr < expr n ;
 
+SYMBOL: input-expr-counter
+
+: next-input-expr ( class -- expr )
+    input-expr-counter [ dup 1 + ] change input-expr boa ;
+
 : constant>vn ( constant -- vn ) <constant> expr>vn ; inline
 
 GENERIC: >expr ( insn -- expr )
@@ -80,7 +80,7 @@ M: ##compare-imm >expr compare-imm>expr ;
 
 M: ##compare-float >expr compare>expr ;
 
-M: ##flushable >expr class next-input-expr input-expr boa ;
+M: ##flushable >expr class next-input-expr ;
 
 : init-expressions ( -- )
     0 input-expr-counter set ;
index abd272081784564b405efe15ed95adc43ab528d0..11c0819027e3f8e9f5132cd6efa2dadbf16103a4 100644 (file)
@@ -2,7 +2,7 @@ IN: compiler.cfg.value-numbering.tests
 USING: compiler.cfg.value-numbering compiler.cfg.instructions
 compiler.cfg.registers compiler.cfg.debugger cpu.architecture
 tools.test kernel math combinators.short-circuit accessors
-sequences ;
+sequences compiler.cfg vectors arrays ;
 
 : trim-temps ( insns -- insns )
     [
@@ -13,6 +13,10 @@ sequences ;
         } 1|| [ f >>temp ] when
     ] map ;
 
+: test-value-numbering ( insns -- insns )
+    basic-block new swap >vector >>instructions
+    dup value-numbering-step instructions>> >array ;
+
 [
     {
         T{ ##peek f V int-regs 45 D 1 }
@@ -24,7 +28,7 @@ sequences ;
         T{ ##peek f V int-regs 45 D 1 }
         T{ ##copy f V int-regs 48 V int-regs 45 }
         T{ ##compare-imm-branch f V int-regs 48 7 cc/= }
-    } value-numbering
+    } test-value-numbering
 ] unit-test
 
 [
@@ -40,14 +44,14 @@ sequences ;
         T{ ##peek f V int-regs 3 D 0 }
         T{ ##slot-imm f V int-regs 4 V int-regs 3 1 3 }
         T{ ##replace f V int-regs 4 D 0 }
-    } value-numbering
+    } test-value-numbering
 ] unit-test
 
 [ t ] [
     {
         T{ ##peek f V int-regs 1 D 0 }
         T{ ##dispatch f V int-regs 1 V int-regs 2 0 }
-    } dup value-numbering =
+    } dup test-value-numbering =
 ] unit-test
 
 [ t ] [
@@ -60,7 +64,7 @@ sequences ;
         T{ ##alien-unsigned-1 f V int-regs 22 V int-regs 21 }
         T{ ##shl-imm f V int-regs 23 V int-regs 22 3 }
         T{ ##replace f V int-regs 23 D 0 }
-    } dup value-numbering =
+    } dup test-value-numbering =
 ] unit-test
 
 [
@@ -76,7 +80,7 @@ sequences ;
         T{ ##mul-imm f V int-regs 2 V int-regs 1 8 }
         T{ ##shr-imm f V int-regs 3 V int-regs 2 3 }
         T{ ##replace f V int-regs 3 D 0 }
-    } value-numbering
+    } test-value-numbering
 ] unit-test
 
 [
@@ -94,7 +98,7 @@ sequences ;
         T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc> }
         T{ ##compare-imm f V int-regs 6 V int-regs 4 5 cc/= }
         T{ ##replace f V int-regs 6 D 0 }
-    } value-numbering trim-temps
+    } test-value-numbering trim-temps
 ] unit-test
 
 [
@@ -112,7 +116,7 @@ sequences ;
         T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc<= }
         T{ ##compare-imm f V int-regs 6 V int-regs 4 5 cc= }
         T{ ##replace f V int-regs 6 D 0 }
-    } value-numbering trim-temps
+    } test-value-numbering trim-temps
 ] unit-test
 
 [
@@ -134,7 +138,7 @@ sequences ;
         T{ ##compare-float f V int-regs 12 V double-float-regs 10 V double-float-regs 11 cc< }
         T{ ##compare-imm f V int-regs 14 V int-regs 12 5 cc= }
         T{ ##replace f V int-regs 14 D 0 }
-    } value-numbering trim-temps
+    } test-value-numbering trim-temps
 ] unit-test
 
 [
@@ -150,5 +154,5 @@ sequences ;
         T{ ##peek f V int-regs 30 D -2 }
         T{ ##compare f V int-regs 33 V int-regs 29 V int-regs 30 cc<= }
         T{ ##compare-imm-branch f V int-regs 33 5 cc/= }
-    } value-numbering trim-temps
+    } test-value-numbering trim-temps
 ] unit-test
index d17b2a7e1f229638010b8f84e72086f01601659a..ac0c512bf883eaa4fe6df490f3178f2b034f7b96 100644 (file)
@@ -2,6 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces assocs biassocs classes kernel math accessors
 sorting sets sequences
+compiler.cfg.liveness
 compiler.cfg.value-numbering.graph
 compiler.cfg.value-numbering.expressions
 compiler.cfg.value-numbering.propagate
@@ -9,7 +10,14 @@ compiler.cfg.value-numbering.simplify
 compiler.cfg.value-numbering.rewrite ;
 IN: compiler.cfg.value-numbering
 
-: value-numbering ( insns -- insns' )
+: number-input-values ( basic-block -- )
+    live-in keys [ [ next-input-expr ] dip set-vn ] each ;
+
+: value-numbering-step ( basic-block -- )
     init-value-graph
     init-expressions
-    [ [ number-values ] [ rewrite propagate ] bi ] map ;
+    dup number-input-values
+    [ [ [ number-values ] [ rewrite propagate ] bi ] map ] change-instructions drop ;
+
+: value-numbering ( rpo -- )
+    [ value-numbering-step ] each ;
index 73748dbc37c33fa4d89f7f488b7e176bdbc6abe4..fb755399dca1ba5cea627d232ca18ca2ce5c87cf 100644 (file)
@@ -1,8 +1,12 @@
 USING: compiler.cfg.write-barrier compiler.cfg.instructions
 compiler.cfg.registers compiler.cfg.debugger cpu.architecture
-arrays tools.test ;
+arrays tools.test vectors compiler.cfg kernel accessors ;
 IN: compiler.cfg.write-barrier.tests
 
+: test-write-barrier ( insns -- insns )
+    basic-block new swap >vector >>instructions
+    dup write-barriers-step instructions>> >array ;
+
 [
     {
         T{ ##peek f V int-regs 4 D 0 f }
@@ -24,7 +28,7 @@ IN: compiler.cfg.write-barrier.tests
         T{ ##set-slot-imm f V int-regs 6 V int-regs 7 2 3 }
         T{ ##write-barrier f V int-regs 7 V int-regs 12 V int-regs 13 }
         T{ ##replace f V int-regs 7 D 0 }
-    } eliminate-write-barriers
+    } test-write-barrier
 ] unit-test
 
 [
@@ -42,7 +46,7 @@ IN: compiler.cfg.write-barrier.tests
         T{ ##peek f V int-regs 6 D -2 }
         T{ ##set-slot-imm f V int-regs 5 V int-regs 6 3 2 }
         T{ ##write-barrier f V int-regs 6 V int-regs 7 V int-regs 8 }
-    } eliminate-write-barriers
+    } test-write-barrier
 ] unit-test
 
 [
@@ -69,5 +73,5 @@ IN: compiler.cfg.write-barrier.tests
         T{ ##copy f V int-regs 29 V int-regs 19 }
         T{ ##set-slot-imm f V int-regs 28 V int-regs 29 4 2 }
         T{ ##write-barrier f V int-regs 29 V int-regs 30 V int-regs 3 }
-    } eliminate-write-barriers
+    } test-write-barrier
 ] unit-test
index 4a55cb3266474dffac2daed5ef6862f0212b0f6c..5a082966171f989beb757f06f4dac242bf18f6a5 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors namespaces assocs sets sequences locals
 compiler.cfg compiler.cfg.instructions compiler.cfg.copy-prop ;
@@ -35,8 +35,11 @@ M: ##set-slot-imm eliminate-write-barrier
 
 M: insn eliminate-write-barrier ;
 
-: eliminate-write-barriers ( insns -- insns' )
+: write-barriers-step ( basic-block -- )
     H{ } clone safe set
     H{ } clone mutated set
     H{ } clone copies set
-    [ eliminate-write-barrier ] map sift ;
+    [ [ eliminate-write-barrier ] map sift ] change-instructions drop ;
+
+: eliminate-write-barriers ( rpo -- )
+    [ write-barriers-step ] each ;