USING: compiler.cfg compiler.cfg.instructions
-compiler.cfg.ssa.destruction.private help.markup help.syntax ;
+compiler.cfg.ssa.destruction.private compiler.cfg.ssa.interference help.markup
+help.syntax kernel ;
IN: compiler.cfg.ssa.destruction
HELP: class-element-map
-{ $var-description "Maps leaders to equivalence class elements." } ;
+{ $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: maybe-eliminate-copy
-{ $values { "vreg1" "vreg" } { "vreg2" "vreg" } }
-{ $description "Eliminate a copy if possible." }
-{ $see-also must-eliminate-copy } ;
-
-HELP: must-eliminate-copy
-{ $values { "vreg1" "vreg" } { "vreg2" "vreg" } }
-{ $description "Eliminates a copy." }
-{ $see-also maybe-eliminate-copy } ;
+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? } ;
ARTICLE: "compiler.cfg.ssa.destruction" "SSA Destruction"
"Because of the design of the register allocator, this pass has three peculiar properties."
compiler.cfg.ssa.destruction.leaders
compiler.cfg.ssa.interference
compiler.cfg.ssa.interference.live-ranges compiler.cfg.utilities
-cpu.architecture kernel locals make namespaces sequences sets ;
+cpu.architecture kernel make namespaces sequences sets ;
FROM: namespaces => set ;
IN: compiler.cfg.ssa.destruction
<PRIVATE
-! Sequence of vreg pairs
SYMBOL: copies
: value-of ( vreg -- value )
] bi
V{ } clone copies set ;
-: coalesce-elements ( merged vreg1 vreg2 -- )
- ! delete leader1's class, and set leader2's class to merged.
+: coalesce-elements ( merged follower leader -- )
class-element-map get [ delete-at ] [ set-at ] bi-curry bi* ;
-: coalesce-vregs ( merged leader1 leader2 -- )
+: coalesce-vregs ( merged follower leader -- )
2dup swap leader-map get set-at coalesce-elements ;
GENERIC: prepare-insn ( insn -- )
ERROR: vregs-shouldn't-interfere vreg1 vreg2 ;
-:: must-eliminate-copy ( vreg1 vreg2 -- )
- vreg1 vreg2 = [
- vreg1 vreg2 vregs-interfere?
- [ vreg1 vreg2 vregs-shouldn't-interfere ]
- [ vreg1 vreg2 coalesce-vregs ]
- if
- ] unless ;
+: 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 ;
M: ##tagged>integer prepare-insn
- [ dst>> ] [ src>> ] bi leaders must-eliminate-copy ;
+ [ dst>> ] [ src>> ] bi t try-eliminate-copy ;
M: ##phi prepare-insn
- [ dst>> ] [ inputs>> values ] bi
- [ leaders must-eliminate-copy ] with each ;
+ [ dst>> ] [ inputs>> values ] bi [ t try-eliminate-copy ] with each ;
: prepare-coalescing ( cfg -- )
init-coalescing [ [ prepare-insn ] each ] simple-analysis ;
-:: maybe-eliminate-copy ( vreg1 vreg2 -- )
- vreg1 vreg2 = [
- vreg1 vreg2 vregs-interfere?
- [ drop ] [ vreg1 vreg2 coalesce-vregs ] if
- ] unless ;
-
: process-copies ( copies -- )
- [ leaders maybe-eliminate-copy ] assoc-each ;
+ [ f try-eliminate-copy ] assoc-each ;
: perform-coalescing ( cfg -- )
prepare-coalescing copies get process-copies ;