]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/tests/optimizer.factor
Delete empty unit tests files, remove 1- and 1+, reorder IN: lines in a lot of places...
[factor.git] / basis / compiler / tests / optimizer.factor
1 USING: accessors arrays compiler.units generic hashtables
2 stack-checker kernel kernel.private math prettyprint sequences
3 sbufs strings tools.test vectors words sequences.private
4 quotations classes classes.algebra classes.tuple.private
5 continuations growable namespaces hints alien.accessors
6 compiler.tree.builder compiler.tree.optimizer sequences.deep
7 compiler definitions ;
8 IN: compiler.tests.optimizer
9
10 GENERIC: xyz ( obj -- obj )
11 M: array xyz xyz ;
12
13 [ t ] [ M\ array xyz optimized? ] unit-test
14
15 ! Test predicate inlining
16 : pred-test-1 ( a -- b c )
17     dup fixnum? [
18         dup integer? [ "integer" ] [ "nope" ] if
19     ] [
20         "not a fixnum"
21     ] if ;
22
23 [ 1 "integer" ] [ 1 pred-test-1 ] unit-test
24
25 TUPLE: pred-test ;
26
27 : pred-test-2 ( a -- b c )
28     dup tuple? [
29         dup pred-test? [ "pred-test" ] [ "nope" ] if
30     ] [
31         "not a tuple"
32     ] if ;
33
34 [ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-2 ] unit-test
35
36 : pred-test-3 ( a -- b c )
37     dup pred-test? [
38         dup tuple? [ "pred-test" ] [ "nope" ] if
39     ] [
40         "not a tuple"
41     ] if ;
42
43 [ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-3 ] unit-test
44
45 : inline-test ( a -- b )
46     "nom" = ;
47
48 [ t ] [ "nom" inline-test ] unit-test
49 [ f ] [ "shayin" inline-test ] unit-test
50 [ f ] [ 3 inline-test ] unit-test
51
52 : fixnum-declarations ( a -- b ) >fixnum 24 shift 1234 bitxor ;
53
54 [ ] [ 1000000 fixnum-declarations . ] unit-test
55
56 ! regression
57
58 : literal-not-branch ( -- ) 0 not [ ] [ ] if ;
59
60 [ ] [ literal-not-branch ] unit-test
61
62 ! regression
63
64 : bad-kill-1 ( a b -- c d e ) [ 3 f ] [ dup bad-kill-1 ] if ; inline recursive
65 : bad-kill-2 ( a b -- c d ) bad-kill-1 drop ;
66
67 [ 3 ] [ t bad-kill-2 ] unit-test
68
69 ! regression
70 : (the-test) ( x -- y ) dup 0 > [ 1- (the-test) ] when ; inline recursive
71 : the-test ( -- x y ) 2 dup (the-test) ;
72
73 [ 2 0 ] [ the-test ] unit-test
74
75 ! regression
76 : (double-recursion) ( start end -- )
77     < [
78         6 1 (double-recursion)
79         3 2 (double-recursion)
80     ] when ; inline recursive
81
82 : double-recursion ( -- ) 0 2 (double-recursion) ;
83
84 [ ] [ double-recursion ] unit-test
85
86 ! regression
87 : double-label-1 ( a b c -- d )
88     [ f double-label-1 ] [ swap nth-unsafe ] if ; inline recursive
89
90 : double-label-2 ( a -- b )
91     dup array? [ ] [ ] if 0 t double-label-1 ;
92
93 [ 0 ] [ 10 double-label-2 ] unit-test
94
95 ! regression
96 GENERIC: void-generic ( obj -- * )
97 : breakage ( -- * ) "hi" void-generic ;
98 [ t ] [ \ breakage optimized? ] unit-test
99 [ breakage ] must-fail
100
101 ! regression
102 : branch-fold-regression-0 ( m -- n )
103     t [ ] [ 1 + branch-fold-regression-0 ] if ; inline recursive
104
105 : branch-fold-regression-1 ( -- m )
106     10 branch-fold-regression-0 ;
107
108 [ 10 ] [ branch-fold-regression-1 ] unit-test
109
110 ! another regression
111 : constant-branch-fold-0 ( -- value ) "hey" ; foldable
112 : constant-branch-fold-1 ( -- ? ) constant-branch-fold-0 "hey" = ; inline
113 [ 1 ] [ [ constant-branch-fold-1 [ 1 ] [ 2 ] if ] compile-call ] unit-test
114
115 ! another regression
116 : foo ( -- value ) f ;
117 : bar ( -- ? ) foo 4 4 = and ;
118 [ f ] [ bar ] unit-test
119
120 ! compiling <tuple> with a non-literal class failed
121 : <tuple>-regression ( class -- tuple ) <tuple> ;
122
123 [ t ] [ \ <tuple>-regression optimized? ] unit-test
124
125 GENERIC: foozul ( a -- b )
126 M: reversed foozul ;
127 M: integer foozul ;
128 M: slice foozul ;
129
130 [ t ] [
131     reversed \ foozul specific-method
132     reversed \ foozul method
133     eq?
134 ] unit-test
135
136 ! regression
137 : constant-fold-2 ( -- value ) f ; foldable
138 : constant-fold-3 ( -- value ) 4 ; foldable
139
140 [ f t ] [
141     [ constant-fold-2 constant-fold-3 4 = ] compile-call
142 ] unit-test
143
144 : constant-fold-4 ( -- value ) f ; foldable
145 : constant-fold-5 ( -- value ) f ; foldable
146
147 [ f ] [
148     [ constant-fold-4 constant-fold-5 or ] compile-call
149 ] unit-test
150
151 [ 5 ] [ 5 [ 0 + ] compile-call ] unit-test
152 [ 5 ] [ 5 [ 0 swap + ] compile-call ] unit-test
153
154 [ 5 ] [ 5 [ 0 - ] compile-call ] unit-test
155 [ -5 ] [ 5 [ 0 swap - ] compile-call ] unit-test
156 [ 0 ] [ 5 [ dup - ] compile-call ] unit-test
157
158 [ 5 ] [ 5 [ 1 * ] compile-call ] unit-test
159 [ 5 ] [ 5 [ 1 swap * ] compile-call ] unit-test
160 [ 0 ] [ 5 [ 0 * ] compile-call ] unit-test
161 [ 0 ] [ 5 [ 0 swap * ] compile-call ] unit-test
162 [ -5 ] [ 5 [ -1 * ] compile-call ] unit-test
163 [ -5 ] [ 5 [ -1 swap * ] compile-call ] unit-test
164
165 [ 0 ] [ 5 [ 1 mod ] compile-call ] unit-test
166 [ 0 ] [ 5 [ 1 rem ] compile-call ] unit-test
167
168 [ 5 ] [ 5 [ -1 bitand ] compile-call ] unit-test
169 [ 0 ] [ 5 [ 0 bitand ] compile-call ] unit-test
170 [ 5 ] [ 5 [ -1 swap bitand ] compile-call ] unit-test
171 [ 0 ] [ 5 [ 0 swap bitand ] compile-call ] unit-test
172 [ 5 ] [ 5 [ dup bitand ] compile-call ] unit-test
173
174 [ 5 ] [ 5 [ 0 bitor ] compile-call ] unit-test
175 [ -1 ] [ 5 [ -1 bitor ] compile-call ] unit-test
176 [ 5 ] [ 5 [ 0 swap bitor ] compile-call ] unit-test
177 [ -1 ] [ 5 [ -1 swap bitor ] compile-call ] unit-test
178 [ 5 ] [ 5 [ dup bitor ] compile-call ] unit-test
179
180 [ 5 ] [ 5 [ 0 bitxor ] compile-call ] unit-test
181 [ 5 ] [ 5 [ 0 swap bitxor ] compile-call ] unit-test
182 [ -6 ] [ 5 [ -1 bitxor ] compile-call ] unit-test
183 [ -6 ] [ 5 [ -1 swap bitxor ] compile-call ] unit-test
184 [ 0 ] [ 5 [ dup bitxor ] compile-call ] unit-test
185
186 [ 0 ] [ 5 [ 0 swap shift ] compile-call ] unit-test
187 [ 5 ] [ 5 [ 0 shift ] compile-call ] unit-test
188
189 [ f ] [ 5 [ dup < ] compile-call ] unit-test
190 [ t ] [ 5 [ dup <= ] compile-call ] unit-test
191 [ f ] [ 5 [ dup > ] compile-call ] unit-test
192 [ t ] [ 5 [ dup >= ] compile-call ] unit-test
193
194 [ t ] [ 5 [ dup eq? ] compile-call ] unit-test
195 [ t ] [ 5 [ dup = ] compile-call ] unit-test
196 [ t ] [ 5 [ dup number= ] compile-call ] unit-test
197 [ t ] [ \ vector [ \ vector = ] compile-call ] unit-test
198
199 GENERIC: detect-number ( obj -- obj )
200 M: number detect-number ;
201
202 [ 10 f [ <array> 0 + detect-number ] compile-call ] must-fail
203
204 ! Regression
205 [ 4 [ + ] ] [ 2 2 [ [ + ] [ call ] keep ] compile-call ] unit-test
206
207 ! Regression
208 USE: sorting
209 USE: binary-search
210 USE: binary-search.private
211
212 : old-binsearch ( elt quot: ( -- ) seq -- elt quot i )
213     dup length 1 <= [
214         from>>
215     ] [
216         [ midpoint swap call ] 3keep roll dup zero?
217         [ drop dup from>> swap midpoint@ + ]
218         [ drop dup midpoint@ head-slice old-binsearch ] if
219     ] if ; inline recursive
220
221 [ 10 ] [
222     10 20 >vector <flat-slice>
223     [ [ - ] swap old-binsearch ] compile-call 2nip
224 ] unit-test
225
226 ! Regression
227 : empty-compound ( -- ) ;
228
229 : node-successor-f-bug ( x -- * )
230     [ 3 throw ] [ empty-compound ] compose [ 3 throw ] if ;
231
232 [ t ] [ \ node-successor-f-bug optimized? ] unit-test
233
234 [ ] [ [ new ] build-tree optimize-tree drop ] unit-test
235
236 [ ] [ [ <tuple> ] build-tree optimize-tree drop ] unit-test
237
238 ! Regression
239 : lift-throw-tail-regression ( obj -- obj str )
240     dup integer? [ "an integer" ] [
241         dup string? [ "a string" ] [
242             "error" throw
243         ] if
244     ] if ;
245
246 [ t ] [ \ lift-throw-tail-regression optimized? ] unit-test
247 [ 3 "an integer" ] [ 3 lift-throw-tail-regression ] unit-test
248 [ "hi" "a string" ] [ "hi" lift-throw-tail-regression ] unit-test
249
250 : lift-loop-tail-test-1 ( a quot: ( -- ) -- )
251     over even? [
252         [ [ 3 - ] dip call ] keep lift-loop-tail-test-1
253     ] [
254         over 0 < [
255             2drop
256         ] [
257             [ [ 2 - ] dip call ] keep lift-loop-tail-test-1
258         ] if
259     ] if ; inline recursive
260
261 : lift-loop-tail-test-2 ( -- a b c )
262     10 [ ] lift-loop-tail-test-1 1 2 3 ;
263
264 \ lift-loop-tail-test-2 def>> must-infer
265
266 [ 1 2 3 ] [ lift-loop-tail-test-2 ] unit-test
267
268 ! Forgot a recursive inline check
269 : recursive-inline-hang ( a -- a )
270     dup array? [ recursive-inline-hang ] when ;
271
272 HINTS: recursive-inline-hang array ;
273
274 : recursive-inline-hang-1 ( -- a )
275     { } recursive-inline-hang ;
276
277 [ t ] [ \ recursive-inline-hang-1 optimized? ] unit-test
278
279 DEFER: recursive-inline-hang-3
280
281 : recursive-inline-hang-2 ( a -- a )
282     dup array? [ recursive-inline-hang-3 ] when ;
283
284 HINTS: recursive-inline-hang-2 array ;
285
286 : recursive-inline-hang-3 ( a -- a )
287     dup array? [ recursive-inline-hang-2 ] when ;
288
289 HINTS: recursive-inline-hang-3 array ;
290
291 ! Regression
292 [ ] [ { 3append-as } compile ] unit-test
293
294 ! Wow
295 : counter-example ( a b c d -- a' b' c' d' )
296     dup 0 > [ 1 - [ rot 2 * ] dip counter-example ] when ; inline recursive
297
298 : counter-example' ( -- a' b' c' d' )
299     1 2 3.0 3 counter-example ;
300
301 [ 2 4 6.0 0 ] [ counter-example' ] unit-test
302
303 : member-test ( obj -- ? ) { + - * / /i } member? ;
304
305 \ member-test def>> must-infer
306 [ ] [ \ member-test build-tree optimize-tree drop ] unit-test
307 [ t ] [ \ + member-test ] unit-test
308 [ f ] [ \ append member-test ] unit-test
309
310 ! Infinite expansion
311 TUPLE: cons car cdr ;
312
313 UNION: improper-list cons POSTPONE: f ;
314
315 PREDICATE: list < improper-list
316     [ cdr>> list instance? ] [ t ] if* ;
317
318 [ t ] [
319     T{ cons f 1 T{ cons f 2 T{ cons f 3 f } } }
320     [ list instance? ] compile-call
321 ] unit-test
322
323 ! Regression
324 : interval-inference-bug ( obj -- obj x )
325     dup "a" get { array-capacity } declare >=
326     [ dup "b" get { array-capacity } declare >= [ 3 ] [ 4 ] if ] [ 5 ] if ;
327
328 [ t ] [ \ interval-inference-bug optimized? ] unit-test
329
330 [ ] [ 1 "a" set 2 "b" set ] unit-test
331 [ 2 3 ] [ 2 interval-inference-bug ] unit-test
332 [ 1 4 ] [ 1 interval-inference-bug ] unit-test
333 [ 0 5 ] [ 0 interval-inference-bug ] unit-test
334
335 : aggressive-flush-regression ( a -- b )
336     f over [ <array> drop ] dip 1 + ;
337
338 [ 1.0 aggressive-flush-regression drop ] must-fail
339
340 [ 1 [ "hi" + drop ] compile-call ] must-fail
341
342 [ "hi" f [ <array> drop ] compile-call ] must-fail
343
344 TUPLE: some-tuple x ;
345
346 : allot-regression ( a -- b )
347     [ ] curry some-tuple boa ;
348
349 [ T{ some-tuple f [ 3 ] } ] [ 3 allot-regression ] unit-test
350
351 [ 1 ] [ B{ 0 0 0 0 } [ 0 alien-signed-4 1 + ] compile-call ] unit-test
352 [ 1 ] [ B{ 0 0 0 0 } [ 0 alien-unsigned-4 1 + ] compile-call ] unit-test
353 [ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-signed-8 1 + ] compile-call ] unit-test
354 [ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-unsigned-8 1 + ] compile-call ] unit-test
355 [ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-signed-cell 1 + ] compile-call ] unit-test
356 [ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-unsigned-cell 1 + ] compile-call ] unit-test
357
358 : deep-find-test ( seq -- ? ) [ 5 = ] deep-find ;
359
360 [ 5 ] [ { 1 2 { 3 { 4 5 } } } deep-find-test ] unit-test
361 [ f ] [ { 1 2 { 3 { 4 } } } deep-find-test ] unit-test
362
363 [ B{ 0 1 2 3 4 5 6 7 } ] [ [ 8 [ ] B{ } map-as ] compile-call ] unit-test
364
365 [ 0 ] [ 1234 [ { fixnum } declare -64 shift ] compile-call ] unit-test
366
367 ! Loop detection problem found by doublec
368 SYMBOL: counter
369
370 DEFER: loop-bbb
371
372 : loop-aaa ( -- )
373     counter inc counter get 2 < [ loop-bbb ] when ; inline recursive
374
375 : loop-bbb ( -- )
376     [ loop-aaa ] with-scope ; inline recursive
377
378 : loop-ccc ( -- ) loop-bbb ;
379
380 [ 0 ] [ 0 counter set loop-ccc counter get ] unit-test
381
382 ! Type inference issue
383 [ 4 3 ] [
384     1 >bignum 2 >bignum
385     [ { bignum integer } declare [ shift ] keep 1 + ] compile-call
386 ] unit-test
387
388 : broken-declaration ( -- ) \ + declare ;
389
390 [ f ] [ \ broken-declaration optimized? ] unit-test
391
392 [ ] [ [ \ broken-declaration forget ] with-compilation-unit ] unit-test
393
394 ! Interval inference issue
395 [ f ] [
396     10 70
397     [
398         dup 70 >=
399         [ dup 700 <= [ swap 1024 rem rem ] [ 2drop 70 ] if ]
400         [ 2drop 70 ] if
401         70 >=
402     ] compile-call
403 ] unit-test
404
405 ! Modular arithmetic bug
406 : modular-arithmetic-bug ( a -- b ) >integer 256 mod ;
407
408 [ 1 ] [ 257 modular-arithmetic-bug ] unit-test
409 [ -10 ] [ -10 modular-arithmetic-bug ] unit-test
410
411 ! Optimizer needs to ignore invalid generics
412 GENERIC# bad-dispatch-position-test* 3 ( -- )
413
414 M: object bad-dispatch-position-test* ;
415
416 : bad-dispatch-position-test ( -- ) bad-dispatch-position-test* ;
417
418 [ 1 2 3 4 bad-dispatch-position-test ] must-fail
419
420 [ ] [
421     [
422         \ bad-dispatch-position-test forget
423         \ bad-dispatch-position-test* forget
424     ] with-compilation-unit
425 ] unit-test