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
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."
"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"
-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
} 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
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
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
] [ -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 ;