From 692b479302c01285c6a9acb7ef95c635da658b60 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 31 May 2009 12:20:46 -0500
Subject: [PATCH] Split off local-optimization combinator into
 compiler.cfg.local, factor out CFG -> MR into compiler.cfg.mr, split off GC
 check insertion into a new compiler.cfg.gc-checks pass

---
 .../cfg/alias-analysis/alias-analysis.factor  |  2 +-
 basis/compiler/cfg/checker/checker.factor     |  2 +-
 basis/compiler/cfg/debugger/debugger.factor   | 11 +++------
 basis/compiler/cfg/def-use/def-use.factor     |  4 +++-
 basis/compiler/cfg/gc-checks/authors.txt      |  1 +
 basis/compiler/cfg/gc-checks/gc-checks.factor | 22 +++++++++++++++++
 basis/compiler/cfg/height/height.factor       |  2 +-
 .../cfg/linearization/linearization.factor    | 16 +++----------
 basis/compiler/cfg/liveness/liveness.factor   |  3 ---
 basis/compiler/cfg/local/authors.txt          |  1 +
 basis/compiler/cfg/local/local.factor         | 10 ++++++++
 basis/compiler/cfg/mr/authors.txt             |  1 +
 basis/compiler/cfg/mr/mr.factor               | 14 +++++++++++
 basis/compiler/cfg/rpo/rpo.factor             |  3 ---
 .../stack-analysis-tests.factor               |  2 +-
 .../cfg/stack-analysis/stack-analysis.factor  |  6 ++++-
 .../value-numbering/value-numbering.factor    |  1 +
 .../cfg/write-barrier/write-barrier.factor    |  2 +-
 basis/compiler/compiler.factor                | 24 +++++++++++--------
 19 files changed, 83 insertions(+), 44 deletions(-)
 create mode 100644 basis/compiler/cfg/gc-checks/authors.txt
 create mode 100644 basis/compiler/cfg/gc-checks/gc-checks.factor
 create mode 100644 basis/compiler/cfg/local/authors.txt
 create mode 100644 basis/compiler/cfg/local/local.factor
 create mode 100644 basis/compiler/cfg/mr/authors.txt
 create mode 100644 basis/compiler/cfg/mr/mr.factor

diff --git a/basis/compiler/cfg/alias-analysis/alias-analysis.factor b/basis/compiler/cfg/alias-analysis/alias-analysis.factor
index 384fd65c1a..2385a4c65a 100644
--- a/basis/compiler/cfg/alias-analysis/alias-analysis.factor
+++ b/basis/compiler/cfg/alias-analysis/alias-analysis.factor
@@ -4,7 +4,7 @@ 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.rpo
-compiler.cfg.liveness ;
+compiler.cfg.liveness compiler.cfg.local ;
 IN: compiler.cfg.alias-analysis
 
 ! We try to eliminate redundant slot operations using some simple heuristics.
diff --git a/basis/compiler/cfg/checker/checker.factor b/basis/compiler/cfg/checker/checker.factor
index bf5adc2d55..b0a279c11b 100644
--- a/basis/compiler/cfg/checker/checker.factor
+++ b/basis/compiler/cfg/checker/checker.factor
@@ -54,5 +54,5 @@ ERROR: undefined-values uses defs ;
     compute-liveness
     [ entry>> live-in assoc-empty? [ bad-live-in ] unless ]
     [ [ check-basic-block ] each-basic-block ]
-    [ build-mr check-mr ]
+    [ flatten-cfg check-mr ]
     tri ;
diff --git a/basis/compiler/cfg/debugger/debugger.factor b/basis/compiler/cfg/debugger/debugger.factor
index 5c106bfaee..cb56937758 100644
--- a/basis/compiler/cfg/debugger/debugger.factor
+++ b/basis/compiler/cfg/debugger/debugger.factor
@@ -7,7 +7,8 @@ parser compiler.tree.builder compiler.tree.optimizer
 compiler.cfg.builder compiler.cfg.linearization
 compiler.cfg.registers compiler.cfg.stack-frame
 compiler.cfg.linear-scan compiler.cfg.two-operand
-compiler.cfg.optimizer ;
+compiler.cfg.liveness compiler.cfg.optimizer
+compiler.cfg.mr ;
 IN: compiler.cfg.debugger
 
 GENERIC: test-cfg ( quot -- cfgs )
