1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry kernel sequences assocs accessors
4 math.intervals arrays classes.algebra combinators columns
5 stack-checker.branches locals math namespaces
8 compiler.tree.combinators
9 compiler.tree.propagation.info
10 compiler.tree.propagation.nodes
11 compiler.tree.propagation.simple
12 compiler.tree.propagation.constraints ;
14 FROM: assocs => change-at ;
15 IN: compiler.tree.propagation.branches
17 ! For conditionals, an assoc of child node # --> constraint
18 GENERIC: child-constraints ( node -- seq )
20 M: #if child-constraints
21 in-d>> first [ =t ] [ =f ] bi 2array ;
23 M: #dispatch child-constraints
24 children>> length f <repetition> ;
26 ! There is an important invariant here, either no flags are set
27 ! in live-branches, exactly one is set, or all are set.
29 GENERIC: live-branches ( #branch -- indices )
32 in-d>> first value-info class>> {
33 { [ dup null-class? ] [ { f f } ] }
34 { [ dup true-class? ] [ { t f } ] }
35 { [ dup false-class? ] [ { f t } ] }
39 M: #dispatch live-branches
40 [ children>> ] [ in-d>> first value-info ] bi {
41 { [ dup class>> null-class? ] [ drop length f <array> ] }
42 { [ dup literal>> integer? not ] [ drop length t <array> ] }
43 { [ 2dup literal>> swap bounds-check? not ] [ drop length t <array> ] }
44 [ literal>> swap length f <array> [ [ t ] 2dip set-nth ] keep ]
47 : live-children ( #branch -- children )
48 [ children>> ] [ live-branches>> ] bi select-children ;
50 SYMBOL: infer-children-data
52 : copy-value-info ( -- )
53 value-infos [ H{ } clone suffix ] change
54 constraints [ H{ } clone suffix ] change ;
56 : no-value-info ( -- )
60 : infer-children ( node -- )
61 [ live-children ] [ child-constraints ] bi [
64 [ copy-value-info assume (propagate) ]
65 [ 2drop no-value-info ]
68 ] 2map infer-children-data set ;
70 : compute-phi-input-infos ( phi-in -- phi-info )
71 infer-children-data get
76 [ drop null-info ] [ value-info ] if
81 : annotate-phi-inputs ( #phi -- )
82 dup phi-in-d>> compute-phi-input-infos >>phi-info-d drop ;
84 : merge-value-infos ( infos outputs -- )
85 [ [ value-infos-union ] map ] dip set-value-infos ;
87 SYMBOL: condition-value
89 M: #phi propagate-before ( #phi -- )
90 [ annotate-phi-inputs ]
91 [ [ phi-info-d>> flip ] [ out-d>> ] bi merge-value-infos ]
94 :: update-constraints ( new old -- )
95 new [| key value | key old [ value union ] change-at ] assoc-each ;
97 : include-child-constraints ( i -- )
98 infer-children-data get nth constraints swap at last
99 constraints get last update-constraints ;
101 : branch-phi-constraints ( output values booleans -- )
106 drop condition-value get
107 [ [ =t ] [ =t ] bi* <--> ]
108 [ [ =f ] [ =f ] bi* <--> ] 2bi /\
114 drop condition-value get
115 [ [ =t ] [ =f ] bi* <--> ]
116 [ [ =f ] [ =t ] bi* <--> ] 2bi /\
123 condition-value get =t /\
131 condition-value get =f /\
139 condition-value get =t /\
147 condition-value get =f /\
156 [ [ =f ] bi@ <--> ] 2bi /\
157 0 include-child-constraints
165 [ [ =f ] bi@ <--> ] 2bi /\
166 1 include-child-constraints
172 M: #phi propagate-after ( #phi -- )
173 condition-value get [
176 [ phi-info-d>> flip ] tri
178 [ possible-boolean-values ] map
179 branch-phi-constraints
183 M: #branch propagate-around
184 dup live-branches >>live-branches
185 [ infer-children ] [ annotate-node ] bi ;
187 M: #if propagate-around
188 [ in-d>> first condition-value set ] [ call-next-method ] bi ;
190 M: #dispatch propagate-around
191 condition-value off call-next-method ;