From e0f6d89ff1f331dbd05fc6b6947394f3f811719c Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@shill.local>
Date: Fri, 24 Jul 2009 05:30:30 -0500
Subject: [PATCH] compiler.cfg.value-numbering: insert ##copy instructions for
 instructions whose expressions simplify. While subsequent usages are replaced
 with the instruction computing the simplified vreg locally, global usages may
 exist of the original instruction. In this case, the ##copy is not dead

---
 .../value-numbering/rewrite/rewrite.factor    | 52 +++++++++----------
 .../value-numbering/simplify/simplify.factor  | 16 +++---
 .../value-numbering/value-numbering.factor    | 31 ++++++-----
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor
index fcd1b1c9ac..4b8ee2a1ae 100755
--- a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor
+++ b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor
@@ -20,13 +20,9 @@ IN: compiler.cfg.value-numbering.rewrite
 
 ! Outputs f to mean no change
 
-GENERIC: rewrite* ( insn -- insn/f )
+GENERIC: rewrite ( insn -- insn/f )
 
-: rewrite ( insn -- insn' )
-    dup [ number-values ] [ rewrite* ] bi
-    [ rewrite ] [ ] ?if ;
-
-M: insn rewrite* drop f ;
+M: insn rewrite drop f ;
 
 : ##branch-t? ( insn -- ? )
     dup ##compare-imm-branch? [
@@ -123,7 +119,7 @@ ERROR: bad-comparison ;
 : fold-compare-imm-branch ( insn -- insn/f )
     (fold-compare-imm) fold-branch ;
 
-M: ##compare-imm-branch rewrite*
+M: ##compare-imm-branch rewrite
     {
         { [ dup rewrite-boolean-comparison? ] [ rewrite-boolean-comparison ] }
         { [ dup rewrite-tagged-comparison? ] [ rewrite-tagged-comparison ] }
@@ -154,7 +150,7 @@ M: ##compare-imm-branch rewrite*
 : rewrite-self-compare-branch ( insn -- insn' )
     (rewrite-self-compare) fold-branch ;
 
-M: ##compare-branch rewrite*
+M: ##compare-branch rewrite
     {
         { [ dup src1>> vreg-small-constant? ] [ t >compare-imm-branch ] }
         { [ dup src2>> vreg-small-constant? ] [ f >compare-imm-branch ] }
@@ -185,7 +181,7 @@ M: ##compare-branch rewrite*
 : rewrite-self-compare ( insn -- insn' )
     dup (rewrite-self-compare) >boolean-insn ;
 
-M: ##compare rewrite*
+M: ##compare rewrite
     {
         { [ dup src1>> vreg-small-constant? ] [ t >compare-imm ] }
         { [ dup src2>> vreg-small-constant? ] [ f >compare-imm ] }
@@ -196,7 +192,7 @@ M: ##compare rewrite*
 : fold-compare-imm ( insn -- insn' )
     dup (fold-compare-imm) >boolean-insn ;
 
-M: ##compare-imm rewrite*
+M: ##compare-imm rewrite
     {
         { [ dup rewrite-redundant-comparison? ] [ rewrite-redundant-comparison ] }
         { [ dup rewrite-tagged-comparison? ] [ rewrite-tagged-comparison ] }
@@ -238,7 +234,7 @@ M: ##shl-imm constant-fold* drop shift ;
     ] dip
     over small-enough? [ new-insn ] [ 2drop 2drop f ] if ; inline
 
-M: ##add-imm rewrite*
+M: ##add-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         { [ dup reassociate? ] [ \ ##add-imm reassociate ] }
@@ -249,7 +245,7 @@ M: ##add-imm rewrite*
     [ dst>> ] [ src1>> ] [ src2>> neg ] tri dup small-enough?
     [ \ ##add-imm new-insn ] [ 3drop f ] if ;
 
-M: ##sub-imm rewrite*
+M: ##sub-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         [ sub-imm>add-imm ]
@@ -261,7 +257,7 @@ M: ##sub-imm rewrite*
 : strength-reduce-mul? ( insn -- ? )
     src2>> power-of-2? ;
 
-M: ##mul-imm rewrite*
+M: ##mul-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         { [ dup strength-reduce-mul? ] [ strength-reduce-mul ] }
@@ -269,40 +265,40 @@ M: ##mul-imm rewrite*
         [ drop f ]
     } cond ;
 
-M: ##and-imm rewrite*
+M: ##and-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         { [ dup reassociate? ] [ \ ##and-imm reassociate ] }
         [ drop f ]
     } cond ;
 
-M: ##or-imm rewrite*
+M: ##or-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         { [ dup reassociate? ] [ \ ##or-imm reassociate ] }
         [ drop f ]
     } cond ;
 
-M: ##xor-imm rewrite*
+M: ##xor-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         { [ dup reassociate? ] [ \ ##xor-imm reassociate ] }
         [ drop f ]
     } cond ;
 
-M: ##shl-imm rewrite*
+M: ##shl-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         [ drop f ]
     } cond ;
 
-M: ##shr-imm rewrite*
+M: ##shr-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         [ drop f ]
     } cond ;
 
-M: ##sar-imm rewrite*
+M: ##sar-imm rewrite
     {
         { [ dup constant-fold? ] [ constant-fold ] }
         [ drop f ]
@@ -327,7 +323,7 @@ M: ##sar-imm rewrite*
         [ 2drop f ]
     } cond ; inline
 
-M: ##add rewrite* \ ##add-imm rewrite-arithmetic-commutative ;
+M: ##add rewrite \ ##add-imm rewrite-arithmetic-commutative ;
 
 : subtraction-identity? ( insn -- ? )
     [ src1>> ] [ src2>> ] bi [ vreg>vn ] bi@ eq?  ;
@@ -335,22 +331,22 @@ M: ##add rewrite* \ ##add-imm rewrite-arithmetic-commutative ;
 : rewrite-subtraction-identity ( insn -- insn' )
     dst>> 0 \ ##load-immediate new-insn ;
 
-M: ##sub rewrite*
+M: ##sub rewrite
     {
         { [ dup subtraction-identity? ] [ rewrite-subtraction-identity ] }
         [ \ ##sub-imm rewrite-arithmetic ]
     } cond ;
 
-M: ##mul rewrite* \ ##mul-imm rewrite-arithmetic-commutative ;
+M: ##mul rewrite \ ##mul-imm rewrite-arithmetic-commutative ;
 
-M: ##and rewrite* \ ##and-imm rewrite-arithmetic-commutative ;
+M: ##and rewrite \ ##and-imm rewrite-arithmetic-commutative ;
 
-M: ##or rewrite* \ ##or-imm rewrite-arithmetic-commutative ;
+M: ##or rewrite \ ##or-imm rewrite-arithmetic-commutative ;
 
-M: ##xor rewrite* \ ##xor-imm rewrite-arithmetic-commutative ;
+M: ##xor rewrite \ ##xor-imm rewrite-arithmetic-commutative ;
 
-M: ##shl rewrite* \ ##shl-imm rewrite-arithmetic ;
+M: ##shl rewrite \ ##shl-imm rewrite-arithmetic ;
 
-M: ##shr rewrite* \ ##shr-imm rewrite-arithmetic ;
+M: ##shr rewrite \ ##shr-imm rewrite-arithmetic ;
 
-M: ##sar rewrite* \ ##sar-imm rewrite-arithmetic ;
+M: ##sar rewrite \ ##sar-imm rewrite-arithmetic ;
diff --git a/basis/compiler/cfg/value-numbering/simplify/simplify.factor b/basis/compiler/cfg/value-numbering/simplify/simplify.factor
index 5934643acc..3e1f6e393b 100644
--- a/basis/compiler/cfg/value-numbering/simplify/simplify.factor
+++ b/basis/compiler/cfg/value-numbering/simplify/simplify.factor
@@ -120,14 +120,12 @@ M: binary-expr simplify*
 
 M: expr simplify* drop f ;
 
-: simplify ( expr -- vn )
+: simplify ( expr -- simplified? vn )
     dup simplify* {
-        { [ dup not ] [ drop expr>vn ] }
-        { [ dup expr? ] [ expr>vn nip ] }
-        { [ dup integer? ] [ nip ] }
-    } cond ;
+        { [ dup not ] [ drop expr>vn f ] }
+        { [ dup expr? ] [ expr>vn nip t ] }
+        { [ dup integer? ] [ nip t ] }
+    } cond swap ;
 
-GENERIC: number-values ( insn -- )
-
-M: ##flushable number-values [ >expr simplify ] [ dst>> ] bi set-vn ;
-M: insn number-values drop ;
+: number-values ( insn -- simplified? )
+    [ >expr simplify ] [ dst>> set-vn ] bi ;
diff --git a/basis/compiler/cfg/value-numbering/value-numbering.factor b/basis/compiler/cfg/value-numbering/value-numbering.factor
index 0c9616b4e5..0688d81109 100644
--- a/basis/compiler/cfg/value-numbering/value-numbering.factor
+++ b/basis/compiler/cfg/value-numbering/value-numbering.factor
@@ -1,10 +1,10 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces assocs biassocs classes kernel math accessors
-sorting sets sequences fry
+USING: namespaces assocs kernel accessors
+sorting sets sequences
 compiler.cfg
 compiler.cfg.rpo
-compiler.cfg.renaming
+compiler.cfg.instructions
 compiler.cfg.value-numbering.graph
 compiler.cfg.value-numbering.expressions
 compiler.cfg.value-numbering.simplify
@@ -12,20 +12,27 @@ compiler.cfg.value-numbering.rewrite ;
 IN: compiler.cfg.value-numbering
 
 ! Local value numbering. Predecessors must be recomputed after this
-: vreg>vreg-mapping ( -- assoc )
-    vregs>vns get [ keys ] keep
-    '[ dup _ [ at ] [ value-at ] bi ] H{ } map>assoc ;
+: >copy ( insn -- ##copy )
+    dst>> dup vreg>vn vn>vreg \ ##copy new-insn ;
 
-: rename-uses ( insns -- )
-    vreg>vreg-mapping renamings [
-        [ rename-insn-uses ] each
-    ] with-variable ;
+: rewrite-loop ( insn -- insn' )
+    dup rewrite [ rewrite-loop ] [ ] ?if ;
+
+GENERIC: process-instruction ( insn -- insn' )
+
+M: ##flushable process-instruction
+    dup rewrite
+    [ process-instruction ]
+    [ dup number-values [ >copy ] when ] ?if ;
+
+M: insn process-instruction
+    dup rewrite
+    [ process-instruction ] [ ] ?if ;
 
 : value-numbering-step ( insns -- insns' )
     init-value-graph
     init-expressions
-    [ rewrite ] map
-    dup rename-uses ;
+    [ process-instruction ] map ;
 
 : value-numbering ( cfg -- cfg' )
     [ value-numbering-step ] local-optimization cfg-changed ;