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