1 ! Copyright (C) 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: namespaces kernel accessors sequences fry assocs
10 compiler.cfg.dominance
11 compiler.cfg.instructions
13 compiler.cfg.renaming.functor
14 compiler.cfg.ssa.construction.tdmsc ;
15 FROM: namespaces => set ;
16 IN: compiler.cfg.ssa.construction
18 ! The phi placement algorithm is implemented in
19 ! compiler.cfg.ssa.construction.tdmsc.
21 ! The renaming algorithm is based on "Practical Improvements to
22 ! the Construction and Destruction of Static Single Assignment Form",
23 ! however we construct pruned SSA, not semi-pruned SSA.
25 ! http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.49.9683
29 ! Maps vregs to sets of basic blocks
32 ! Set of vregs defined in more than one basic block
35 : compute-insn-defs ( bb insn -- )
37 defs get [ conjoin-at ] [ drop ] [ at assoc-size 1 > ] 2tri
38 [ defs-multi get conjoin ] [ drop ] if
41 : compute-defs ( cfg -- )
43 H{ } clone defs-multi set
50 ! Maps basic blocks to sequences of vregs
51 SYMBOL: inserting-phi-nodes
53 : insert-phi-node-later ( vreg bb -- )
55 [ predecessors>> over '[ _ ] H{ } map>assoc \ ##phi new-insn ] keep
56 inserting-phi-nodes get push-at
59 : compute-phi-nodes-for ( vreg bbs -- )
60 keys [ insert-phi-node-later ] with merge-set-each ;
62 : compute-phi-nodes ( -- )
63 H{ } clone inserting-phi-nodes set
64 defs-multi get defs get '[ _ at compute-phi-nodes-for ] assoc-each ;
66 : insert-phi-nodes-in ( phis bb -- )
67 [ append ] change-instructions drop ;
69 : insert-phi-nodes ( -- )
70 inserting-phi-nodes get [ swap insert-phi-nodes-in ] assoc-each ;
72 SYMBOLS: stacks pushed ;
74 : init-renaming ( -- )
75 H{ } clone stacks set ;
77 : gen-name ( vreg -- vreg' )
79 dup pushed get 2dup key?
80 [ 2drop stacks get at set-last ]
81 [ conjoin stacks get push-at ]
84 : top-name ( vreg -- vreg' )
87 RENAMING: ssa-rename [ gen-name ] [ top-name ] [ ]
89 GENERIC: rename-insn ( insn -- )
92 [ ssa-rename-insn-uses ]
93 [ ssa-rename-insn-defs ]
97 ssa-rename-insn-defs ;
99 : rename-insns ( bb -- )
100 instructions>> [ rename-insn ] each ;
102 : rename-successor-phi ( phi bb -- )
103 swap inputs>> [ top-name ] change-at ;
105 : rename-successor-phis ( succ bb -- )
106 [ inserting-phi-nodes get at ] dip
107 '[ _ rename-successor-phi ] each ;
109 : rename-successors-phis ( bb -- )
110 [ successors>> ] keep '[ _ rename-successor-phis ] each ;
113 pushed get stacks get '[ drop _ at pop* ] assoc-each ;
115 : rename-in-block ( bb -- )
116 H{ } clone pushed set
118 [ rename-successors-phis ]
121 [ dom-children [ rename-in-block ] each ] dip
128 entry>> rename-in-block ;
132 : construct-ssa ( cfg -- cfg' )
134 [ compute-live-sets ]
135 [ compute-merge-sets ]
136 [ compute-defs compute-phi-nodes insert-phi-nodes ]