]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler.cfg.ssa.destruction.coalescing: new vocab to refactor and 1361/head
authorBjörn Lindqvist <bjourne@gmail.com>
Mon, 15 Jun 2015 08:44:53 +0000 (10:44 +0200)
committerBjörn Lindqvist <bjourne@gmail.com>
Mon, 15 Jun 2015 10:28:31 +0000 (12:28 +0200)
simplify the prepare-insn code in compiler.cfg.ssa.destruction

basis/compiler/cfg/linearization/linearization.factor
basis/compiler/cfg/ssa/destruction/coalescing/coalescing-docs.factor [new file with mode: 0644]
basis/compiler/cfg/ssa/destruction/coalescing/coalescing-tests.factor [new file with mode: 0644]
basis/compiler/cfg/ssa/destruction/coalescing/coalescing.factor [new file with mode: 0644]
basis/compiler/cfg/ssa/destruction/destruction-docs.factor
basis/compiler/cfg/ssa/destruction/destruction-tests.factor
basis/compiler/cfg/ssa/destruction/destruction.factor
basis/compiler/cfg/ssa/destruction/leaders/leaders-docs.factor
basis/compiler/cfg/ssa/destruction/leaders/leaders.factor

index 998bcdfd09dcea21226e7a3b4cc9ca46b4c464ac..c20be464f1709ea4874c441abd88ea94221886c0 100644 (file)
@@ -74,5 +74,11 @@ SYMBOL: numbers
 : number-blocks ( bbs -- )
     H{ } zip-index-as numbers set ;
 
+: blocks>insns ( bbs -- insns )
+    [ instructions>> ] map concat ;
+
 : cfg>insns ( cfg -- insns )
