]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler.cfg: new system to track when results of analyses need to be recomputed...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 9 Aug 2009 01:02:56 +0000 (20:02 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 9 Aug 2009 01:02:56 +0000 (20:02 -0500)
48 files changed:
basis/compiler/cfg/block-joining/block-joining.factor
basis/compiler/cfg/branch-splitting/branch-splitting-tests.factor
basis/compiler/cfg/branch-splitting/branch-splitting.factor
basis/compiler/cfg/builder/builder-tests.factor
basis/compiler/cfg/cfg.factor
basis/compiler/cfg/copy-prop/copy-prop.factor
basis/compiler/cfg/dataflow-analysis/dataflow-analysis.factor
basis/compiler/cfg/dce/dce.factor
basis/compiler/cfg/debugger/debugger.factor
basis/compiler/cfg/dominance/dominance-tests.factor
basis/compiler/cfg/dominance/dominance.factor
basis/compiler/cfg/empty-blocks/empty-blocks.factor
basis/compiler/cfg/gc-checks/gc-checks-tests.factor
basis/compiler/cfg/linear-scan/assignment/assignment.factor
basis/compiler/cfg/linear-scan/linear-scan-tests.factor
basis/compiler/cfg/linear-scan/linear-scan.factor
basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor
basis/compiler/cfg/linear-scan/numbering/numbering.factor
basis/compiler/cfg/linear-scan/resolve/resolve.factor
basis/compiler/cfg/linearization/linearization.factor
basis/compiler/cfg/linearization/order/order.factor
basis/compiler/cfg/liveness/liveness-tests.factor
basis/compiler/cfg/liveness/ssa/ssa.factor
basis/compiler/cfg/loop-detection/loop-detection-tests.factor
basis/compiler/cfg/loop-detection/loop-detection.factor
basis/compiler/cfg/mr/mr.factor
basis/compiler/cfg/optimizer/optimizer.factor
basis/compiler/cfg/predecessors/predecessors.factor
basis/compiler/cfg/representations/representations.factor
basis/compiler/cfg/rpo/rpo.factor
basis/compiler/cfg/ssa/construction/construction-tests.factor
basis/compiler/cfg/ssa/construction/construction.factor
basis/compiler/cfg/ssa/construction/tdmsc/tdmsc-tests.factor
basis/compiler/cfg/ssa/construction/tdmsc/tdmsc.factor
basis/compiler/cfg/ssa/destruction/destruction.factor
basis/compiler/cfg/ssa/interference/interference-tests.factor
basis/compiler/cfg/ssa/interference/live-ranges/live-ranges.factor
basis/compiler/cfg/ssa/liveness/liveness-tests.factor
basis/compiler/cfg/stacks/finalize/finalize.factor
basis/compiler/cfg/stacks/stacks.factor
basis/compiler/cfg/stacks/uninitialized/uninitialized-tests.factor
basis/compiler/cfg/tco/tco.factor
basis/compiler/cfg/useless-conditionals/useless-conditionals.factor
basis/compiler/cfg/value-numbering/value-numbering-tests.factor
basis/compiler/cfg/value-numbering/value-numbering.factor
basis/compiler/compiler.factor
basis/compiler/tests/low-level-ir.factor
extra/compiler/graphviz/graphviz.factor

index 08c43f203ccd451876f411d07045d336bc5f51db..60528a61bbdf1f32ba621cd670988bed14c798f7 100644 (file)
@@ -2,12 +2,12 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors combinators.short-circuit kernel sequences math
 compiler.utilities compiler.cfg compiler.cfg.instructions compiler.cfg.rpo
-compiler.cfg.utilities ;
+compiler.cfg.predecessors compiler.cfg.utilities ;
 IN: compiler.cfg.block-joining
 
 ! Joining blocks that are not calls and are connected by a single CFG edge.
-! Predecessors must be recomputed after this. Also this pass does not
-! update ##phi nodes and should therefore only run before stack analysis.
+! This pass does not update ##phi nodes and should therefore only run
+! before stack analysis.
 : join-block? ( bb -- ? )
     {
         [ kill-block? not ]
@@ -27,8 +27,11 @@ IN: compiler.cfg.block-joining
     [ join-instructions ] [ update-successors ] 2bi ;
 
 : join-blocks ( cfg -- cfg' )
+    needs-predecessors
+
     dup post-order [
         dup join-block?
         [ dup predecessor join-block ] [ drop ] if
     ] each
-    cfg-changed ;
+
+    cfg-changed predecessors-changed ;
index d73bd866a0bb1013880372de12ab54ee14c2e5d1..f3790fd33810d7edc766d865723cbac9546cfc51 100644 (file)
@@ -9,11 +9,11 @@ IN: compiler.cfg.branch-splitting.tests
 
 : check-predecessors ( cfg -- )
     [ get-predecessors ]
-    [ compute-predecessors drop ]
+    [ needs-predecessors drop ]
     [ get-predecessors ] tri assert= ;
 
 : check-branch-splitting ( cfg -- )
-    compute-predecessors
+    needs-predecessors
     split-branches
     check-predecessors ;
 
index e5583a14ab0f2f4ec39ecf0b3762aca94cb3f7e4..1daabf6f0efaee6fdb49b0124121ab1f3a2901da 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors combinators.short-circuit kernel math math.order
 sequences assocs namespaces vectors fry arrays splitting
-compiler.cfg.def-use compiler.cfg compiler.cfg.rpo
+compiler.cfg.def-use compiler.cfg compiler.cfg.rpo compiler.cfg.predecessors
 compiler.cfg.renaming compiler.cfg.instructions compiler.cfg.utilities ;
 IN: compiler.cfg.branch-splitting
 
@@ -81,7 +81,10 @@ UNION: irrelevant ##peek ##replace ##inc-d ##inc-r ;
     ] if ;
 
 : split-branches ( cfg -- cfg' )
+    needs-predecessors
+    
     dup [
         dup split-branch? [ split-branch ] [ drop ] if
     ] each-basic-block
+
     cfg-changed ;
index 2de7c7c3d1ed0bc31aca942a9515c324f92adf35..09f670ac54c4b574c05d55fa4d92afa3030d8702 100644 (file)
@@ -3,12 +3,13 @@ USING: tools.test kernel sequences words sequences.private fry
 prettyprint alien alien.accessors math.private compiler.tree.builder
 compiler.tree.optimizer compiler.cfg.builder compiler.cfg.debugger
 compiler.cfg.optimizer compiler.cfg.predecessors compiler.cfg.checker
-arrays locals byte-arrays kernel.private math slots.private vectors sbufs
-strings math.partial-dispatch strings.private ;
+compiler.cfg arrays locals byte-arrays kernel.private math
+slots.private vectors sbufs strings math.partial-dispatch
+strings.private ;
 
 ! Just ensure that various CFGs build correctly.
 : unit-test-cfg ( quot -- )
-    '[ _ test-cfg [ optimize-cfg check-cfg ] each ] [ ] swap unit-test ;
+    '[ _ test-cfg [ [ optimize-cfg check-cfg ] with-cfg ] each ] [ ] swap unit-test ;
 
 : blahblah ( nodes -- ? )
     { fixnum } declare [
index 6a04f5b6270f80bdd01a7d3738df99aa3eb5a161..369e6ebc32631f8177b338225cc12f8e79da93cb 100644 (file)
@@ -19,7 +19,10 @@ M: basic-block hashcode* nip id>> ;
         V{ } clone >>predecessors
         \ basic-block counter >>id ;
 
-TUPLE: cfg { entry basic-block } word label spill-area-size reps post-order ;
+TUPLE: cfg { entry basic-block } word label
+spill-area-size reps
+post-order linear-order
+predecessors-valid? dominance-valid? loops-valid? ;
 
 : <cfg> ( entry word label -- cfg )
     cfg new
@@ -27,7 +30,17 @@ TUPLE: cfg { entry basic-block } word label spill-area-size reps post-order ;
         swap >>word
         swap >>entry ;
 
-: cfg-changed ( cfg -- cfg ) f >>post-order ; inline
+: cfg-changed ( cfg -- cfg )
+    f >>post-order
+    f >>linear-order
+    f >>dominance-valid?
+    f >>loops-valid? ; inline
+
+: predecessors-changed ( cfg -- cfg )
+    f >>predecessors-valid? ;
+
+: with-cfg ( cfg quot: ( cfg -- ) -- )
+    [ dup cfg ] dip with-variable ; inline
 
 TUPLE: mr { instructions array } word label ;
 
index 812a5a1a7fb236e796011ee93be63d46a47c317c..6919ba8b9b06eb7d1b9fa4d81fa24f7690bfe42d 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel namespaces assocs accessors sequences grouping
 combinators compiler.cfg.rpo compiler.cfg.renaming
-compiler.cfg.instructions ;
+compiler.cfg.instructions compiler.cfg.predecessors ;
 IN: compiler.cfg.copy-prop
 
 ! The first three definitions are also used in compiler.cfg.alias-analysis.
@@ -70,6 +70,8 @@ M: insn update-insn rename-insn-uses t ;
 PRIVATE>
 
 : copy-propagation ( cfg -- cfg' )
+    needs-predecessors
+
     [ collect-copies ]
     [ rename-copies ]
     [ ]
index 975adfa6cb19ab2ec6e130bbb90822755d812fb6..62043fb413aaf5dcbeab23d0955b3cf4af670684 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs deques dlists kernel locals sequences lexer
 namespaces functors compiler.cfg.rpo compiler.cfg.utilities
-compiler.cfg ;
+compiler.cfg.predecessors compiler.cfg ;
 IN: compiler.cfg.dataflow-analysis
 
 GENERIC: join-sets ( sets dfa -- set )
@@ -48,6 +48,7 @@ M:: basic-block compute-out-set ( bb in-sets dfa -- set )
     ] when ; inline
 
 :: run-dataflow-analysis ( cfg dfa -- in-sets out-sets )
+    cfg needs-predecessors drop
     H{ } clone :> in-sets
     H{ } clone :> out-sets
     cfg dfa <dfa-worklist> :> work-list
index fdc6601de41c1d0009334ed42f87a0e234f31ed5..dd42475a138a0667390cba6e60727d2fa253801b 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs sets kernel namespaces sequences
 compiler.cfg.instructions compiler.cfg.def-use
-compiler.cfg.rpo ;
+compiler.cfg.rpo compiler.cfg.predecessors ;
 IN: compiler.cfg.dce
 
 ! Maps vregs to sequences of vregs
@@ -95,6 +95,8 @@ M: ##write-barrier live-insn? src>> live-vreg? ;
 M: insn live-insn? drop t ;
 
 : eliminate-dead-code ( cfg -- cfg' )
+    needs-predecessors
+
     init-dead-code
     dup
     [ [ instructions>> [ build-liveness-graph ] each ] each-basic-block ]
index bab17d160b396e1fdf1bfa5186bcd1d24ab05598..33f87ff1d417fde17fc6f0e810f5980d5e24f35e 100644 (file)
@@ -24,8 +24,10 @@ M: word test-cfg
 
 : test-mr ( quot -- mrs )
     test-cfg [
-        optimize-cfg
-        build-mr
+        [
+            optimize-cfg
+            build-mr
+        ] with-cfg
     ] map ;
 
 : insn. ( insn -- )
index a3b9fc0223d2411ae314290d2726d2a2b89f0c69..81d573a4e21a2a141999867fd5af6a6acd1111b3 100644 (file)
@@ -5,8 +5,7 @@ compiler.cfg.predecessors ;
 
 : test-dominance ( -- )
     cfg new 0 get >>entry
-    compute-predecessors
-    compute-dominance ;
+    needs-dominance drop ;
 
 ! Example with no back edges
 V{ } 0 test-bb
index 325bed74ff99142532b310dbfa998e78aca1e886..d21e81526e426d2299f6475b9cfe36f7bc503c8d 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs combinators sets math fry kernel math.order
 dlists deques vectors namespaces sequences sorting locals
-compiler.cfg.rpo ;
+compiler.cfg.rpo compiler.cfg.predecessors ;
 IN: compiler.cfg.dominance
 
 ! Reference:
@@ -83,10 +83,14 @@ PRIVATE>
     H{ } clone maxpreorder set
     [ 0 ] dip entry>> (compute-dfs) drop ;
 
+: compute-dominance ( cfg -- cfg' )
+    [ compute-dom-parents compute-dom-children ] [ compute-dfs ] [ ] tri ;
+
 PRIVATE>
 
-: compute-dominance ( cfg -- )
-    [ compute-dom-parents compute-dom-children ] [ compute-dfs ] bi ;
+: needs-dominance ( cfg -- cfg' )
+    needs-predecessors
+    dup dominance-valid?>> [ compute-dominance t >>dominance-valid? ] unless ;
 
 : dominates? ( bb1 bb2 -- ? )
     swap [ pre-of ] [ [ pre-of ] [ maxpre-of ] bi ] bi* between? ;
index 2a31a20b72d0d14548637db6484c69b0b56132e0..605c572cb3b548b9e3a60b264b34399561e42b53 100644 (file)
@@ -1,9 +1,12 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors sequences combinators combinators.short-circuit
-classes vectors compiler.cfg compiler.cfg.instructions compiler.cfg.rpo ;
+USING: kernel accessors sequences namespaces combinators
+combinators.short-circuit classes vectors compiler.cfg
+compiler.cfg.instructions compiler.cfg.rpo ;
 IN: compiler.cfg.empty-blocks
+
+<PRIVATE
+
 : update-predecessor ( bb -- )
     ! We have to replace occurrences of bb with bb's successor
     ! in bb's predecessor's list of successors.
@@ -21,9 +24,12 @@ IN: compiler.cfg.empty-blocks
             2dup eq? [ drop predecessors>> first ] [ nip ] if
         ] with map
     ] change-predecessors drop ;
+
+SYMBOL: changed?
+
 : delete-basic-block ( bb -- )
-    [ update-predecessor ] [ update-successor ] bi ;
+    [ update-predecessor ] [ update-successor ] bi
+    changed? on ;
  
 : delete-basic-block? ( bb -- ? )
     {
@@ -32,7 +38,10 @@ IN: compiler.cfg.empty-blocks
         [ successors>> length 1 = ]
         [ instructions>> first ##branch? ]
     } 1&& ;
+
+PRIVATE>
+
 : delete-empty-blocks ( cfg -- cfg' )
+    changed? off
     dup [ dup delete-basic-block? [ delete-basic-block ] [ drop ] if ] each-basic-block
-    cfg-changed ;
\ No newline at end of file
+    changed? get [ cfg-changed ] when ;
\ No newline at end of file
index ac7ebd94e8d856707f53274770ff62f09381ba4d..9059713e2176aebddf56cc6c7dfe8566005091e4 100644 (file)
@@ -7,7 +7,6 @@ namespaces accessors sequences ;
 : test-gc-checks ( -- )
     H{ } clone representations set
     cfg new 0 get >>entry
-    compute-predecessors
     insert-gc-checks
     drop ;
 
index c05103f244a0c2eedc3e87e94e5b55ac6cb06bc6..16f1ccf96a1e4ff2e62b1ee6df2d2a97da624cdf 100644 (file)
@@ -4,12 +4,12 @@ USING: accessors kernel math assocs namespaces sequences heaps
 fry make combinators sets locals arrays
 cpu.architecture
 compiler.cfg
-compiler.cfg.rpo
 compiler.cfg.def-use
 compiler.cfg.liveness
 compiler.cfg.registers
 compiler.cfg.instructions
 compiler.cfg.renaming.functor
+compiler.cfg.linearization.order
 compiler.cfg.linear-scan.allocation
 compiler.cfg.linear-scan.allocation.state
 compiler.cfg.linear-scan.live-intervals ;
@@ -181,4 +181,4 @@ ERROR: bad-vreg vreg ;
 
 : assign-registers ( live-intervals cfg -- )
     [ init-assignment ] dip
-    [ assign-registers-in-block ] each-basic-block ;
+    linearization-order [ assign-registers-in-block ] each ;
index 1580ee3f653b81ceb4a809da8f6f5146367e9c99..b7a97e75c6d80e16c0eb9403e80238d3d88b42a9 100644 (file)
@@ -565,10 +565,9 @@ H{
 :: test-linear-scan-on-cfg ( regs -- )
     [
         cfg new 0 get >>entry
-        compute-predecessors
+        dup cfg set
         dup fake-representations
         dup { { int-regs regs } } (linear-scan)
-        cfg-changed
         flatten-cfg 1array mr.
     ] with-scope ;
 
index d90fd00fdd5519c21707819c1cef193e38e7568b..5e723f098a06dcbd9f8c7a5f675179c8864d6210 100644 (file)
@@ -38,7 +38,4 @@ IN: compiler.cfg.linear-scan
     cfg check-numbering ;
 
 : linear-scan ( cfg -- cfg' )
-    [
-        dup machine-registers (linear-scan)
-        cfg-changed
-    ] with-scope ;
+    dup machine-registers (linear-scan) ;
index 8cc28e41e246c4494ee590b15d241f2ffe48ac36..2301d26f8069a23ac8a42eff0ab8d4f927530ae1 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces kernel assocs accessors sequences math math.order fry
 combinators binary-search compiler.cfg.instructions compiler.cfg.registers
-compiler.cfg.def-use compiler.cfg.liveness compiler.cfg.rpo
+compiler.cfg.def-use compiler.cfg.liveness compiler.cfg.linearization.order
 compiler.cfg ;
 IN: compiler.cfg.linear-scan.live-intervals
 
@@ -137,7 +137,8 @@ ERROR: bad-live-interval live-interval ;
 : compute-live-intervals ( cfg -- live-intervals )
     H{ } clone [
         live-intervals set
-        post-order [ compute-live-intervals-step ] each
+        linearization-order <reversed>
+        [ compute-live-intervals-step ] each
     ] keep values dup finish-live-intervals ;
 
 : relevant-ranges ( interval1 interval2 -- ranges1 ranges2 )
index 2976680857140e49aae8608322f8733edc995123..6fd97c64dad30f66d915b633e757901543cbf577 100644 (file)
@@ -1,15 +1,15 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors math sequences grouping namespaces
-compiler.cfg.rpo ;
+compiler.cfg.linearization.order ;
 IN: compiler.cfg.linear-scan.numbering
 
 : number-instructions ( rpo -- )
-    [ 0 ] dip [
+    linearization-order 0 [
         instructions>> [
             [ (>>insn#) ] [ drop 2 + ] 2bi
         ] each
-    ] each-basic-block drop ;
+    ] reduce drop ;
 
 SYMBOL: check-numbering?
 
@@ -20,4 +20,5 @@ ERROR: bad-numbering bb ;
     [ drop ] [ bad-numbering ] if ;
 
 : check-numbering ( cfg -- )
-    check-numbering? get [ [ check-block-numbering ] each-basic-block ] [ drop ] if ;
\ No newline at end of file
+    check-numbering? get
+    [ linearization-order [ check-block-numbering ] each ] [ drop ] if ;
\ No newline at end of file
index dd0ae4a2703e34ba1c6275a3ae1e15d2f6a1802a..a3733b5d98d2459f9e9ad4e4bbb764db9c492aeb 100644 (file)
@@ -3,6 +3,7 @@
 USING: accessors arrays assocs combinators
 combinators.short-circuit fry kernel locals namespaces
 make math sequences hashtables
+compiler.cfg
 compiler.cfg.rpo
 compiler.cfg.liveness
 compiler.cfg.registers
@@ -63,8 +64,8 @@ SYMBOL: temp
 
 : perform-mappings ( bb to mappings -- )
     dup empty? [ 3drop ] [
-        mapping-instructions <simple-block>
-        insert-basic-block
+        mapping-instructions <simple-block> insert-basic-block
+        cfg get cfg-changed drop
     ] if ;
 
 : resolve-edge-data-flow ( bb to -- )
index df646b5e6a161ba0cdce95ad24f71040ebc443f3..97d00c1ed3312e826a30e26c47c8d8ca8e1dfd65 100755 (executable)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math accessors sequences namespaces make
-combinators assocs arrays locals layouts cpu.architecture
+combinators assocs arrays locals layouts hashtables
+cpu.architecture
 compiler.cfg
 compiler.cfg.comparisons
 compiler.cfg.stack-frame
@@ -10,6 +11,14 @@ compiler.cfg.utilities
 compiler.cfg.linearization.order ;
 IN: compiler.cfg.linearization
 
+<PRIVATE
+
+SYMBOL: numbers
+
+: block-number ( bb -- n ) numbers get at ;
+
+: number-blocks ( bbs -- ) [ 2array ] map-index >hashtable numbers set ;
+
 ! Convert CFG IR to machine IR.
 GENERIC: linearize-insn ( basic-block insn -- )
 
@@ -87,11 +96,15 @@ M: ##gc linearize-insn
 
 : linearize-basic-blocks ( cfg -- insns )
     [
-        [ linearization-order [ linearize-basic-block ] each ]
-        [ spill-area-size>> _spill-area-size ]
-        bi
+        [
+            linearization-order
+            [ number-blocks ]
+            [ [ linearize-basic-block ] each ] bi
+        ] [ spill-area-size>> _spill-area-size ] bi
     ] { } make ;
 
+PRIVATE>
+        
 : flatten-cfg ( cfg -- mr )
     [ linearize-basic-blocks ] [ word>> ] [ label>> ] tri
     <mr> ;
index c09c2969bad0d35f8e083b414406a3d4f15ea5ae..2e91184fe5d1e5b501b781e4bbbe19c250254876 100644 (file)
@@ -1,15 +1,16 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs deques dlists kernel make
+USING: accessors assocs deques dlists kernel make sorting
 namespaces sequences combinators combinators.short-circuit
-fry math sets compiler.cfg.rpo compiler.cfg.utilities ;
+fry math sets compiler.cfg.rpo compiler.cfg.utilities
+compiler.cfg.loop-detection ;
 IN: compiler.cfg.linearization.order
 
 ! This is RPO except loops are rotated. Based on SBCL's src/compiler/control.lisp
 
 <PRIVATE
 
-SYMBOLS: work-list loop-heads visited numbers next-number ;
+SYMBOLS: work-list loop-heads visited ;
 
 : visited? ( bb -- ? ) visited get key? ;
 
@@ -18,6 +19,11 @@ SYMBOLS: work-list loop-heads visited numbers next-number ;
         work-list get push-back
     ] if ;
 
+: init-linearization-order ( cfg -- )
+    <dlist> work-list set
+    H{ } clone visited set
+    entry>> add-to-work-list ;
+
 : (find-alternate-loop-head) ( bb -- bb' )
     dup {
         [ predecessor visited? not ]
@@ -46,28 +52,26 @@ SYMBOLS: work-list loop-heads visited numbers next-number ;
         add-to-work-list
     ] [ drop ] if ;
 
-: assign-number ( bb -- )
-    next-number [ get ] [ inc ] bi swap numbers get set-at ;
+: sorted-successors ( bb -- seq )
+    successors>> [ loop-nesting-at ] sort-with ;
 
 : process-block ( bb -- )
-    {
-        [ , ]
-        [ assign-number ]
-        [ visited get conjoin ]
-        [ successors>> <reversed> [ process-successor ] each ]
-    } cleave ;
+    [ , ]
+    [ visited get conjoin ]
+    [ sorted-successors [ process-successor ] each ]
+    tri ;
+
+: (linearization-order) ( cfg -- bbs )
+    init-linearization-order
+
+    [ work-list get [ process-block ] slurp-deque ] { } make ;
 
 PRIVATE>
 
 : linearization-order ( cfg -- bbs )
-    ! We call 'post-order drop' to ensure blocks receive their
-    ! RPO numbers.
-    <dlist> work-list set
-    H{ } clone visited set
-    H{ } clone numbers set
-    0 next-number set
-    [ post-order drop ]
-    [ entry>> add-to-work-list ] bi
-    [ work-list get [ process-block ] slurp-deque ] { } make ;
+    needs-post-order needs-loops
 
-: block-number ( bb -- n ) numbers get at ;
+    dup linear-order>> [ ] [
+        dup (linearization-order)
+        >>linear-order linear-order>>
+    ] ?if ;
\ No newline at end of file
index 1f53695d9ef757479a028307c405dd5b4a61bc88..e4f5144e1f8a42122c229c922e9813ce7ce37112 100644 (file)
@@ -6,7 +6,6 @@ IN: compiler.cfg.liveness.tests
 
 : test-liveness ( -- )
     cfg new 1 get >>entry
-    compute-predecessors
     compute-live-sets ;
 
 ! Sanity check...
index 82af084f06ddc5b2d2f4e2f1426aad7a269bede8..81263c8e9ac3ddcaef1863fc1f8ff6ca15c5b7f7 100644 (file)
@@ -2,7 +2,8 @@
 ! 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 compiler.cfg.utilities ;
+compiler.cfg.rpo compiler.cfg.liveness compiler.cfg.utilities
+compiler.cfg.predecessors ;
 IN: compiler.cfg.liveness.ssa
 
 ! TODO: merge with compiler.cfg.liveness
@@ -47,6 +48,8 @@ SYMBOL: work-list
     ] [ drop ] if ;
 
 : compute-ssa-live-sets ( cfg -- cfg' )
+    needs-predecessors
+
     <hashed-dlist> work-list set
     H{ } clone live-ins set
     H{ } clone phi-live-ins set
index fbb5b2340cc292cf2609c5b080bed5bbb28cadc2..d525f91ed3e7822883c88a4d2107fa82b5c09c84 100644 (file)
@@ -11,7 +11,7 @@ V{ } 2 test-bb
 0 { 1 2 } edges
 2 0 edge
 
-: test-loop-detection ( -- ) cfg new 0 get >>entry compute-predecessors detect-loops drop ;
+: test-loop-detection ( -- ) cfg new 0 get >>entry needs-loops drop ;
 
 [ ] [ test-loop-detection ] unit-test
 
index 9f71aba14a5e4ef529c2e84880e3fade949a1081..dc70656c081f74584a21f2a05a97483e4ab49d76 100644 (file)
@@ -1,11 +1,9 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs combinators deques dlists fry kernel
-namespaces sequences sets compiler.cfg ;
+namespaces sequences sets compiler.cfg compiler.cfg.predecessors ;
 IN: compiler.cfg.loop-detection
 
-! Loop detection -- predecessors must be computed first
-
 TUPLE: natural-loop header index ends blocks ;
 
 <PRIVATE
@@ -68,13 +66,18 @@ SYMBOL: loop-nesting
         [ values ] dip '[ blocks>> values [ _ inc-at ] each ] each
     ] keep loop-nesting set ;
 
-PRIVATE>
-
-: loop-nesting-at ( bb -- n ) loop-nesting get at 0 or ;
-
 : detect-loops ( cfg -- cfg' )
+    needs-predecessors
     H{ } clone loops set
     H{ } clone visited set
     H{ } clone active set
     H{ } clone loop-nesting set
-    dup entry>> find-loop-headers process-loop-headers compute-loop-nesting ;
\ No newline at end of file
+    dup entry>> find-loop-headers process-loop-headers compute-loop-nesting ;
+
+PRIVATE>
+
+: loop-nesting-at ( bb -- n ) loop-nesting get at 0 or ;
+
+: needs-loops ( cfg -- cfg' )
+    needs-predecessors
+    dup loops-valid?>> [ detect-loops t >>loops-valid? ] unless ;
\ No newline at end of file
index bedfca3c0e65f05a00e9d76ba4ca770c2c35eb34..de679cbcc2e2ec0c0e9dc7f5168c86e12eb705a7 100644 (file)
@@ -1,15 +1,12 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces accessors compiler.cfg compiler.cfg.registers
+USING: kernel namespaces accessors compiler.cfg
 compiler.cfg.linearization compiler.cfg.gc-checks
 compiler.cfg.linear-scan compiler.cfg.build-stack-frame ;
 IN: compiler.cfg.mr
 
 : build-mr ( cfg -- mr )
-    dup cfg [
-        cfg get reps>> representations set
-        insert-gc-checks
-        linear-scan
-        flatten-cfg
-        build-stack-frame
-    ] with-variable ;
\ No newline at end of file
+    insert-gc-checks
+    linear-scan
+    flatten-cfg
+    build-stack-frame ;
\ No newline at end of file
index f7a6c81d3003598c795a8cb27844c59264d3f5a7..649032b46936d958d214ea39a85fdfb5ed78d365 100644 (file)
@@ -1,7 +1,6 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences accessors combinators namespaces
-compiler.cfg
 compiler.cfg.tco
 compiler.cfg.useless-conditionals
 compiler.cfg.branch-splitting
@@ -13,12 +12,9 @@ compiler.cfg.copy-prop
 compiler.cfg.dce
 compiler.cfg.write-barrier
 compiler.cfg.representations
-compiler.cfg.loop-detection
 compiler.cfg.two-operand
 compiler.cfg.ssa.destruction
 compiler.cfg.empty-blocks
-compiler.cfg.predecessors
-compiler.cfg.rpo
 compiler.cfg.checker ;
 IN: compiler.cfg.optimizer
 
@@ -30,26 +26,18 @@ SYMBOL: check-optimizer?
     ] when ;
 
 : optimize-cfg ( cfg -- cfg' )
-    ! Note that compute-predecessors has to be called several times.
-    ! The passes that need this document it.
-    dup cfg [
-        optimize-tail-calls
-        delete-useless-conditionals
-        compute-predecessors
-        split-branches
-        join-blocks
-        compute-predecessors
-        construct-ssa
-        alias-analysis
-        value-numbering
-        compute-predecessors
-        copy-propagation
-        eliminate-dead-code
-        eliminate-write-barriers
-        detect-loops
-        select-representations
-        convert-two-operand
-        destruct-ssa
-        delete-empty-blocks
-        ?check
-    ] with-variable ;
+    optimize-tail-calls
+    delete-useless-conditionals
+    split-branches
+    join-blocks
+    construct-ssa
+    alias-analysis
+    value-numbering
+    copy-propagation
+    eliminate-dead-code
+    eliminate-write-barriers
+    select-representations
+    convert-two-operand
+    destruct-ssa
+    delete-empty-blocks
+    ?check ;
index c972197dd8459e22d6e76b16f0c678fc59aba0d0..8ab9f316a726c357945f2a59da4f3a679d778911 100644 (file)
@@ -4,6 +4,8 @@ USING: kernel accessors combinators fry sequences assocs compiler.cfg.rpo
 compiler.cfg.instructions compiler.cfg.utilities ;
 IN: compiler.cfg.predecessors
 
+<PRIVATE
+
 : update-predecessors ( bb -- )
     dup successors>> [ predecessors>> push ] with each ;
 
@@ -23,3 +25,9 @@ IN: compiler.cfg.predecessors
         [ [ update-phis ] each-basic-block ]
         [ ]
     } cleave ;
+
+PRIVATE>
+
+: needs-predecessors ( cfg -- cfg' )
+    dup predecessors-valid?>>
+    [ compute-predecessors t >>predecessors-valid? ] unless ;
\ No newline at end of file
index a31851d6ddbe5288c3dd88b1ae414faba10008eb..f58870850e6ee39d065d25727174350f5ab7efcf 100644 (file)
@@ -14,8 +14,7 @@ compiler.cfg.renaming.functor
 compiler.cfg.representations.preferred ;
 IN: compiler.cfg.representations
 
-! Virtual register representation selection. Predecessors and loops
-! must be computed first.
+! Virtual register representation selection.
 
 : emit-conversion ( dst src dst-rep src-rep -- )
     2array {
@@ -217,6 +216,8 @@ SYMBOL: work-list
 PRIVATE>
 
 : select-representations ( cfg -- cfg' )
+    needs-loops
+
     {
         [ compute-possibilities ]
         [ compute-representations ]
index 1ddacdf8abbab4ebc784d492ae57683fe46ce499..b6322730ee72bd2a80ff881a8e95f5e17dd0a901 100644 (file)
@@ -39,4 +39,7 @@ SYMBOL: visited
     [ change-instructions drop ] 2bi ; inline
 
 : local-optimization ( cfg quot: ( insns -- insns' ) -- cfg' )
-    dupd '[ _ optimize-basic-block ] each-basic-block ; inline
\ No newline at end of file
+    dupd '[ _ optimize-basic-block ] each-basic-block ; inline
+
+: needs-post-order ( cfg -- cfg' )
+    dup post-order drop ;
\ No newline at end of file
index 4814aba935b01678e0e94c4830e5d1622910e339..3d743176b139338df8a6ec33c432c3a5f5d03f35 100644 (file)
@@ -41,7 +41,6 @@ V{
 : test-ssa ( -- )
     cfg new 0 get >>entry
     dup cfg set
-    compute-predecessors
     construct-ssa
     drop ;
 
index d77c45232a37662a3efdbabd6f2c413c80103c69..7662b8ab01093fd288fd340b5b998ed220a9fa2d 100644 (file)
@@ -14,8 +14,6 @@ compiler.cfg.renaming.functor
 compiler.cfg.ssa.construction.tdmsc ;
 IN: compiler.cfg.ssa.construction
 
-! SSA construction. Predecessors must be computed first.
-
 ! The phi placement algorithm is implemented in
 ! compiler.cfg.ssa.construction.tdmsc.
 
@@ -132,10 +130,9 @@ PRIVATE>
 
 : construct-ssa ( cfg -- cfg' )
     {
-        [ ]
         [ compute-live-sets ]
-        [ compute-dominance ]
         [ compute-merge-sets ]
         [ compute-defs compute-phi-nodes insert-phi-nodes ]
         [ rename ]
+        [ ]
     } cleave ;
\ No newline at end of file
index e6ef3ebeac2a6acb935bdcdababbf2de74cf3203..955d41814fe6e39f2b61169dc92ea1df83873f85 100644 (file)
@@ -6,8 +6,6 @@ IN: compiler.cfg.ssa.construction.tdmsc.tests
 
 : test-tdmsc ( -- )
     cfg new 0 get >>entry dup cfg set
-    compute-predecessors
-    dup compute-dominance
     compute-merge-sets ;
 
 V{ } 0 test-bb
index 954680eaeb5d4d42af7be091cdd6197e259ea243..647c97d6c3f3b0f3ecc61bb76c8471219140848c 100644 (file)
@@ -93,6 +93,8 @@ HINTS: filter-by { bit-array object } ;
 PRIVATE>
 
 : compute-merge-sets ( cfg -- )
+    needs-dominance
+
     H{ } clone visited set
     [ compute-levels ]
     [ init-merge-sets ]
index c19f615e958f0e21429af8d880c8574fc1d3f5a0..424be91e2ba4850c86c78e43de76d06b42ea8e4b 100644 (file)
@@ -97,9 +97,10 @@ M: insn prepare-insn drop ;
     ] each-basic-block ;
 
 : destruct-ssa ( cfg -- cfg' )
+    needs-dominance
+
     dup construct-cssa
     dup compute-defs
-    dup compute-dominance
     compute-ssa-live-sets
     dup compute-live-ranges
     dup prepare-coalescing
index cdcacd709160fb2006d5dd6e8850a9da2ebc0d89..2f13331024c3a957baff7e1e1736c5124d9642d8 100644 (file)
@@ -10,9 +10,7 @@ IN: compiler.cfg.ssa.interference.tests
 : test-interference ( -- )
     cfg new 0 get >>entry
     compute-ssa-live-sets
-    compute-predecessors
     dup compute-defs
-    dup compute-dominance
     compute-live-ranges ;
 
 V{
index c094b18ce9a3e3184b948d86cd2a59705c47e410..fd1f09a900e4c9bb6f4fc4a6a17960bc87e74d83 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs fry kernel namespaces sequences math
 arrays compiler.cfg.def-use compiler.cfg.instructions
-compiler.cfg.liveness.ssa compiler.cfg.rpo ;
+compiler.cfg.liveness.ssa compiler.cfg.rpo compiler.cfg.dominance ;
 IN: compiler.cfg.ssa.interference.live-ranges
 
 ! Live ranges for interference testing
@@ -47,6 +47,8 @@ SYMBOLS: def-indices kill-indices ;
 PRIVATE>
 
 : compute-live-ranges ( cfg -- )
+    needs-dominance
+
     H{ } clone def-indices set
     H{ } clone kill-indices set
     [ compute-local-live-ranges ] each-basic-block ;
index 6b71397f2ac0cb56ddbd4513531b6bf8976994f3..bc5807087da7d95b60bd44805d4794251f9a5b15 100644 (file)
@@ -21,10 +21,9 @@ IN: compiler.cfg.ssa.liveness
 
 : test-liveness ( -- )
     cfg new 0 get >>entry
-    compute-predecessors
     dup compute-defs
     dup compute-uses
-    dup compute-dominance
+    needs-dominance
     precompute-liveness ;
 
 V{
index 148104a465b6fd276bd7c113006834cdafc47985..ca81c69bc0a6fc2db01e90dcdf4114828f571045 100644 (file)
@@ -3,7 +3,8 @@
 USING: namespaces assocs kernel fry accessors sequences make math locals
 combinators compiler.cfg compiler.cfg.hats compiler.cfg.instructions
 compiler.cfg.utilities compiler.cfg.rpo compiler.cfg.stacks.local
-compiler.cfg.stacks.global compiler.cfg.stacks.height ;
+compiler.cfg.stacks.global compiler.cfg.stacks.height
+compiler.cfg.predecessors ;
 IN: compiler.cfg.stacks.finalize
 
 ! This pass inserts peeks and replaces.
@@ -51,5 +52,8 @@ ERROR: bad-peek dst loc ;
     [ predecessors>> ] keep '[ _ visit-edge ] each ;
 
 : finalize-stack-shuffling ( cfg -- cfg' )
+    needs-predecessors
+
     dup [ visit-block ] each-basic-block
+
     cfg-changed ;
\ No newline at end of file
index 1896b0a7fb5fb54e9b17657a7f12335f06cea695..ce673ba5bb4da2a317347c3763ffb9bb29ec18dc 100755 (executable)
@@ -18,7 +18,6 @@ IN: compiler.cfg.stacks
 
 : end-stack-analysis ( -- )
     cfg get
-    compute-predecessors
     compute-global-sets
     finalize-stack-shuffling
     drop ;
index df355f9d9a9f9ac0738027220c9a0bbd022d9d1f..9c8a41f2c4fba5abac216484b4ec713d1f11d9b5 100644 (file)
@@ -6,7 +6,6 @@ namespaces accessors sequences ;
 
 : test-uninitialized ( -- )
     cfg new 0 get >>entry
-    compute-predecessors
     compute-uninitialized-sets ;
 
 V{
index 7fbe8331b1152ad86bbd0dded9af6ef946642d8e..810b9010130d47716f9cd3d1a0cad8613efbfd9d 100644 (file)
@@ -10,7 +10,7 @@ compiler.cfg.instructions
 compiler.cfg.utilities ;
 IN: compiler.cfg.tco
 
-! Tail call optimization. You must run compute-predecessors after this
+! Tail call optimization.
 
 : return? ( bb -- ? )
     skip-empty-blocks
@@ -64,4 +64,5 @@ IN: compiler.cfg.tco
 
 : optimize-tail-calls ( cfg -- cfg' )
     dup [ optimize-tail-call ] each-basic-block
-    cfg-changed ;
\ No newline at end of file
+
+    cfg-changed predecessors-changed ;
\ No newline at end of file
index cc98d0804204dbd2d91cfb9b3763cca8a3ab80d2..d480ad97d1fcd6142b658404bb8e8e474875f7ef 100644 (file)
@@ -19,4 +19,5 @@ IN: compiler.cfg.useless-conditionals
     dup [
         dup delete-conditional? [ delete-conditional ] [ drop ] if
     ] each-basic-block
-    cfg-changed ;
+    
+    cfg-changed predecessors-changed ;
index 583d7730b0b32962bb14f3aa3c2bc171c05a774b..f3c950679a5657ac3e31b383d4cf6def5887602c 100644 (file)
@@ -1186,8 +1186,6 @@ test-diamond
 [ ] [
     cfg new 0 get >>entry dup cfg set
     value-numbering
-    compute-predecessors
-    detect-loops
     select-representations
     destruct-ssa drop
 ] unit-test
@@ -1230,9 +1228,7 @@ test-diamond
 
 [ ] [
     cfg new 0 get >>entry
-    compute-predecessors
     value-numbering
-    compute-predecessors
     eliminate-dead-code
     drop
 ] unit-test
index 914970f3ada2aea7698ed5db34af42c912d6ca31..689d1d32c67666e51dbfe58f183444aa5afeb39f 100644 (file)
@@ -12,7 +12,8 @@ compiler.cfg.value-numbering.simplify
 compiler.cfg.value-numbering.rewrite ;
 IN: compiler.cfg.value-numbering
 
-! Local value numbering. Predecessors must be recomputed after this
+! Local value numbering.
+
 : >copy ( insn -- insn/##copy )
     dup dst>> dup vreg>vn vn>vreg
     2dup eq? [ 2drop ] [ any-rep \ ##copy new-insn nip ] if ;
@@ -37,4 +38,6 @@ M: insn process-instruction
     [ process-instruction ] map ;
 
 : value-numbering ( cfg -- cfg' )
-    [ value-numbering-step ] local-optimization cfg-changed ;
+    [ value-numbering-step ] local-optimization
+
+    cfg-changed predecessors-changed ;
index 6d0f6f3acefdaf3643709c83cfe9e5e9ca79a555..3b8d996f3437a8005afbbea4ff31d60c00bac129 100644 (file)
@@ -12,6 +12,7 @@ compiler.errors compiler.units compiler.utilities
 compiler.tree.builder
 compiler.tree.optimizer
 
+compiler.cfg
 compiler.cfg.builder
 compiler.cfg.optimizer
 compiler.cfg.mr
@@ -152,8 +153,7 @@ t compile-dependencies? set-global
 
 : backend ( tree word -- )
     build-cfg [
-        optimize-cfg
-        build-mr
+        [ optimize-cfg build-mr ] with-cfg
         generate
         save-asm
     ] each ;
index 9d71c237e7d5f4e10d411cb7db97b48cdf059e65..ececac303772e6fd5eb2895caf373a504290b3ab 100644 (file)
@@ -13,6 +13,7 @@ IN: compiler.tests.low-level-ir
 
 : compile-test-cfg ( -- word )
     cfg new 0 get >>entry
+    dup cfg set
     dup fake-representations representations get >>reps
     compile-cfg ;
 
index 353a134375e9d3fa5590a25e219b96a43961b8ba..9823f93d4e644350b658ac60902ad1da810b988e 100644 (file)
@@ -24,7 +24,7 @@ IN: compiler.graphviz
     dup "Wrote " prepend print
     [ [ concat ] dip ascii set-file-lines ]
     [ { "dot" "-Tpng" "-O" } swap suffix try-process ]
-    [ ".png" append image. ]
+    [ ".png" append "open" swap 2array try-process ]
     tri ; inline
 
 : attrs>string ( seq -- str )
@@ -86,8 +86,7 @@ IN: compiler.graphviz
 : dom-trees ( cfgs -- )
     [
         [
-            compute-predecessors
-            compute-dominance
+            needs-dominance drop
             dom-childrens get [
                 [
                     bb-edge,