1 ! Copyright (C) 2008, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry accessors kernel sequences sequences.private assocs
4 words namespaces classes.algebra combinators
5 combinators.short-circuit classes classes.tuple
6 classes.tuple.private continuations arrays alien.c-types math
7 math.private slots generic definitions stack-checker.dependencies
9 compiler.tree.propagation.info
10 compiler.tree.propagation.nodes
11 compiler.tree.propagation.slots
12 compiler.tree.propagation.inlining
13 compiler.tree.propagation.constraints ;
14 IN: compiler.tree.propagation.simple
16 ! Propagation for straight-line code.
18 M: #introduce propagate-before
19 out-d>> [ object-info swap set-value-info ] each ;
21 M: #push propagate-before
22 [ literal>> <literal-info> ] [ out-d>> first ] bi
25 : refine-value-infos ( classes values -- )
26 [ refine-value-info ] 2each ;
28 : class-infos ( classes -- infos )
29 [ <class-info> ] map ;
31 : set-value-infos ( infos values -- )
32 [ set-value-info ] 2each ;
34 M: #declare propagate-before
35 #! We need to force the caller word to recompile when the
36 #! classes mentioned in the declaration are redefined, since
37 #! now we're making assumptions but their definitions.
39 [ depends-on-conditionally ]
40 [ <class-info> swap refine-value-info ]
44 : predicate-constraints ( value class boolean-value -- constraint )
45 [ [ is-instance-of ] dip t--> ]
46 [ [ class-not is-instance-of ] dip f--> ]
49 : custom-constraints ( #call quot -- )
50 [ [ in-d>> ] [ out-d>> ] bi append ] dip
51 with-datastack first assume ;
53 : compute-constraints ( #call word -- )
54 dup "constraints" word-prop [ nip custom-constraints ] [
56 [ [ in-d>> first ] [ out-d>> first ] bi ]
57 [ "predicating" word-prop ] bi*
58 swap predicate-constraints assume
62 : call-outputs-quot ( #call word -- infos )
63 [ in-d>> [ value-info ] map ] [ "outputs" word-prop ] bi*
66 : literal-inputs? ( #call -- ? )
67 in-d>> [ value-info literal?>> ] all? ;
69 : input-classes-match? ( #call word -- ? )
70 [ in-d>> ] [ "input-classes" word-prop ] bi*
71 [ [ value-info literal>> ] dip instance? ] 2all? ;
73 : foldable-call? ( #call word -- ? )
75 [ nip "foldable" word-prop ]
76 [ drop literal-inputs? ]
77 [ input-classes-match? ]
80 : (fold-call) ( #call word -- info )
81 [ [ out-d>> ] [ in-d>> [ value-info literal>> ] map ] bi ] [ '[ _ execute ] ] bi*
82 '[ _ _ with-datastack [ <literal-info> ] map nip ]
83 [ drop length [ object-info ] replicate ]
86 : fold-call ( #call word -- )
87 [ (fold-call) ] [ drop out-d>> ] 2bi set-value-infos ;
89 : predicate-output-infos/literal ( info class -- info )
91 '[ _ _ instance? <literal-info> ]
95 : predicate-output-infos/class ( info class -- info )
96 [ class>> ] dip compare-classes
97 dup +incomparable+ eq? [ drop object-info ] [ <literal-info> ] if ;
99 : predicate-output-infos ( info class -- info )
101 [ predicate-output-infos/literal ]
102 [ predicate-output-infos/class ]
105 : propagate-predicate ( #call word -- infos )
106 #! We need to force the caller word to recompile when the class
107 #! is redefined, since now we're making assumptions but the
108 #! class definition itself.
109 [ in-d>> first value-info ]
110 [ "predicating" word-prop ] bi*
111 [ nip depends-on-conditionally ]
112 [ predicate-output-infos 1array ] 2bi ;
114 : default-output-value-infos ( #call word -- infos )
115 "default-output-classes" word-prop
116 [ class-infos ] [ out-d>> length object-info <repetition> ] ?if ;
118 : output-value-infos ( #call word -- infos )
120 { [ dup \ <tuple-boa> eq? ] [ drop propagate-<tuple-boa> ] }
121 { [ dup sequence-constructor? ] [ propagate-sequence-constructor ] }
122 { [ dup predicate? ] [ propagate-predicate ] }
123 { [ dup "outputs" word-prop ] [ call-outputs-quot ] }
124 [ default-output-value-infos ]
127 M: #call propagate-before
129 { [ 2dup foldable-call? ] [ fold-call ] }
130 { [ 2dup do-inlining ] [
131 [ output-value-infos ] [ drop out-d>> ] 2bi refine-value-infos
134 [ [ output-value-infos ] [ drop out-d>> ] 2bi set-value-infos ]
135 [ compute-constraints ]
140 M: #call annotate-node
141 dup [ in-d>> ] [ out-d>> ] bi append (annotate-node) ;
143 : propagate-input-classes ( node input-classes -- )
144 class-infos swap in-d>> refine-value-infos ;
146 M: #call propagate-after
147 dup word>> "input-classes" word-prop dup
148 [ propagate-input-classes ] [ 2drop ] if ;
150 : propagate-alien-invoke ( node -- )
151 [ out-d>> ] [ params>> return>> ] bi
152 [ drop ] [ c-type-class <class-info> swap first set-value-info ] if-void ;
154 M: #alien-node propagate-before propagate-alien-invoke ;
156 M: #return annotate-node dup in-d>> (annotate-node) ;