-    linearization-order [ instructions>> ] map concat ;
+    linearization-order blocks>insns ;
+
+: cfg>insns-rpo ( cfg -- insns )
+    reverse-post-order blocks>insns ;
diff --git a/basis/compiler/cfg/ssa/destruction/coalescing/coalescing-docs.factor b/basis/compiler/cfg/ssa/destruction/coalescing/coalescing-docs.factor
new file mode 100644 (file)
index 0000000..a392c0d
--- /dev/null
@@ -0,0 +1,39 @@
+USING: compiler.cfg.instructions compiler.cfg.ssa.interference
+help.markup help.syntax kernel make sequences ;
+IN: compiler.cfg.ssa.destruction.coalescing
+
+HELP: class-element-map
+{ $var-description "Maps leaders to equivalence class elements which are sequences of " { $link vreg-info } " instances." } ;
+
+HELP: coalesce-elements
+{ $values { "merged" "??" } { "follower" "vreg" } { "leader" "vreg" } }
+{ $description "Delete follower's class, and set leaders's class to merged." } ;
+
+HELP: coalesce-insn
+{ $values { "insn" insn } }
+{ $description "Generic word supposed to be called in a " { $link make } " context which generates a list of eliminatable vreg copies. The word either eliminates copies immediately in case of " { $link ##phi } " and " { $link ##tagged>integer } " instructions or appends copies to the make sequence so that they are handled later by " { $link coalesce-cfg } "." } ;
+
+HELP: coalesce-vregs
+{ $values { "merged" "??" } { "follower" "vreg" } { "leader" "vreg" } }
+{ $description "Sets 'leader' as the leader of 'follower'." } ;
+
+HELP: try-eliminate-copy
+{ $values { "follower" "vreg" } { "leader" "vreg" } { "must?" boolean } }
+{ $description "Tries to eliminate a vreg copy from 'leader' to 'follower'. If 'must?' is " { $link t } " then a " { $link vregs-shouldn't-interfere } " error is thrown if the vregs interfere." }
+{ $see-also try-eliminate-copies vregs-interfere? } ;
+
+HELP: try-eliminate-copies
+{ $values { "pairs" "a sequence of vreg pairs" } { "must?" boolean } }
+{ $description "Tries to eliminate the vreg copies in the " { $link sequence } " 'pairs'. If 'must?' is " { $link t } " then a " { $link vregs-shouldn't-interfere } " error is thrown if any of the vregs interfere." }
+{ $see-also try-eliminate-copy } ;
+
+ARTICLE: "compiler.cfg.ssa.destruction.coalescing" "Vreg Coalescing"
+"This compiler pass eliminates redundant vreg copies."
+$nl
+"Main entry point:"
+{ $subsections coalesce-cfg }
+"Vreg copy elimination:"
+{ $subsections
+  try-eliminate-copies
+  try-eliminate-copy
+} ;
diff --git a/basis/compiler/cfg/ssa/destruction/coalescing/coalescing-tests.factor b/basis/compiler/cfg/ssa/destruction/coalescing/coalescing-tests.factor
new file mode 100644 (file)
index 0000000..4eecdb0
--- /dev/null
@@ -0,0 +1,49 @@
+USING: assocs compiler.cfg.def-use compiler.cfg.instructions
+compiler.cfg.ssa.destruction.coalescing compiler.cfg.ssa.destruction.leaders
+cpu.architecture grouping kernel make namespaces random sequences tools.test ;
+QUALIFIED: sets
+IN: compiler.cfg.ssa.destruction.coalescing.tests
+
+! init-coalescing
+{
+    H{ { 123 123 } { 77 77 } }
+} [
+    H{ { 123 "bb1" } { 77 "bb2" } } defs set
+    init-coalescing
+    leader-map get
+] unit-test
+
+! try-eliminate-copy
+{ } [
+    10 10 f try-eliminate-copy
+] unit-test
+
+! coalesce-insn
+{ V{ { 2 1 } } } [
+    [
+        T{ ##copy { src 1 } { dst 2 } { rep int-rep } } coalesce-insn
+    ] V{ } make
+] unit-test
+
+{ V{ { 3 4 } { 7 8 } } } [
+    [
+        T{ ##parallel-copy { values V{ { 3 4 } { 7 8 } } } } coalesce-insn
+    ] V{ } make
+] unit-test
+
+! All this work to make the 'values' order non-deterministic.
+: make-phi-inputs ( -- assoc )
+    H{ } clone [
+        { 2287 2288 } [
+            10 iota 1 sample first rot set-at
+        ] with each
+    ] keep ;
+
+{ t } [
+    10 [
+        { 2286 2287 2288 } sets:unique leader-map set
+        2286 make-phi-inputs ##phi new-insn
+        coalesce-insn
+        2286 leader
+    ] replicate all-equal?
+] unit-test
diff --git a/basis/compiler/cfg/ssa/destruction/coalescing/coalescing.factor b/basis/compiler/cfg/ssa/destruction/coalescing/coalescing.factor
new file mode 100644 (file)
index 0000000..80e066b
--- /dev/null
@@ -0,0 +1,79 @@
+USING: accessors arrays assocs compiler.cfg.def-use
+compiler.cfg.instructions compiler.cfg.linearization
+compiler.cfg.registers compiler.cfg.ssa.destruction.leaders
+compiler.cfg.ssa.interference cpu.architecture fry kernel make
+namespaces sequences sets sorting ;
+FROM: namespaces => set ;
+IN: compiler.cfg.ssa.destruction.coalescing
+
+: zip-scalar ( scalar seq -- pairs )
+    [ 2array ] with map ;
+
+SYMBOL: class-element-map
+
+: value-of ( vreg -- value )
+    dup insn-of dup ##tagged>integer? [ nip src>> ] [ drop ] if ;
+
+: init-coalescing ( -- )
+    defs get
+    [ keys unique leader-map set ]
+    [
+        [ [ dup dup value-of ] dip <vreg-info> 1array ] assoc-map
+        class-element-map set
+    ] bi ;
+
+: coalesce-elements ( merged follower leader -- )
+    class-element-map get [ delete-at ] [ set-at ] bi-curry bi* ;
+
+: coalesce-vregs ( merged follower leader -- )
+    2dup swap leader-map get set-at coalesce-elements ;
+
+: vregs-interfere? ( vreg1 vreg2 -- merged/f ? )
+    [ class-element-map get at ] bi@ sets-interfere? ;
+
+ERROR: vregs-shouldn't-interfere vreg1 vreg2 ;
+
+: try-eliminate-copy ( follower leader must? -- )
+    -rot leaders 2dup = [ 3drop ] [
+        2dup vregs-interfere? [
+            drop rot [ vregs-shouldn't-interfere ] [ 2drop ] if
+        ] [ -rot coalesce-vregs drop ] if
+    ] if ;
+
+: try-eliminate-copies ( pairs must? -- )
+    '[ first2 _ try-eliminate-copy ] each ;
+
+GENERIC: coalesce-insn ( insn -- )
+
+M: insn coalesce-insn drop ;
+
+M: alien-call-insn coalesce-insn drop ;
+
+M: vreg-insn coalesce-insn
+    [ temp-vregs [ leader-map get conjoin ] each ]
+    [
+        [ defs-vregs ] [ uses-vregs ] bi
+        2dup [ empty? not ] both? [
+            [ first ] bi@
+            2dup [ rep-of reg-class-of ] bi@ eq?
+            [ 2array , ] [ 2drop ] if
+        ] [ 2drop ] if
+    ] bi ;
+
+M: ##copy coalesce-insn
+    [ dst>> ] [ src>> ] bi 2array , ;
+
+M: ##parallel-copy coalesce-insn
+    values>> % ;
+
+M: ##tagged>integer coalesce-insn
+    [ dst>> ] [ src>> ] bi t try-eliminate-copy ;
+
+M: ##phi coalesce-insn
+    [ dst>> ] [ inputs>> values ] bi zip-scalar
+    natural-sort t try-eliminate-copies ;
+
+: coalesce-cfg ( cfg -- )
+    init-coalescing
+    cfg>insns-rpo [ [ coalesce-insn ] each ] V{ } make
+    f try-eliminate-copies ;
index 2fea4ed3ca536343c1bd79944b2779921dd5b4b0..b76cc9c13968de514abf76bc06970c232e7751ef 100644 (file)
@@ -3,35 +3,10 @@ compiler.cfg.ssa.destruction.private compiler.cfg.ssa.destruction.leaders
 compiler.cfg.ssa.interference help.markup help.syntax kernel sequences ;
 IN: compiler.cfg.ssa.destruction
 
-HELP: class-element-map
-{ $var-description "Maps leaders to equivalence class elements which are sequences of " { $link vreg-info } " instances." } ;
-
 HELP: cleanup-cfg
 { $values { "cfg" cfg } }
 { $description "In this step, " { $link ##parallel-copy } " instructions are substituted with more concreete " { $link ##copy } " instructions. " { $link ##phi } " instructions are removed here." } ;
 
-HELP: coalesce-elements
-{ $values { "merged" "??" } { "follower" "vreg" } { "leader" "vreg" } }
-{ $description "Delete follower's class, and set leaders's class to merged." } ;
-
-HELP: coalesce-vregs
-{ $values { "merged" "??" } { "follower" "vreg" } { "leader" "vreg" } }
-{ $description "Sets 'leader' as the leader of 'follower'." } ;
-
-HELP: copies
-{ $var-description "Sequence of copies (tuples of { vreg-dst vreg-src}) that maybe can be eliminated later." }
-{ $see-also init-coalescing } ;
-
-HELP: try-eliminate-copy
-{ $values { "follower" "vreg" } { "leader" "vreg" } { "must?" boolean } }
-{ $description "Tries to eliminate a vreg copy from 'leader' to 'follower'. If 'must?' is " { $link t } " then a " { $link vregs-shouldn't-interfere } " error is thrown if the vregs interfere." }
-{ $see-also try-eliminate-copies vregs-interfere? } ;
-
-HELP: try-eliminate-copies
-{ $values { "pairs" "a sequence of vreg pairs" } { "must?" boolean } }
-{ $description "Tries to eliminate the vreg copies in the " { $link sequence } " 'pairs'. If 'must?' is " { $link t } " then a " { $link vregs-shouldn't-interfere } " error is thrown if any of the vregs interfere." }
-{ $see-also try-eliminate-copy } ;
-
 ARTICLE: "compiler.cfg.ssa.destruction" "SSA Destruction"
 "Because of the design of the register allocator, this pass has three peculiar properties."
 { $list
@@ -41,12 +16,6 @@ ARTICLE: "compiler.cfg.ssa.destruction" "SSA Destruction"
 }
 $nl
 "Main entry point:"
-{ $subsections destruct-ssa }
-"Vreg copy elimination:"
-{ $subsections
-  perform-coalescing
-  try-eliminate-copies
-  try-eliminate-copy
-} ;
+{ $subsections destruct-ssa } ;
 
 ABOUT: "compiler.cfg.ssa.destruction"
index 661d567d4152a06b1d9f6ac5aa19fc3f7f5f29fb..2549134884e8b2196d453bf0b0217af29353864a 100644 (file)
@@ -1,11 +1,8 @@
-USING: alien.syntax assocs compiler.cfg.def-use
-compiler.cfg.instructions compiler.cfg.registers
+USING: alien.syntax compiler.cfg.instructions compiler.cfg.registers
 compiler.cfg.ssa.destruction compiler.cfg.ssa.destruction.leaders
 compiler.cfg.ssa.destruction.private compiler.cfg.utilities
-cpu.architecture cpu.x86.assembler.operands grouping kernel make math
-math.functions math.order math.ranges namespaces random sequences
-tools.test ;
-QUALIFIED: sets
+cpu.architecture cpu.x86.assembler.operands kernel make namespaces
+sequences tools.test ;
 IN: compiler.cfg.ssa.destruction.tests
 
 ! cleanup-insn
@@ -30,15 +27,6 @@ IN: compiler.cfg.ssa.destruction.tests
     [ cleanup-insn ] V{ } make
 ] unit-test
 
-! init-coalescing
-{
-    H{ { 123 123 } { 77 77 } }
-} [
-    H{ { 123 "bb1" } { 77 "bb2" } } defs set
-    init-coalescing
-    leader-map get
-] unit-test
-
 ! destruct-ssa
 { } [
     H{ { 36 23 } { 23 23 } } leader-map set
@@ -65,45 +53,3 @@ IN: compiler.cfg.ssa.destruction.tests
         }
     } 0 insns>block block>cfg destruct-ssa
 ] unit-test
-
-! try-eliminate-copy
-{ } [
-    10 10 f try-eliminate-copy
-] unit-test
-
-! prepare-insn
-{ V{ { 2 1 } } } [
-    V{ } clone copies set
-    T{ ##copy { src 1 } { dst 2 } { rep int-rep } } prepare-insn
-    copies get
-] unit-test
-
-{ V{ { 3 4 } { 7 8 } } } [
-    V{ } clone copies set
-    T{ ##parallel-copy { values V{ { 3 4 } { 7 8 } } } } prepare-insn
-    copies get
-] unit-test
-
-! All this work to make the 'values' order non-deterministic.
-: make-phi-inputs ( -- assoc )
-    H{ } clone [
-        { 2287 2288 } [
-            10 iota 1 sample first rot set-at
-        ] with each
-    ] keep ;
-
-{ t } [
-    10 [
-        { 2286 2287 2288 } sets:unique leader-map set
-        2286 make-phi-inputs ##phi new-insn
-        prepare-insn
-        2286 leader
-    ] replicate all-equal?
-] unit-test
-
-! Test is just to ensure the my-euler word compiles. See #1345
-: my-euler-step ( min m n -- min' )
-    dup sqrt 1 mod [ - min ] [ 2drop ] if ; inline
-
-: my-euler ( -- answer )
-    33 2500 [1,b] [ dup [1,b] [ my-euler-step ] with each ] each ;
index 8a0d41a9b2822f49f88cd9a13bbfa2ccc9ed0fd2..b4d325e49a3753ca3572840de845f71962ff437f 100644 (file)
@@ -1,97 +1,16 @@
 ! Copyright (C) 2009, 2011 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs combinators compiler.cfg.def-use
-compiler.cfg.dominance compiler.cfg.instructions
-compiler.cfg.liveness compiler.cfg.parallel-copy
-compiler.cfg.registers compiler.cfg.rpo compiler.cfg.ssa.cssa
-compiler.cfg.ssa.destruction.leaders
-compiler.cfg.ssa.interference
+USING: accessors assocs compiler.cfg.def-use compiler.cfg.dominance
+compiler.cfg.instructions compiler.cfg.liveness
+compiler.cfg.parallel-copy compiler.cfg.rpo compiler.cfg.ssa.cssa
+compiler.cfg.ssa.destruction.coalescing compiler.cfg.ssa.destruction.leaders
 compiler.cfg.ssa.interference.live-ranges compiler.cfg.utilities
-cpu.architecture fry kernel make namespaces sequences sets sorting ;
+kernel make sequences ;
 FROM: namespaces => set ;
 IN: compiler.cfg.ssa.destruction
 
-SYMBOL: class-element-map
-
 <PRIVATE
 
-SYMBOL: copies
-
-: value-of ( vreg -- value )
-    dup insn-of dup ##tagged>integer? [ nip src>> ] [ drop ] if ;
-
-: init-coalescing ( -- )
-    defs get
-    [ keys unique leader-map set ]
-    [
-        [ [ dup dup value-of ] dip <vreg-info> 1array ] assoc-map
-        class-element-map set
-    ] bi
-    V{ } clone copies set ;
-
-: coalesce-elements ( merged follower leader -- )
-    class-element-map get [ delete-at ] [ set-at ] bi-curry bi* ;
-
-: coalesce-vregs ( merged follower leader -- )
-    2dup swap leader-map get set-at coalesce-elements ;
-
-GENERIC: prepare-insn ( insn -- )
-
-M: insn prepare-insn drop ;
-
-M: alien-call-insn prepare-insn drop ;
-
-M: vreg-insn prepare-insn
-    [ temp-vregs [ leader-map get conjoin ] each ]
-    [
-        [ defs-vregs ] [ uses-vregs ] bi
-        2dup [ empty? not ] both? [
-            [ first ] bi@
-            2dup [ rep-of reg-class-of ] bi@ eq?
-            [ 2array copies get push ] [ 2drop ] if
-        ] [ 2drop ] if
-    ] bi ;
-
-M: ##copy prepare-insn
-    [ dst>> ] [ src>> ] bi 2array copies get push ;
-
-M: ##parallel-copy prepare-insn
-    values>> copies get push-all ;
-
-: leaders ( vreg1 vreg2 -- vreg1' vreg2' )
-    [ leader ] bi@ ;
-
-: vregs-interfere? ( vreg1 vreg2 -- merged/f ? )
-    [ class-element-map get at ] bi@ sets-interfere? ;
-
-ERROR: vregs-shouldn't-interfere vreg1 vreg2 ;
-
-: try-eliminate-copy ( follower leader must? -- )
-    -rot leaders 2dup = [ 3drop ] [
-        2dup vregs-interfere? [
-            drop rot [ vregs-shouldn't-interfere ] [ 2drop ] if
-        ] [ -rot coalesce-vregs drop ] if
-    ] if ;
-
-: try-eliminate-copies ( pairs must? -- )
-    '[ first2 _ try-eliminate-copy ] each ;
-
-M: ##tagged>integer prepare-insn
-    [ dst>> ] [ src>> ] bi t try-eliminate-copy ;
-
-: zip-scalar ( scalar seq -- pairs )
-    [ 2array ] with map ;
-
-M: ##phi prepare-insn
-    [ dst>> ] [ inputs>> values ] bi zip-scalar
-    natural-sort t try-eliminate-copies ;
-
-: prepare-coalescing ( cfg -- )
-    init-coalescing [ [ prepare-insn ] each ] simple-analysis ;
-
-: perform-coalescing ( cfg -- )
-    prepare-coalescing copies get f try-eliminate-copies ;
-
 GENERIC: cleanup-insn ( insn -- )
 
 : useful-copy? ( insn -- ? )
@@ -125,7 +44,7 @@ PRIVATE>
         compute-insns
         compute-live-sets
         compute-live-ranges
-        perform-coalescing
+        coalesce-cfg
         cleanup-cfg
         compute-live-sets
     } apply-passes ;
index 4cc85b3da6d1b4157c4078e02f198a7c4d616c2a..a8f6bc2ddc33b96f7b776ae5095a80f4ffec40b9 100644 (file)
@@ -1,4 +1,4 @@
-USING: compiler.cfg.ssa.destruction.private help.markup help.syntax math ;
+USING: compiler.cfg.ssa.destruction.coalescing help.markup help.syntax math ;
 IN: compiler.cfg.ssa.destruction.leaders
 
 HELP: ?leader
@@ -7,7 +7,7 @@ HELP: ?leader
 
 HELP: leader-map
 { $var-description "A map from vregs to canonical representatives due to coalescing done by SSA destruction. Used by liveness analysis and the register allocator, so we can use the original SSA names to get certain info (reaching definitions, representations). By default, each vreg is its own leader." }
-{ $see-also init-coalescing perform-coalescing } ;
+{ $see-also init-coalescing } ;
 
 ARTICLE: "compiler.cfg.ssa.destruction.leaders" "Leader book-keeping" "This vocab defines words for getting the leaders of vregs." ;
 
index bc2344de49a75a6fe572302cff82ef76a75f5903..291aadd571aaadb33afe8b5759d92cc4ed5a570e 100644 (file)
@@ -8,3 +8,6 @@ SYMBOL: leader-map
 : leader ( vreg -- vreg' ) leader-map get compress-path ;
 
 : ?leader ( vreg -- vreg' ) [ leader ] keep or ; inline
+
+: leaders ( vreg1 vreg2 -- vreg1' vreg2' )
+    [ leader ] bi@ ;