@@ -18,20 +19,14 @@ M: callable test-cfg
 M: word test-cfg
     [ build-tree optimize-tree ] keep build-cfg ;
 
-SYMBOL: allocate-registers?
-
 : test-mr ( quot -- mrs )
     test-cfg [
         optimize-cfg
-        convert-two-operand
-        allocate-registers? get [ linear-scan ] when
         build-mr
-        allocate-registers? get [ build-stack-frame ] when
     ] map ;
 
 : insn. ( insn -- )
-    tuple>array allocate-registers? get [ but-last ] unless
-    [ pprint bl ] each nl ;
+    tuple>array [ pprint bl ] each nl ;
 
 : mr. ( mrs -- )
     [
diff --git a/basis/compiler/cfg/def-use/def-use.factor b/basis/compiler/cfg/def-use/def-use.factor
index 17e49f59a8..28351ca7b2 100644
--- a/basis/compiler/cfg/def-use/def-use.factor
+++ b/basis/compiler/cfg/def-use/def-use.factor
@@ -54,6 +54,7 @@ M: ##phi uses-vregs inputs>> ;
 M: _conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ;
 M: _compare-imm-branch uses-vregs src1>> 1array ;
 M: _dispatch uses-vregs src>> 1array ;
+M: _gc uses-vregs live-in>> ;
 M: insn uses-vregs drop f ;
 
 ! Instructions that use vregs
@@ -67,4 +68,5 @@ UNION: vreg-insn
 ##compare-imm-branch
 _conditional-branch
 _compare-imm-branch
-_dispatch ;
+_dispatch
+_gc ;
diff --git a/basis/compiler/cfg/gc-checks/authors.txt b/basis/compiler/cfg/gc-checks/authors.txt
new file mode 100644
index 0000000000..d4f5d6b3ae
--- /dev/null
+++ b/basis/compiler/cfg/gc-checks/authors.txt
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/compiler/cfg/gc-checks/gc-checks.factor b/basis/compiler/cfg/gc-checks/gc-checks.factor
new file mode 100644
index 0000000000..7a47da00a8
--- /dev/null
+++ b/basis/compiler/cfg/gc-checks/gc-checks.factor
@@ -0,0 +1,22 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel sequences assocs
+cpu.architecture compiler.cfg.rpo
+compiler.cfg.liveness compiler.cfg.instructions ;
+IN: compiler.cfg.gc-checks
+
+: gc? ( bb -- ? )
+    instructions>> [ ##allocation? ] any? ;
+
+: object-pointer-regs ( basic-block -- vregs )
+    live-in keys [ reg-class>> int-regs eq? ] filter ;
+
+: insert-gc-check ( basic-block -- )
+    dup gc? [
+        dup
+        [ swap object-pointer-regs \ _gc new-insn suffix ]
+        change-instructions drop
+    ] [ drop ] if ;
+
+: insert-gc-checks ( cfg -- cfg' )
+    dup [ insert-gc-check ] each-basic-block ;
\ No newline at end of file
diff --git a/basis/compiler/cfg/height/height.factor b/basis/compiler/cfg/height/height.factor
index b91120ccfd..14a0a54715 100644
--- a/basis/compiler/cfg/height/height.factor
+++ b/basis/compiler/cfg/height/height.factor
@@ -2,7 +2,7 @@
 ! 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.liveness ;
+compiler.cfg.liveness compiler.cfg.local ;
 IN: compiler.cfg.height
 
 ! Combine multiple stack height changes into one at the
diff --git a/basis/compiler/cfg/linearization/linearization.factor b/basis/compiler/cfg/linearization/linearization.factor
index 5ad8be2953..2e09e493db 100755
--- a/basis/compiler/cfg/linearization/linearization.factor
+++ b/basis/compiler/cfg/linearization/linearization.factor
@@ -12,20 +12,10 @@ IN: compiler.cfg.linearization
 ! Convert CFG IR to machine IR.
 GENERIC: linearize-insn ( basic-block insn -- )
 
-: linearize-insns ( bb insns -- )
-    dup instructions>> [ linearize-insn ] with each ;
-
-: gc? ( bb -- ? )
-    instructions>> [ ##allocation? ] any? ;
-
-: object-pointer-regs ( basic-block -- vregs )
-    live-in keys [ reg-class>> int-regs eq? ] filter ;
-
 : linearize-basic-block ( bb -- )
     [ number>> _label ]
-    [ dup gc? [ object-pointer-regs _gc ] [ drop ] if ]
-    [ linearize-insns ]
-    tri ;
+    [ dup instructions>> [ linearize-insn ] with each ]
+    bi ;
 
 M: insn linearize-insn , drop ;
 
@@ -85,6 +75,6 @@ M: ##dispatch linearize-insn
         bi
     ] { } make ;
 
-: build-mr ( cfg -- mr )
+: flatten-cfg ( cfg -- mr )
     [ linearize-basic-blocks ] [ word>> ] [ label>> ] tri
     <mr> ;
diff --git a/basis/compiler/cfg/liveness/liveness.factor b/basis/compiler/cfg/liveness/liveness.factor
index 72609cf4d9..6c40bb3782 100644
--- a/basis/compiler/cfg/liveness/liveness.factor
+++ b/basis/compiler/cfg/liveness/liveness.factor
@@ -76,6 +76,3 @@ SYMBOL: work-list
     H{ } clone live-outs set
     dup post-order add-to-work-list
     work-list get [ liveness-step ] slurp-deque ;
-
-: local-optimization ( cfg init-quot: ( live-in -- ) insn-quot: ( insns -- insns' ) -- cfg' )
-    [ dup ] 2dip '[ _ _ optimize-basic-block ] each-basic-block ;
\ No newline at end of file
diff --git a/basis/compiler/cfg/local/authors.txt b/basis/compiler/cfg/local/authors.txt
new file mode 100644
index 0000000000..d4f5d6b3ae
--- /dev/null
+++ b/basis/compiler/cfg/local/authors.txt
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/compiler/cfg/local/local.factor b/basis/compiler/cfg/local/local.factor
new file mode 100644
index 0000000000..bf336a8d2a
--- /dev/null
+++ b/basis/compiler/cfg/local/local.factor
@@ -0,0 +1,10 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: fry accessors kernel assocs compiler.cfg.liveness compiler.cfg.rpo ;
+IN: compiler.cfg.local
+
+: optimize-basic-block ( bb init-quot insn-quot -- )
+    [ '[ live-in keys @ ] ] [ '[ _ change-instructions drop ] ] bi* bi ; inline
+
+: local-optimization ( cfg init-quot: ( live-in -- ) insn-quot: ( insns -- insns' ) -- cfg' )
+    [ dup ] 2dip '[ _ _ optimize-basic-block ] each-basic-block ;
diff --git a/basis/compiler/cfg/mr/authors.txt b/basis/compiler/cfg/mr/authors.txt
new file mode 100644
index 0000000000..d4f5d6b3ae
--- /dev/null
+++ b/basis/compiler/cfg/mr/authors.txt
@@ -0,0 +1 @@
+Slava Pestov
\ No newline at end of file
diff --git a/basis/compiler/cfg/mr/mr.factor b/basis/compiler/cfg/mr/mr.factor
new file mode 100644
index 0000000000..49f7c793e5
--- /dev/null
+++ b/basis/compiler/cfg/mr/mr.factor
@@ -0,0 +1,14 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: compiler.cfg.linearization compiler.cfg.two-operand
+compiler.cfg.liveness compiler.cfg.gc-checks compiler.cfg.linear-scan
+compiler.cfg.stack-frame compiler.cfg.rpo ;
+IN: compiler.cfg.mr
+
+: build-mr ( cfg -- mr )
+    convert-two-operand
+    compute-liveness
+    insert-gc-checks
+    linear-scan
+    flatten-cfg
+    build-stack-frame ;
\ No newline at end of file
diff --git a/basis/compiler/cfg/rpo/rpo.factor b/basis/compiler/cfg/rpo/rpo.factor
index d01f5ee864..c6ea2ee8b1 100644
--- a/basis/compiler/cfg/rpo/rpo.factor
+++ b/basis/compiler/cfg/rpo/rpo.factor
@@ -34,6 +34,3 @@ SYMBOL: visited
 
 : each-basic-block ( cfg quot -- )
     [ reverse-post-order ] dip each ; inline
-
-: optimize-basic-block ( bb init-quot insn-quot -- )
-    [ '[ live-in keys @ ] ] [ '[ _ change-instructions drop ] ] bi* bi ; inline
diff --git a/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor b/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor
index bd0e539173..383bd2e637 100644
--- a/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor
+++ b/basis/compiler/cfg/stack-analysis/stack-analysis-tests.factor
@@ -31,7 +31,7 @@ IN: compiler.cfg.stack-analysis.tests
     dup check-for-redundant-ops ;
 
 : linearize ( cfg -- mr )
-    build-mr instructions>> ;
+    flatten-cfg instructions>> ;
 
 [ ] [ [ ] test-stack-analysis drop ] unit-test
 
diff --git a/basis/compiler/cfg/stack-analysis/stack-analysis.factor b/basis/compiler/cfg/stack-analysis/stack-analysis.factor
index dfc99883c4..c1ed2615c3 100644
--- a/basis/compiler/cfg/stack-analysis/stack-analysis.factor
+++ b/basis/compiler/cfg/stack-analysis/stack-analysis.factor
@@ -98,9 +98,13 @@ UNION: sync-if-back-edge
     ##compare-imm-branch
     ##dispatch ;
 
+SYMBOL: local-only?
+
+t local-only? set-global
+
 M: sync-if-back-edge visit
     basic-block get [ successors>> ] [ number>> ] bi
-    '[ number>> _ < ] any?
+    '[ number>> _ < local-only? get or ] any?
     [ sync-state ] when
     , ;
 
diff --git a/basis/compiler/cfg/value-numbering/value-numbering.factor b/basis/compiler/cfg/value-numbering/value-numbering.factor
index cc62c0f0c1..9f5473c62f 100644
--- a/basis/compiler/cfg/value-numbering/value-numbering.factor
+++ b/basis/compiler/cfg/value-numbering/value-numbering.factor
@@ -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.local
 compiler.cfg.liveness
 compiler.cfg.value-numbering.graph
 compiler.cfg.value-numbering.expressions
diff --git a/basis/compiler/cfg/write-barrier/write-barrier.factor b/basis/compiler/cfg/write-barrier/write-barrier.factor
index 52d5170138..b260b0464e 100644
--- a/basis/compiler/cfg/write-barrier/write-barrier.factor
+++ b/basis/compiler/cfg/write-barrier/write-barrier.factor
@@ -2,7 +2,7 @@
 ! 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
-compiler.cfg.liveness ;
+compiler.cfg.liveness compiler.cfg.local ;
 IN: compiler.cfg.write-barrier
 
 ! Eliminate redundant write barrier hits.
diff --git a/basis/compiler/compiler.factor b/basis/compiler/compiler.factor
index ae58c3bd3e..eee00bfccb 100644
--- a/basis/compiler/compiler.factor
+++ b/basis/compiler/compiler.factor
@@ -3,13 +3,20 @@
 USING: accessors kernel namespaces arrays sequences io words fry
 continuations vocabs assocs dlists definitions math graphs generic
 generic.single combinators deques search-deques macros
-source-files.errors stack-checker stack-checker.state
-stack-checker.inlining stack-checker.errors combinators.short-circuit
-compiler.errors compiler.units compiler.tree.builder
-compiler.tree.optimizer compiler.cfg.builder compiler.cfg.optimizer
-compiler.cfg.linearization compiler.cfg.two-operand
-compiler.cfg.linear-scan compiler.cfg.stack-frame compiler.cfg.rpo
-compiler.codegen compiler.utilities ;
+source-files.errors combinators.short-circuit
+
+stack-checker stack-checker.state stack-checker.inlining stack-checker.errors
+
+compiler.errors compiler.units compiler.utilities
+
+compiler.tree.builder
+compiler.tree.optimizer
+
+compiler.cfg.builder
+compiler.cfg.optimizer
+compiler.cfg.mr
+
+compiler.codegen ;
 IN: compiler
 
 SYMBOL: compile-queue
@@ -146,10 +153,7 @@ t compile-dependencies? set-global
 : backend ( nodes word -- )
     build-cfg [
         optimize-cfg
-        convert-two-operand
-        linear-scan
         build-mr
-        build-stack-frame
         generate
         save-asm
     ] each ;