]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/tree/debugger/debugger.factor
core, basis, extra: Remove DOS line endings from files.
[factor.git] / basis / compiler / tree / debugger / debugger.factor
1 ! Copyright (C) 2006, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs combinators
4 combinators.short-circuit compiler.tree compiler.tree.builder
5 compiler.tree.checker compiler.tree.cleanup
6 compiler.tree.combinators compiler.tree.dead-code
7 compiler.tree.def-use compiler.tree.escape-analysis
8 compiler.tree.identities compiler.tree.modular-arithmetic
9 compiler.tree.normalization compiler.tree.optimizer
10 compiler.tree.propagation compiler.tree.propagation.info
11 compiler.tree.recursive compiler.tree.tuple-unboxing effects fry
12 generic hints io kernel macros make match math namespaces
13 prettyprint prettyprint.config prettyprint.custom
14 prettyprint.sections quotations sequences sequences.private sets
15 sorting words ;
16 FROM: fry => _ ;
17 FROM: namespaces => set ;
18 RENAME: _ match => __
19 IN: compiler.tree.debugger
20
21 ! A simple tool for turning tree IR into quotations and
22 ! printing reports, for debugging purposes.
23
24 GENERIC: node>quot ( node -- )
25
26 MACRO: match-choose ( alist -- )
27     [ '[ _ ] ] assoc-map '[ _ match-cond ] ;
28
29 MATCH-VARS: ?a ?b ?c ;
30
31 : pretty-shuffle ( effect -- word/f )
32     [ in>> ] [ out>> ] bi 2array {
33         { { { } { } } [ ] }
34         { { { ?a } { ?a } } [ ] }
35         { { { ?a ?b } { ?a ?b } } [ ] }
36         { { { ?a ?b ?c } { ?a ?b ?c } } [ ] }
37         { { { ?a } { } } [ drop ] }
38         { { { ?a ?b } { } } [ 2drop ] }
39         { { { ?a ?b ?c } { } } [ 3drop ] }
40         { { { ?a } { ?a ?a } } [ dup ] }
41         { { { ?a ?b } { ?a ?b ?a ?b } } [ 2dup ] }
42         { { { ?a ?b ?c } { ?a ?b ?c ?a ?b ?c } } [ 3dup ] }
43         { { { ?a ?b } { ?a ?b ?a } } [ over ] }
44         { { { ?b ?a } { ?a ?b } } [ swap ] }
45         { { { ?b ?a ?c } { ?a ?b ?c } } [ swapd ] }
46         { { { ?a ?b } { ?a ?a ?b } } [ dupd ] }
47         { { { ?a ?b ?c } { ?a ?b ?c ?a } } [ pick ] }
48         { { { ?a ?b ?c } { ?c ?a ?b } } [ -rot ] }
49         { { { ?a ?b ?c } { ?b ?c ?a } } [ rot ] }
50         { { { ?a ?b } { ?b } } [ nip ] }
51         { { { ?a ?b ?c } { ?c } } [ 2nip ] }
52         { __ f }
53     } match-choose ;
54
55 TUPLE: shuffle-node { effect effect } ;
56
57 M: shuffle-node pprint* effect>> effect>string text ;
58
59 : (shuffle-effect) ( in out #shuffle -- effect )
60     mapping>> '[ _ at ] map [ >array ] bi@ <effect> ;
61
62 : shuffle-effect ( #shuffle -- effect )
63     [ in-d>> ] [ out-d>> ] [ ] tri (shuffle-effect) ;
64
65 : #>r? ( #shuffle -- ? )
66     {
67         [ in-d>> length 1 = ]
68         [ out-r>> length 1 = ]
69         [ in-r>> empty? ]
70         [ out-d>> empty? ]
71     } 1&& ;
72
73 : #r>? ( #shuffle -- ? )
74     {
75         [ in-d>> empty? ]
76         [ out-r>> empty? ]
77         [ in-r>> length 1 = ]
78         [ out-d>> length 1 = ]
79     } 1&& ;
80
81 SYMBOLS: >R R> ;
82
83 M: #shuffle node>quot
84     {
85         { [ dup #>r? ] [ drop \ >R , ] }
86         { [ dup #r>? ] [ drop \ R> , ] }
87         {
88             [ dup [ in-r>> empty? ] [ out-r>> empty? ] bi and ]
89             [
90                 shuffle-effect dup pretty-shuffle
91                 [ % ] [ shuffle-node boa , ] ?if
92             ]
93         }
94         [ drop "COMPLEX SHUFFLE" , ]
95     } cond ;
96
97 M: #push node>quot literal>> literalize , ;
98
99 M: #call node>quot word>> , ;
100
101 M: #call-recursive node>quot label>> id>> , ;
102
103 DEFER: nodes>quot
104
105 DEFER: label
106
107 M: #recursive node>quot
108     [ label>> id>> literalize , ]
109     [ child>> nodes>quot , \ label , ]
110     bi ;
111
112 M: #if node>quot
113     children>> [ nodes>quot ] map % \ if , ;
114
115 M: #dispatch node>quot
116     children>> [ nodes>quot ] map , \ dispatch , ;
117
118 M: #alien-invoke node>quot params>> , #alien-invoke , ;
119
120 M: #alien-indirect node>quot params>> , #alien-indirect , ;
121
122 M: #alien-assembly node>quot params>> , #alien-assembly , ;
123
124 M: #alien-callback node>quot
125     [ params>> , ] [ child>> nodes>quot , ] bi #alien-callback , ;
126
127 M: node node>quot drop ;
128
129 : nodes>quot ( node -- quot )
130     [ [ node>quot ] each ] [ ] make ;
131
132 GENERIC: optimized. ( quot/word -- )
133
134 M: word optimized. specialized-def optimized. ;
135
136 M: callable optimized.
137     build-tree optimize-tree nodes>quot
138     f length-limit [ . ] with-variable ;
139
140 SYMBOL: words-called
141 SYMBOL: generics-called
142 SYMBOL: methods-called
143 SYMBOL: intrinsics-called
144 SYMBOL: node-count
145
146 : make-report ( word/quot -- assoc )
147     [
148         build-tree optimize-tree
149
150         H{ } clone words-called ,,
151         H{ } clone generics-called ,,
152         H{ } clone methods-called ,,
153         H{ } clone intrinsics-called ,,
154
155         0 swap [
156             [ 1 + ] dip
157             dup #call? [
158                 word>> {
159                     { [ dup "intrinsic" word-prop ] [ intrinsics-called ] }
160                     { [ dup generic? ] [ generics-called ] }
161                     { [ dup method? ] [ methods-called ] }
162                     [ words-called ]
163                 } cond building get at inc-at
164             ] [ drop ] if
165         ] each-node
166         node-count ,,
167     ] H{ } make ;
168
169 : report. ( report -- )
170     [
171         "==== Total number of IR nodes:" print
172         node-count get .
173
174         {
175             { generics-called "==== Generic word calls:" }
176             { words-called "==== Ordinary word calls:" }
177             { methods-called "==== Non-inlined method calls:" }
178             { intrinsics-called "==== Open-coded intrinsic calls:" }
179         } [
180             nl print get keys natural-sort stack.
181         ] assoc-each
182     ] with-variables ;
183
184 : optimizer-report. ( word -- )
185     make-report report. ;
186
187 ! More utilities
188
189 : final-info ( quot -- seq )
190     build-tree
191     analyze-recursive
192     normalize
193     propagate
194     compute-def-use
195     dup check-nodes
196     last node-input-infos ;
197
198 : final-classes ( quot -- seq )
199     final-info [ class>> ] map ;
200
201 : final-literals ( quot -- seq )
202     final-info [ literal>> ] map ;
203
204 : cleaned-up-tree ( quot -- nodes )
205     [
206         build-tree
207         analyze-recursive
208         normalize
209         propagate
210         cleanup-tree
211         escape-analysis
212         unbox-tuples
213         apply-identities
214         compute-def-use
215         remove-dead-code
216         compute-def-use
217         optimize-modular-arithmetic
218     ] with-scope ;
219
220 : inlined? ( quot seq/word -- ? )
221     dup word? [ 1array ] when swap
222     [ cleaned-up-tree [ dup #call? [ word>> , ] [ drop ] if ] each-node ] V{ } make
223     intersect empty? ;