1 ! Copyright (C) 2006, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: classes inference inference.dataflow io kernel
4 kernel.private math.parser namespaces optimizer prettyprint
5 prettyprint.backend sequences words arrays match macros
6 assocs sequences.private optimizer.specializers generic
7 combinators sorting math quotations accessors ;
10 ! A simple tool for turning dataflow IR into quotations, for
13 GENERIC: node>quot ( ? node -- )
15 TUPLE: comment node text ;
18 "( " over comment-text " )" 3append
19 swap comment-node present-text ;
21 : comment, ( ? node text -- )
22 rot [ \ comment boa , ] [ 2drop ] if ;
24 : values% ( prefix values -- )
28 value-literal unparse %
34 : effect-str ( node -- str )
36 " " over in-d>> values%
37 " r: " over in-r>> values%
39 " " over out-d>> values%
40 " r: " swap out-r>> values%
43 MACRO: match-choose ( alist -- )
44 [ [ ] curry ] assoc-map [ match-cond ] curry ;
46 MATCH-VARS: ?a ?b ?c ;
48 : pretty-shuffle ( in out -- word/f )
50 { { { ?a } { } } drop }
51 { { { ?a ?b } { } } 2drop }
52 { { { ?a ?b ?c } { } } 3drop }
53 { { { ?a } { ?a ?a } } dup }
54 { { { ?a ?b } { ?a ?b ?a ?b } } 2dup }
55 { { { ?a ?b ?c } { ?a ?b ?c ?a ?b ?c } } 3dup }
56 { { { ?a ?b } { ?a ?b ?a } } over }
57 { { { ?b ?a } { ?a ?b } } swap }
58 { { { ?a ?b ?c } { ?a ?b ?c ?a } } pick }
59 { { { ?a ?b ?c } { ?c ?a ?b } } -rot }
60 { { { ?a ?b ?c } { ?b ?c ?a } } rot }
61 { { { ?a ?b } { ?b } } nip }
66 dup [ in-d>> ] [ out-d>> ] bi pretty-shuffle
67 [ , ] [ >r drop t r> ] if*
68 dup effect-str "#shuffle: " prepend comment, ;
70 : pushed-literals ( node -- seq )
71 out-d>> [ value-literal literalize ] map ;
73 M: #push node>quot nip pushed-literals % ;
77 : #call>quot ( ? node -- )
79 [ dup effect-str ] [ "empty call" ] if comment, ;
81 M: #call node>quot #call>quot ;
83 M: #call-label node>quot #call>quot ;
87 dup param>> literalize ,
88 dup #label-loop? "#loop: " "#label: " ?
89 over param>> name>> append comment,
91 node-child swap dataflow>quot , \ call , ;
94 [ "#if" comment, ] 2keep
95 children>> swap [ dataflow>quot ] curry map %
98 M: #dispatch node>quot
99 [ "#dispatch" comment, ] 2keep
100 children>> swap [ dataflow>quot ] curry map ,
103 M: #>r node>quot nip in-d>> length \ >r <array> % ;
105 M: #r> node>quot nip out-d>> length \ r> <array> % ;
111 dup param>> unparse %
116 : (dataflow>quot) ( ? node -- )
118 2dup node>quot successor>> (dataflow>quot)
123 : dataflow>quot ( node ? -- quot )
124 [ swap (dataflow>quot) ] [ ] make ;
126 : optimized-quot. ( quot ? -- )
127 #! Print dataflow IR for a quotation. Flag indicates if
128 #! annotations should be printed or not.
129 >r dataflow optimize r> dataflow>quot pprint nl ;
131 : optimized-word. ( word ? -- ) >r specialized-def r> optimized-quot. ;
134 SYMBOL: generics-called
135 SYMBOL: methods-called
136 SYMBOL: intrinsics-called
139 : dataflow>report ( node -- alist )
141 H{ } clone words-called set
142 H{ } clone generics-called set
143 H{ } clone methods-called set
144 H{ } clone intrinsics-called set
150 { [ dup "intrinsics" word-prop over "if-intrinsics" word-prop or ] [ intrinsics-called ] }
151 { [ dup generic? ] [ generics-called ] }
152 { [ dup method-body? ] [ methods-called ] }
154 } cond 1 -rot get at+
162 : quot-optimize-report ( quot -- report )
163 dataflow optimize dataflow>report ;
165 : word-optimize-report ( word -- report )
166 def>> quot-optimize-report ;
168 : report. ( report -- )
170 "==== Total number of dataflow nodes:" print
174 { generics-called "==== Generic word calls:" }
175 { words-called "==== Ordinary word calls:" }
176 { methods-called "==== Non-inlined method calls:" }
177 { intrinsics-called "==== Open-coded intrinsic calls:" }
179 nl print get keys natural-sort stack.
183 : optimizer-report. ( word -- )
184 word-optimize-report report. ;