]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/tree/propagation/simple/simple.factor
Fix comments to be ! not #!.
[factor.git] / basis / compiler / tree / propagation / simple / simple.factor
1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types arrays assocs classes
4 classes.algebra classes.algebra.private classes.maybe
5 classes.tuple.private combinators combinators.short-circuit
6 compiler.tree compiler.tree.propagation.constraints
7 compiler.tree.propagation.info
8 compiler.tree.propagation.inlining
9 compiler.tree.propagation.nodes compiler.tree.propagation.slots
10 continuations fry kernel sequences stack-checker.dependencies
11 words ;
12 IN: compiler.tree.propagation.simple
13
14 M: #introduce propagate-before
15     out-d>> [ object-info swap set-value-info ] each ;
16
17 M: #push propagate-before
18     [ literal>> <literal-info> ] [ out-d>> first ] bi
19     set-value-info ;
20
21 : refine-value-infos ( classes values -- )
22     [ refine-value-info ] 2each ;
23
24 : class-infos ( classes -- infos )
25     [ <class-info> ] map ;
26
27 : set-value-infos ( infos values -- )
28     [ set-value-info ] 2each ;
29
30 GENERIC: add-depends-on-class ( obj -- )
31
32 M: class add-depends-on-class
33     add-depends-on-conditionally ;
34
35 M: maybe add-depends-on-class
36     class>> add-depends-on-class ;
37
38 M: anonymous-union add-depends-on-class
39     members>> [ add-depends-on-class ] each ;
40
41 M: anonymous-intersection add-depends-on-class
42     participants>> [ add-depends-on-class ] each ;
43
44 M: #declare propagate-before
45     ! We need to force the caller word to recompile when the
46     ! classes mentioned in the declaration are redefined, since
47     ! now we're making assumptions about their definitions.
48     declaration>> [
49         [ add-depends-on-class ]
50         [ <class-info> swap refine-value-info ]
51         bi
52     ] assoc-each ;
53
54 : predicate-constraints ( value class boolean-value -- constraint )
55     [ [ is-instance-of ] dip t--> ]
56     [ [ class-not is-instance-of ] dip f--> ]
57     3bi /\ ;
58
59 : custom-constraints ( #call quot -- )
60     [ [ in-d>> ] [ out-d>> ] bi append ] dip
61     with-datastack first assume ;
62
63 : compute-constraints ( #call word -- )
64     dup "constraints" word-prop [ nip custom-constraints ] [
65         dup predicate? [
66             [ [ in-d>> first ] [ out-d>> first ] bi ]
67             [ "predicating" word-prop ] bi*
68             swap predicate-constraints assume
69         ] [ 2drop ] if
70     ] if* ;
71
72 ERROR: invalid-outputs #call infos ;
73
74 : check-outputs ( #call infos -- infos )
75     over out-d>> over [ length ] bi@ =
76     [ nip ] [ invalid-outputs ] if ;
77
78 : call-outputs-quot ( #call word -- infos )
79     dupd
80     [ in-d>> [ value-info ] map ]
81     [ "outputs" word-prop ] bi*
82     with-datastack check-outputs ;
83
84 : literal-inputs? ( #call -- ? )
85     in-d>> [ value-info literal?>> ] all? ;
86
87 : input-classes-match? ( #call word -- ? )
88     [ in-d>> ] [ "input-classes" word-prop ] bi*
89     [ [ value-info literal>> ] dip instance? ] 2all? ;
90
91 : foldable-call? ( #call word -- ? )
92     {
93         [ nip foldable? ]
94         [ drop literal-inputs? ]
95         [ input-classes-match? ]
96     } 2&& ;
97
98 : (fold-call) ( #call word -- info )
99     [ [ out-d>> ] [ in-d>> [ value-info literal>> ] map ] bi ] [ '[ _ execute ] ] bi*
100     '[ _ _ with-datastack [ <literal-info> ] map nip ]
101     [ drop length [ object-info ] replicate ]
102     recover ;
103
104 : fold-call ( #call word -- )
105     [ (fold-call) ] [ drop out-d>> ] 2bi set-value-infos ;
106
107 : predicate-output-infos/literal ( info class -- info )
108     [ literal>> ] dip
109     '[ _ _ instance? <literal-info> ]
110     [ drop object-info ]
111     recover ;
112
113 : predicate-output-infos/class ( info class -- info )
114     [ class>> ] dip evaluate-class-predicate
115     dup +incomparable+ eq? [ drop object-info ] [ <literal-info> ] if ;
116
117 : predicate-output-infos ( info class -- info )
118     over literal?>>
119     [ predicate-output-infos/literal ]
120     [ predicate-output-infos/class ]
121     if ;
122
123 : propagate-predicate ( #call word -- infos )
124     ! We need to force the caller word to recompile when the class
125     ! is redefined, since now we're making assumptions but the
126     ! class definition itself.
127     [ in-d>> first value-info ]
128     [ "predicating" word-prop ] bi*
129     [ nip add-depends-on-conditionally ]
130     [ predicate-output-infos 1array ] 2bi ;
131
132 : default-output-value-infos ( #call word -- infos )
133     "default-output-classes" word-prop
134     [ class-infos ] [ out-d>> length object-info <repetition> ] ?if ;
135
136 : output-value-infos ( #call word -- infos )
137     {
138         { [ dup \ <tuple-boa> eq? ] [ drop propagate-<tuple-boa> ] }
139         { [ dup sequence-constructor? ] [ propagate-sequence-constructor ] }
140         { [ dup predicate? ] [ propagate-predicate ] }
141         { [ dup "outputs" word-prop ] [ call-outputs-quot ] }
142         [ default-output-value-infos ]
143     } cond ;
144
145 M: #call propagate-before
146     dup word>> {
147         { [ 2dup foldable-call? ] [ fold-call ] }
148         { [ 2dup do-inlining ] [
149             [ output-value-infos ] [ drop out-d>> ] 2bi refine-value-infos
150         ] }
151         [
152             [ [ output-value-infos ] [ drop out-d>> ] 2bi set-value-infos ]
153             [ compute-constraints ]
154             2bi
155         ]
156     } cond ;
157
158 M: #call annotate-node
159     dup [ in-d>> ] [ out-d>> ] bi append (annotate-node) ;
160
161 : propagate-input-classes ( node input-classes -- )
162     class-infos swap in-d>> refine-value-infos ;
163
164 M: #call propagate-after
165     dup word>> "input-classes" word-prop dup
166     [ propagate-input-classes ] [ 2drop ] if ;
167
168 : propagate-alien-invoke ( node -- )
169     [ out-d>> ] [ params>> return>> ] bi
170     [ drop ] [ c-type-class <class-info> swap first set-value-info ] if-void ;
171
172 M: #alien-node propagate-before propagate-alien-invoke ;
173
174 M: #alien-callback propagate-around child>> (propagate) ;
175
176 M: #return annotate-node dup in-d>> (annotate-node) ;