]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/linear-scan/linear-scan-tests.factor
Stack allocation improvements
[factor.git] / basis / compiler / cfg / linear-scan / linear-scan-tests.factor
1 USING: tools.test random sorting sequences sets hashtables assocs
2 kernel fry arrays splitting namespaces math accessors vectors locals
3 math.order grouping strings strings.private classes layouts
4 cpu.architecture
5 compiler.cfg
6 compiler.cfg.optimizer
7 compiler.cfg.instructions
8 compiler.cfg.registers
9 compiler.cfg.predecessors
10 compiler.cfg.rpo
11 compiler.cfg.debugger
12 compiler.cfg.def-use
13 compiler.cfg.comparisons
14 compiler.cfg.linear-scan
15 compiler.cfg.linear-scan.numbering
16 compiler.cfg.linear-scan.live-intervals
17 compiler.cfg.linear-scan.allocation
18 compiler.cfg.linear-scan.allocation.state
19 compiler.cfg.linear-scan.allocation.splitting
20 compiler.cfg.linear-scan.allocation.spilling
21 compiler.cfg.linear-scan.debugger ;
22 FROM: namespaces => set ;
23 IN: compiler.cfg.linear-scan.tests
24
25 check-allocation? on
26 check-numbering? on
27
28 [
29     { T{ live-range f 1 10 } T{ live-range f 15 15 } }
30     { T{ live-range f 16 20 } }
31 ] [
32     {
33         T{ live-range f 1 10 }
34         T{ live-range f 15 20 }
35     } 15 split-ranges
36 ] unit-test
37
38 [
39     { T{ live-range f 1 10 } T{ live-range f 15 16 } }
40     { T{ live-range f 17 20 } }
41 ] [
42     {
43         T{ live-range f 1 10 }
44         T{ live-range f 15 20 }
45     } 16 split-ranges
46 ] unit-test
47
48 [
49     { T{ live-range f 1 10 } }
50     { T{ live-range f 15 20 } }
51 ] [
52     {
53         T{ live-range f 1 10 }
54         T{ live-range f 15 20 }
55     } 12 split-ranges
56 ] unit-test
57
58 [
59     { T{ live-range f 1 10 } T{ live-range f 15 17 } }
60     { T{ live-range f 18 20 } }
61 ] [
62     {
63         T{ live-range f 1 10 }
64         T{ live-range f 15 20 }
65     } 17 split-ranges
66 ] unit-test
67
68 [
69     { T{ live-range f 1 10 } } 0 split-ranges
70 ] must-fail
71
72 [
73     { T{ live-range f 0 0 } }
74     { T{ live-range f 1 5 } }
75 ] [
76     { T{ live-range f 0 5 } } 0 split-ranges
77 ] unit-test
78
79 cfg new 0 >>spill-area-size 4 >>spill-area-align cfg set
80 H{ } spill-slots set
81
82 H{
83     { 1 float-rep }
84     { 2 float-rep }
85     { 3 float-rep }
86 } representations set
87
88 : clean-up-split ( a b -- a b )
89     [ dup [ [ >vector ] change-uses [ >vector ] change-ranges ] when ] bi@ ;
90
91 [
92     T{ live-interval
93        { vreg 1 }
94        { reg-class float-regs }
95        { start 0 }
96        { end 2 }
97        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } } }
98        { ranges V{ T{ live-range f 0 2 } } }
99        { spill-to T{ spill-slot f 0 } }
100        { spill-rep float-rep }
101     }
102     T{ live-interval
103        { vreg 1 }
104        { reg-class float-regs }
105        { start 5 }
106        { end 5 }
107        { uses V{ T{ vreg-use f 5 f float-rep } } }
108        { ranges V{ T{ live-range f 5 5 } } }
109        { reload-from T{ spill-slot f 0 } }
110        { reload-rep float-rep }
111     }
112 ] [
113     T{ live-interval
114        { vreg 1 }
115        { reg-class float-regs }
116        { start 0 }
117        { end 5 }
118        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
119        { ranges V{ T{ live-range f 0 5 } } }
120     } 2 split-for-spill
121     clean-up-split
122 ] unit-test
123
124 [
125     f
126     T{ live-interval
127        { vreg 2 }
128        { reg-class float-regs }
129        { start 1 }
130        { end 5 }
131        { uses V{ T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
132        { ranges V{ T{ live-range f 1 5 } } }
133        { reload-from T{ spill-slot f 4 } }
134        { reload-rep float-rep }
135     }
136 ] [
137     T{ live-interval
138        { vreg 2 }
139        { reg-class float-regs }
140        { start 0 }
141        { end 5 }
142        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
143        { ranges V{ T{ live-range f 0 5 } } }
144     } 0 split-for-spill
145     clean-up-split
146 ] unit-test
147
148 [
149     T{ live-interval
150        { vreg 3 }
151        { reg-class float-regs }
152        { start 0 }
153        { end 2 }
154        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } } }
155        { ranges V{ T{ live-range f 0 2 } } }
156        { spill-to T{ spill-slot f 8 } }
157        { spill-rep float-rep }
158     }
159     f
160 ] [
161     T{ live-interval
162        { vreg 3 }
163        { reg-class float-regs }
164        { start 0 }
165        { end 5 }
166        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
167        { ranges V{ T{ live-range f 0 5 } } }
168     } 5 split-for-spill
169     clean-up-split
170 ] unit-test
171
172 [
173     T{ live-interval
174        { vreg 4 }
175        { reg-class float-regs }
176        { start 0 }
177        { end 1 }
178        { uses V{ T{ vreg-use f 0 float-rep f } } }
179        { ranges V{ T{ live-range f 0 1 } } }
180        { spill-to T{ spill-slot f 12 } }
181        { spill-rep float-rep }
182     }
183     T{ live-interval
184        { vreg 4 }
185        { reg-class float-regs }
186        { start 20 }
187        { end 30 }
188        { uses V{ T{ vreg-use f 20 f float-rep } T{ vreg-use f 30 f float-rep } } }
189        { ranges V{ T{ live-range f 20 30 } } }
190        { reload-from T{ spill-slot f 12 } }
191        { reload-rep float-rep }
192     }
193 ] [
194     T{ live-interval
195        { vreg 4 }
196        { reg-class float-regs }
197        { start 0 }
198        { end 30 }
199        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 20 f float-rep } T{ vreg-use f 30 f float-rep } } }
200        { ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
201     } 10 split-for-spill
202     clean-up-split
203 ] unit-test
204
205 ! Don't insert reload if first usage is a def
206 [
207     T{ live-interval
208        { vreg 5 }
209        { reg-class float-regs }
210        { start 0 }
211        { end 1 }
212        { uses V{ T{ vreg-use f 0 float-rep f } } }
213        { ranges V{ T{ live-range f 0 1 } } }
214        { spill-to T{ spill-slot f 16 } }
215        { spill-rep float-rep }
216     }
217     T{ live-interval
218        { vreg 5 }
219        { reg-class float-regs }
220        { start 20 }
221        { end 30 }
222        { uses V{ T{ vreg-use f 20 float-rep f } T{ vreg-use f 30 f float-rep } } }
223        { ranges V{ T{ live-range f 20 30 } } }
224     }
225 ] [
226     T{ live-interval
227        { vreg 5 }
228        { reg-class float-regs }
229        { start 0 }
230        { end 30 }
231        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 20 float-rep f } T{ vreg-use f 30 f float-rep } } }
232        { ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
233     } 10 split-for-spill
234     clean-up-split
235 ] unit-test
236
237 ! Multiple representations
238 [
239     T{ live-interval
240        { vreg 6 }
241        { reg-class float-regs }
242        { start 0 }
243        { end 11 }
244        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 10 double-rep float-rep } } }
245        { ranges V{ T{ live-range f 0 11 } } }
246        { spill-to T{ spill-slot f 24 } }
247        { spill-rep double-rep }
248     }
249     T{ live-interval
250        { vreg 6 }
251        { reg-class float-regs }
252        { start 20 }
253        { end 20 }
254        { uses V{ T{ vreg-use f 20 f double-rep } } }
255        { ranges V{ T{ live-range f 20 20 } } }
256        { reload-from T{ spill-slot f 24 } }
257        { reload-rep double-rep }
258     }
259 ] [
260     T{ live-interval
261        { vreg 6 }
262        { reg-class float-regs }
263        { start 0 }
264        { end 20 }
265        { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 10 double-rep float-rep } T{ vreg-use f 20 f double-rep } } }
266        { ranges V{ T{ live-range f 0 20 } } }
267     } 15 split-for-spill
268     clean-up-split
269 ] unit-test
270
271 [
272     f
273     T{ live-interval
274         { vreg 7 }
275         { start 8 }
276         { end 8 }
277         { ranges V{ T{ live-range f 8 8 } } }
278         { uses V{ T{ vreg-use f 8 int-rep } } }
279         { reg-class int-regs }
280     }
281 ] [
282     T{ live-interval
283         { vreg 7 }
284         { start 4 }
285         { end 8 }
286         { ranges V{ T{ live-range f 4 8 } } }
287         { uses V{ T{ vreg-use f 8 int-rep } } }
288         { reg-class int-regs }
289     } 4 split-for-spill
290     clean-up-split
291 ] unit-test
292
293 ! trim-before-ranges, trim-after-ranges
294 [
295     T{ live-interval
296         { vreg 8 }
297         { start 0 }
298         { end 3 }
299         { ranges V{ T{ live-range f 0 3 } } }
300         { uses V{ T{ vreg-use f 0 f int-rep } T{ vreg-use f 2 f int-rep } } }
301         { reg-class int-regs }
302         { spill-to T{ spill-slot f 32 } }
303         { spill-rep int-rep }
304     }
305     T{ live-interval
306         { vreg 8 }
307         { start 14 }
308         { end 16 }
309         { ranges V{ T{ live-range f 14 16 } } }
310         { uses V{ T{ vreg-use f 14 f int-rep } } }
311         { reg-class int-regs }
312         { reload-from T{ spill-slot f 32 } }
313         { reload-rep int-rep }
314     }
315 ] [
316     T{ live-interval
317         { vreg 8 }
318         { start 0 }
319         { end 16 }
320         { ranges V{ T{ live-range f 0 4 } T{ live-range f 6 10 } T{ live-range f 12 16 } } }
321         { uses V{ T{ vreg-use f 0 f int-rep } T{ vreg-use f 2 f int-rep } T{ vreg-use f 14 f int-rep } } }
322         { reg-class int-regs }
323     } 8 split-for-spill
324     clean-up-split
325 ] unit-test
326
327 H{
328     { 1 int-rep }
329     { 2 int-rep }
330     { 3 int-rep }
331 } representations set
332
333 [
334     {
335         3
336         10
337     }
338 ] [
339     H{
340         { int-regs
341           V{
342               T{ live-interval
343                  { vreg 1 }
344                  { reg-class int-regs }
345                  { reg 1 }
346                  { start 1 }
347                  { end 15 }
348                  { uses V{ T{ vreg-use f 1 int-rep f } T{ vreg-use f 3 f int-rep } T{ vreg-use f 7 f int-rep } T{ vreg-use f 10 f int-rep } T{ vreg-use f 15 f int-rep } } }
349               }
350               T{ live-interval
351                  { vreg 2 }
352                  { reg-class int-regs }
353                  { reg 2 }
354                  { start 3 }
355                  { end 8 }
356                  { uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 4 f int-rep } T{ vreg-use f 8 f int-rep } } }
357               }
358               T{ live-interval
359                  { vreg 3 }
360                  { reg-class int-regs }
361                  { reg 3 }
362                  { start 3 }
363                  { end 10 }
364                  { uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 10 f int-rep } } }
365               }
366           }
367         }
368     } active-intervals set
369     H{ } inactive-intervals set
370     T{ live-interval
371         { vreg 1 }
372         { reg-class int-regs }
373         { start 5 }
374         { end 5 }
375         { uses V{ T{ vreg-use f 5 int-rep f } } }
376     }
377     spill-status
378 ] unit-test
379
380 [
381     {
382         1
383         1/0.
384     }
385 ] [
386     H{
387         { int-regs
388           V{
389               T{ live-interval
390                  { vreg 1 }
391                  { reg-class int-regs }
392                  { reg 1 }
393                  { start 1 }
394                  { end 15 }
395                  { uses V{ T{ vreg-use f 1 int-rep f } } }
396               }
397               T{ live-interval
398                  { vreg 2 }
399                  { reg-class int-regs }
400                  { reg 2 }
401                  { start 3 }
402                  { end 8 }
403                  { uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 8 f int-rep } } }
404               }
405           }
406         }
407     } active-intervals set
408     H{ } inactive-intervals set
409     T{ live-interval
410         { vreg 3 }
411         { reg-class int-regs }
412         { start 5 }
413         { end 5 }
414         { uses V{ T{ vreg-use f 5 int-rep f } } }
415     }
416     spill-status
417 ] unit-test
418
419 H{ { 1 int-rep } { 2 int-rep } } representations set
420
421 [ ] [
422     {
423         T{ live-interval
424            { vreg 1 }
425            { reg-class int-regs }
426            { start 0 }
427            { end 100 }
428            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
429            { ranges V{ T{ live-range f 0 100 } } }
430         }
431     }
432     H{ { int-regs { "A" } } }
433     check-linear-scan
434 ] unit-test
435
436 [ ] [
437     {
438         T{ live-interval
439            { vreg 1 }
440            { reg-class int-regs }
441            { start 0 }
442            { end 10 }
443            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } } }
444            { ranges V{ T{ live-range f 0 10 } } }
445         }
446         T{ live-interval
447            { vreg 2 }
448            { reg-class int-regs }
449            { start 11 }
450            { end 20 }
451            { uses V{ T{ vreg-use f 11 int-rep f } T{ vreg-use f 20 f int-rep } } }
452            { ranges V{ T{ live-range f 11 20 } } }
453         }
454     }
455     H{ { int-regs { "A" } } }
456     check-linear-scan
457 ] unit-test
458
459 [ ] [
460     {
461         T{ live-interval
462            { vreg 1 }
463            { reg-class int-regs }
464            { start 0 }
465            { end 100 }
466            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
467            { ranges V{ T{ live-range f 0 100 } } }
468         }
469         T{ live-interval
470            { vreg 2 }
471            { reg-class int-regs }
472            { start 30 }
473            { end 60 }
474            { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 60 f int-rep } } }
475            { ranges V{ T{ live-range f 30 60 } } }
476         }
477     }
478     H{ { int-regs { "A" } } }
479     check-linear-scan
480 ] unit-test
481
482 [ ] [
483     {
484         T{ live-interval
485            { vreg 1 }
486            { reg-class int-regs }
487            { start 0 }
488            { end 100 }
489            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
490            { ranges V{ T{ live-range f 0 100 } } }
491         }
492         T{ live-interval
493            { vreg 2 }
494            { reg-class int-regs }
495            { start 30 }
496            { end 200 }
497            { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 200 f int-rep } } }
498            { ranges V{ T{ live-range f 30 200 } } }
499         }
500     }
501     H{ { int-regs { "A" } } }
502     check-linear-scan
503 ] unit-test
504
505 [
506     {
507         T{ live-interval
508            { vreg 1 }
509            { reg-class int-regs }
510            { start 0 }
511            { end 100 }
512            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
513            { ranges V{ T{ live-range f 0 100 } } }
514         }
515         T{ live-interval
516            { vreg 2 }
517            { reg-class int-regs }
518            { start 30 }
519            { end 100 }
520            { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 100 f int-rep } } }
521            { ranges V{ T{ live-range f 30 100 } } }
522         }
523     }
524     H{ { int-regs { "A" } } }
525     check-linear-scan
526 ] must-fail
527
528 ! Problem with spilling intervals with no more usages after the spill location
529 H{
530     { 1 int-rep }
531     { 2 int-rep }
532     { 3 int-rep }
533     { 4 int-rep }
534     { 5 int-rep }
535 } representations set
536
537 [ ] [
538     {
539         T{ live-interval
540            { vreg 1 }
541            { reg-class int-regs }
542            { start 0 }
543            { end 20 }
544            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } T{ vreg-use f 20 f int-rep } } }
545            { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
546         }
547         T{ live-interval
548            { vreg 2 }
549            { reg-class int-regs }
550            { start 0 }
551            { end 20 }
552            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } T{ vreg-use f 20 f int-rep } } }
553            { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
554         }
555         T{ live-interval
556            { vreg 3 }
557            { reg-class int-regs }
558            { start 4 }
559            { end 8 }
560            { uses V{ T{ vreg-use f 6 int-rep f } } }
561            { ranges V{ T{ live-range f 4 8 } } }
562         }
563         T{ live-interval
564            { vreg 4 }
565            { reg-class int-regs }
566            { start 4 }
567            { end 8 }
568            { uses V{ T{ vreg-use f 8 int-rep f } } }
569            { ranges V{ T{ live-range f 4 8 } } }
570         }
571
572         ! This guy will invoke the 'spill partially available' code path
573         T{ live-interval
574            { vreg 5 }
575            { reg-class int-regs }
576            { start 4 }
577            { end 8 }
578            { uses V{ T{ vreg-use f 8 int-rep f } } }
579            { ranges V{ T{ live-range f 4 8 } } }
580         }
581     }
582     H{ { int-regs { "A" "B" } } }
583     check-linear-scan
584 ] unit-test
585
586 ! Test spill-new code path
587
588 [ ] [
589     {
590         T{ live-interval
591            { vreg 1 }
592            { reg-class int-regs }
593            { start 0 }
594            { end 10 }
595            { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 6 f int-rep } T{ vreg-use f 10 f int-rep } } }
596            { ranges V{ T{ live-range f 0 10 } } }
597         }
598
599         ! This guy will invoke the 'spill new' code path
600         T{ live-interval
601            { vreg 5 }
602            { reg-class int-regs }
603            { start 2 }
604            { end 8 }
605            { uses V{ T{ vreg-use f 8 int-rep f } } }
606            { ranges V{ T{ live-range f 2 8 } } }
607         }
608     }
609     H{ { int-regs { "A" } } }
610     check-linear-scan
611 ] unit-test
612
613 [ f ] [
614     T{ live-range f 0 10 }
615     T{ live-range f 20 30 }
616     intersect-live-range
617 ] unit-test
618
619 [ 10 ] [
620     T{ live-range f 0 10 }
621     T{ live-range f 10 30 }
622     intersect-live-range
623 ] unit-test
624
625 [ 5 ] [
626     T{ live-range f 0 10 }
627     T{ live-range f 5 30 }
628     intersect-live-range
629 ] unit-test
630
631 [ 5 ] [
632     T{ live-range f 5 30 }
633     T{ live-range f 0 10 }
634     intersect-live-range
635 ] unit-test
636
637 [ 5 ] [
638     T{ live-range f 5 10 }
639     T{ live-range f 0 15 }
640     intersect-live-range
641 ] unit-test
642
643 [ 50 ] [
644     {
645         T{ live-range f 0 10 }
646         T{ live-range f 20 30 }
647         T{ live-range f 40 50 }
648     }
649     {
650         T{ live-range f 11 15 }
651         T{ live-range f 31 35 }
652         T{ live-range f 50 55 }
653     }
654     intersect-live-ranges
655 ] unit-test
656
657 [ f ] [
658     {
659         T{ live-range f 0 10 }
660         T{ live-range f 20 30 }
661         T{ live-range f 40 50 }
662     }
663     {
664         T{ live-range f 11 15 }
665         T{ live-range f 31 36 }
666         T{ live-range f 51 55 }
667     }
668     intersect-live-ranges
669 ] unit-test
670
671 [ 5 ] [
672     T{ live-interval
673        { start 0 }
674        { reg-class int-regs }
675        { end 10 }
676        { uses { 0 10 } }
677        { ranges V{ T{ live-range f 0 10 } } }
678     }
679     T{ live-interval
680        { start 5 }
681        { reg-class int-regs }
682        { end 10 }
683        { uses { 5 10 } }
684        { ranges V{ T{ live-range f 5 10 } } }
685     }
686     relevant-ranges intersect-live-ranges
687 ] unit-test
688
689 ! register-status had problems because it used map>assoc where the sequence
690 ! had multiple keys
691 H{
692     { 1 int-rep }
693     { 2 int-rep }
694     { 3 int-rep }
695     { 4 int-rep }
696 } representations set
697
698 [ { 0 10 } ] [
699     H{ { int-regs { 0 1 } } } registers set
700     H{
701         { int-regs
702           {
703               T{ live-interval
704                  { vreg 1 }
705                  { reg-class int-regs }
706                  { start 0 }
707                  { end 20 }
708                  { reg 0 }
709                  { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
710                  { uses V{ 0 2 10 20 } }
711               }
712
713               T{ live-interval
714                  { vreg 2 }
715                  { reg-class int-regs }
716                  { start 4 }
717                  { end 40 }
718                  { reg 0 }
719                  { ranges V{ T{ live-range f 4 6 } T{ live-range f 30 40 } } }
720                  { uses V{ 4 6 30 40 } }
721               }
722           }
723         }
724     } inactive-intervals set
725     H{
726         { int-regs
727           {
728               T{ live-interval
729                  { vreg 3 }
730                  { reg-class int-regs }
731                  { start 0 }
732                  { end 40 }
733                  { reg 1 }
734                  { ranges V{ T{ live-range f 0 40 } } }
735                  { uses V{ 0 40 } }
736               }
737           }
738         }
739     } active-intervals set
740
741     T{ live-interval
742         { vreg 4 }
743         { reg-class int-regs }
744         { start 8 }
745         { end 10 }
746         { ranges V{ T{ live-range f 8 10 } } }
747         { uses V{ T{ vreg-use f 8 int-rep f } T{ vreg-use f 10 f int-rep } } }
748     }
749     register-status
750 ] unit-test