1 ! Copyright (C) 2010 Slava Pestov.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: arrays assocs compiler.cfg.instructions
4 compiler.cfg.registers compiler.cfg.renaming.functor
5 compiler.cfg.representations.conversion
6 compiler.cfg.representations.preferred compiler.cfg.rpo kernel
7 make namespaces sequences ;
8 IN: compiler.cfg.representations.rewrite
10 ! Insert conversions. This introduces new temporaries, so we need
11 ! to rename opearands too.
15 :: (emit-def-conversion) ( dst preferred required -- new-dst' )
16 ! If an instruction defines a register with representation 'required',
17 ! but the register has preferred representation 'preferred', then
18 ! we rename the instruction's definition to a new register, which
19 ! becomes the input of a conversion instruction.
20 dst required next-vreg-rep [ preferred required emit-conversion ] keep ;
22 :: (emit-use-conversion) ( src preferred required -- new-src' )
23 ! If an instruction uses a register with representation 'required',
24 ! but the register has preferred representation 'preferred', then
25 ! we rename the instruction's input to a new register, which
26 ! becomes the output of a conversion instruction.
27 preferred required eq? [ src ] [
28 src required alternatives get [
29 required next-vreg-rep :> new-src
30 [ new-src ] 2dip preferred emit-conversion
35 SYMBOLS: renaming-set needs-renaming? ;
37 : init-renaming-set ( -- )
39 renaming-set get delete-all ;
41 : no-renaming ( vreg -- )
42 dup 2array renaming-set get push ;
44 : record-renaming ( from to -- )
45 2array renaming-set get push needs-renaming? on ;
47 :: (compute-renaming-set) ( vreg required quot: ( vreg preferred required -- new-vreg ) -- )
48 vreg rep-of :> preferred
49 preferred required eq?
51 [ vreg vreg preferred required quot call record-renaming ] if ; inline
53 : emit-use-conversion ( insn -- )
54 [ [ (emit-use-conversion) ] (compute-renaming-set) ] each-use-rep ;
56 : no-use-conversion ( insn -- )
57 [ drop no-renaming ] each-use-rep ;
59 : emit-def-conversion ( insn -- )
60 [ [ (emit-def-conversion) ] (compute-renaming-set) ] each-def-rep ;
62 : no-def-conversion ( insn -- )
63 [ drop no-renaming ] each-def-rep ;
65 : converted-value ( vreg -- vreg' )
66 renaming-set get pop first2 [ assert= ] dip ;
68 RENAMING: convert [ converted-value ] [ converted-value ] [ ]
70 : perform-renaming ( insn -- )
72 renaming-set get reverse! drop
73 [ convert-insn-uses ] [ convert-insn-defs ] bi
74 renaming-set get length 0 assert=
77 GENERIC: conversions-for-insn ( insn -- )
79 M: ##phi conversions-for-insn , ;
81 M: ##copy conversions-for-insn , ;
83 M: insn conversions-for-insn , ;
85 : conversions-for-block ( insns -- insns )
87 alternatives get clear-assoc
88 [ conversions-for-insn ] each
91 : insert-conversions ( cfg -- )
92 H{ } clone alternatives set
93 V{ } clone renaming-set set
94 [ conversions-for-block ] simple-optimization ;