From ae0b77a0c410da7e171e23c29acd0df2160508e7 Mon Sep 17 00:00:00 2001
From: Alex Vondrak <ajvondrak@gmail.com>
Date: Tue, 25 Dec 2012 09:19:35 -0800
Subject: [PATCH] compiler.cfg.ssa.cssa: split the definitions of ##phis so
 live-ranges don't interfere (issue #22)

See the explanation after the proof of Lemma 1 in "Revisiting Out-of-SSA
Translation for Correctness, Code Quality, and Efficiency" (Boissinot et
al.) for why this is necessary.
---
 basis/compiler/cfg/ssa/cssa/cssa.factor | 35 ++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/basis/compiler/cfg/ssa/cssa/cssa.factor b/basis/compiler/cfg/ssa/cssa/cssa.factor
index 7565be48b8..6c2d6587b9 100644
--- a/basis/compiler/cfg/ssa/cssa/cssa.factor
+++ b/basis/compiler/cfg/ssa/cssa/cssa.factor
@@ -15,19 +15,26 @@ IN: compiler.cfg.ssa.cssa
 ! selection, so it must keep track of representations when introducing
 ! new values.
 
-SYMBOL: copies
+SYMBOLS: edge-copies phi-copies ;
 
 : init-copies ( bb -- )
-    predecessors>> [ V{ } clone ] H{ } map>assoc copies set ;
+    V{ } clone phi-copies set
+    predecessors>> [ V{ } clone ] H{ } map>assoc edge-copies set ;
 
 :: convert-operand ( src pred rep -- dst )
     rep next-vreg-rep :> dst
-    { dst src } pred copies get at push
+    { dst src } pred edge-copies get at push
     dst ;
 
 :: convert-phi ( insn preds -- )
-    insn dst>> rep-of :> rep
+    insn dst>> :> dst
+    dst rep-of :> rep
     insn inputs>> :> inputs
+    rep next-vreg-rep :> dst'
+
+    { dst dst' } phi-copies get push
+    dst' insn dst<<
+
     preds [| pred |
         pred inputs [ pred rep convert-operand ] change-at
     ] each ;
@@ -35,11 +42,27 @@ SYMBOL: copies
 : insert-edge-copies ( from to copies -- )
     [ ##parallel-copy, ##branch, ] { } make insert-basic-block ;
 
-: insert-copies ( bb -- )
-    [ copies get ] dip '[
+: insert-all-edge-copies ( bb -- )
+    [ edge-copies get ] dip '[
         [ drop ] [ [ _ ] dip insert-edge-copies ] if-empty
     ] assoc-each ;
 
+: phi-copy-insn ( -- insn )
+    phi-copies get f \ ##parallel-copy boa ;
+
+: end-of-phis ( insns -- i )
+    [ [ ##phi? not ] find drop ] [ length ] bi or ;
+
+: insert-phi-copies ( bb -- )
+    [
+        [
+            [ drop phi-copy-insn ] [ end-of-phis ] [ ] tri insert-nth
+        ] change-instructions drop
+    ] if-has-phis ;
+
+: insert-copies ( bb -- )
+    [ insert-all-edge-copies ] [ insert-phi-copies ] bi ;
+
 : convert-phis ( bb -- )
     [ init-copies ]
     [ dup predecessors>> '[ _ convert-phi ] each-phi ]