1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays generic assocs inference inference.class
4 inference.dataflow inference.backend inference.state io kernel
5 math namespaces sequences vectors words quotations hashtables
6 combinators classes optimizer.def-use accessors ;
9 SYMBOL: class-substitutions
11 SYMBOL: literal-substitutions
13 SYMBOL: value-substitutions
15 SYMBOL: optimizer-changed
17 GENERIC: optimize-node* ( node -- node/t changed? )
19 : ?union ( assoc assoc/f -- assoc' )
20 dup assoc-empty? [ drop ] [ swap assoc-union ] if ;
22 : add-node-literals ( node assoc -- )
23 [ ?union ] curry change-literals drop ;
25 : add-node-classes ( node assoc -- )
26 [ ?union ] curry change-classes drop ;
28 : substitute-values ( node assoc -- )
33 [ >r in-d>> r> substitute-here ]
34 [ >r in-r>> r> substitute-here ]
35 [ >r out-d>> r> substitute-here ]
36 [ >r out-r>> r> substitute-here ]
40 : perform-substitutions ( node -- )
41 [ class-substitutions get add-node-classes ]
42 [ literal-substitutions get add-node-literals ]
43 [ value-substitutions get substitute-values ]
48 : optimize-children ( node -- )
49 [ optimize-nodes ] map-children ;
51 : optimize-node ( node -- node )
53 dup perform-substitutions
55 nip optimizer-changed on optimize-node
58 drop dup optimize-children
65 : optimize-nodes ( node -- newnode )
67 class-substitutions [ clone ] change
68 literal-substitutions [ clone ] change
69 [ optimize-node ] transform-nodes
71 ] with-scope optimizer-changed set ;
73 M: node optimize-node* drop t f ;
75 ! Post-inlining cleanup
76 : follow ( key assoc -- value )
77 2dup at* [ swap follow nip ] [ 2drop ] if ;
79 : union* ( assoc1 assoc2 -- assoc )
80 assoc-union [ keys ] keep
84 : update* ( assoc1 assoc2 -- )
85 #! Not very efficient.
88 : compute-value-substitutions ( #call/#merge #return/#values -- assoc )
89 [ out-d>> ] [ in-d>> ] bi* 2array unify-lengths flip
90 [ = not ] assoc-filter >hashtable ;
92 : cleanup-inlining ( #return/#values -- newnode changed? )
94 [ node-successor ] keep
96 [ nip classes>> class-substitutions get swap update ]
97 [ nip literals>> literal-substitutions get swap update ]
98 [ compute-value-substitutions value-substitutions get swap update* ]
99 [ drop node-successor ]
106 M: #return optimize-node* cleanup-inlining ;
109 M: #values optimize-node* cleanup-inlining ;
111 M: f set-node-successor 2drop ;
113 : splice-node ( old new -- )
114 dup splice-def-use last-node set-node-successor ;
116 : drop-inputs ( node -- #shuffle )
117 node-in-d clone \ #shuffle in-node ;
119 : optimizer-hooks ( node -- conditions )
120 param>> "optimizer-hooks" word-prop ;
122 : optimizer-hook ( node -- pair/f )
123 dup optimizer-hooks [ first call ] find 2nip ;
125 : optimize-hook ( node -- )
126 dup optimizer-hook second call ;
128 : define-optimizers ( word optimizers -- )
129 "optimizer-hooks" set-word-prop ;