From ca2d64af6852672441fcabc488a01462592163f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lindqvist?= Date: Sun, 14 Jun 2015 02:44:45 +0200 Subject: [PATCH] compiler.cfg.ssa.destruction: try and sort the vreg pairs before elimination, this way you always get the same leader info --- .../ssa/destruction/destruction-docs.factor | 14 +++++++-- .../ssa/destruction/destruction-tests.factor | 31 +++++++++++++++---- .../cfg/ssa/destruction/destruction.factor | 12 +++++-- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/basis/compiler/cfg/ssa/destruction/destruction-docs.factor b/basis/compiler/cfg/ssa/destruction/destruction-docs.factor index d4f21aebe0..886861693f 100644 --- a/basis/compiler/cfg/ssa/destruction/destruction-docs.factor +++ b/basis/compiler/cfg/ssa/destruction/destruction-docs.factor @@ -1,6 +1,6 @@ USING: compiler.cfg compiler.cfg.instructions compiler.cfg.ssa.destruction.private compiler.cfg.ssa.interference help.markup -help.syntax kernel ; +help.syntax kernel sequences ; IN: compiler.cfg.ssa.destruction HELP: class-element-map @@ -25,7 +25,12 @@ HELP: copies 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 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. To ensure deterministic " { $link leader-map } " data, the pairs are sorted." } +{ $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." @@ -33,6 +38,9 @@ ARTICLE: "compiler.cfg.ssa.destruction" "SSA Destruction" "Instead of renaming vreg usages in the CFG, a map from vregs to canonical representatives is computed. This allows the register allocator to use the original SSA names to get reaching definitions." { "Useless " { $link ##copy } " instructions, and all " { $link ##phi } " instructions, are eliminated, so the register allocator does not have to remove any redundant operations." } { "This pass computes live sets and fills out the " { $slot "gc-roots" } " slots of GC maps with " { $vocab-link "compiler.cfg.liveness" } ", so the linear scan register allocator does not need to compute liveness again." } -} ; +} +$nl +"Main entry point:" +{ $subsections destruct-ssa } ; ABOUT: "compiler.cfg.ssa.destruction" diff --git a/basis/compiler/cfg/ssa/destruction/destruction-tests.factor b/basis/compiler/cfg/ssa/destruction/destruction-tests.factor index ce05ae4d28..217a1b7f91 100644 --- a/basis/compiler/cfg/ssa/destruction/destruction-tests.factor +++ b/basis/compiler/cfg/ssa/destruction/destruction-tests.factor @@ -1,8 +1,10 @@ -USING: alien.syntax compiler.cfg.def-use compiler.cfg.instructions -compiler.cfg.registers compiler.cfg.ssa.destruction -compiler.cfg.ssa.destruction.leaders +USING: alien.syntax assocs compiler.cfg.def-use +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 kernel make namespaces tools.test ; +cpu.architecture cpu.x86.assembler.operands grouping kernel make namespaces +random sequences tools.test ; +QUALIFIED: sets IN: compiler.cfg.ssa.destruction.tests ! cleanup-insn @@ -63,9 +65,9 @@ IN: compiler.cfg.ssa.destruction.tests } 0 insns>block block>cfg destruct-ssa ] unit-test -! must-eliminate-copy +! try-eliminate-copy { } [ - 10 10 must-eliminate-copy + 10 10 f try-eliminate-copy ] unit-test ! prepare-insn @@ -80,3 +82,20 @@ IN: compiler.cfg.ssa.destruction.tests 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 diff --git a/basis/compiler/cfg/ssa/destruction/destruction.factor b/basis/compiler/cfg/ssa/destruction/destruction.factor index c5ad460bdb..73e4d12594 100644 --- a/basis/compiler/cfg/ssa/destruction/destruction.factor +++ b/basis/compiler/cfg/ssa/destruction/destruction.factor @@ -7,7 +7,7 @@ compiler.cfg.registers compiler.cfg.rpo compiler.cfg.ssa.cssa compiler.cfg.ssa.destruction.leaders compiler.cfg.ssa.interference compiler.cfg.ssa.interference.live-ranges compiler.cfg.utilities -cpu.architecture kernel make namespaces sequences sets ; +cpu.architecture fry kernel make namespaces sequences sets sorting ; FROM: namespaces => set ; IN: compiler.cfg.ssa.destruction @@ -73,17 +73,23 @@ ERROR: vregs-shouldn't-interfere vreg1 vreg2 ; ] [ -rot coalesce-vregs drop ] if ] if ; +: try-eliminate-copies ( pairs must? -- ) + [ natural-sort ] dip '[ 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 [ t try-eliminate-copy ] with each ; + [ dst>> ] [ inputs>> values ] bi zip-scalar t try-eliminate-copies ; : prepare-coalescing ( cfg -- ) init-coalescing [ [ prepare-insn ] each ] simple-analysis ; : process-copies ( copies -- ) - [ f try-eliminate-copy ] assoc-each ; + >alist f try-eliminate-copies ; : perform-coalescing ( cfg -- ) prepare-coalescing copies get process-copies ;