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
7 compiler.cfg.instructions
9 compiler.cfg.predecessors
13 compiler.cfg.comparisons
14 compiler.cfg.ssa.destruction.leaders
15 compiler.cfg.linear-scan
16 compiler.cfg.linear-scan.allocation
17 compiler.cfg.linear-scan.allocation.state
18 compiler.cfg.linear-scan.allocation.splitting
19 compiler.cfg.linear-scan.allocation.spilling
20 compiler.cfg.linear-scan.live-intervals
21 compiler.cfg.linear-scan.numbering
22 compiler.cfg.linear-scan.ranges
23 compiler.cfg.linear-scan.debugger
24 compiler.cfg.utilities ;
25 IN: compiler.cfg.linear-scan.tests
30 ! Live interval calculation
32 ! A value is defined and never used; make sure it has the right
35 T{ ##load-integer f 1 0 }
36 T{ ##replace-imm f D: 0 "hi" }
40 : test-live-intervals ( -- )
42 [ cfg set ] [ number-instructions ] [ compute-live-intervals ] tri
56 1 live-intervals get at [ start>> ] [ end>> ] bi
59 ! Live interval splitting
61 cfg new 0 >>spill-area-size 4 >>spill-area-align cfg set
70 : clean-up-split ( a b -- a b )
71 [ dup [ [ >vector ] change-uses [ >vector ] change-ranges ] when ] bi@ ;
74 T{ live-interval-state
76 { reg-class float-regs }
79 { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } } }
80 { ranges V{ T{ live-range f 0 2 } } }
81 { spill-to T{ spill-slot f 0 } }
82 { spill-rep float-rep }
84 T{ live-interval-state
86 { reg-class float-regs }
89 { uses V{ T{ vreg-use f 5 f float-rep } } }
90 { ranges V{ T{ live-range f 5 5 } } }
91 { reload-from T{ spill-slot f 0 } }
92 { reload-rep float-rep }
95 T{ live-interval-state
97 { reg-class float-regs }
100 { 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 } } }
101 { ranges V{ T{ live-range f 0 5 } } }
108 T{ live-interval-state
110 { reg-class float-regs }
113 { uses V{ T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
114 { ranges V{ T{ live-range f 1 5 } } }
115 { reload-from T{ spill-slot f 4 } }
116 { reload-rep float-rep }
119 T{ live-interval-state
121 { reg-class float-regs }
124 { 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 } } }
125 { ranges V{ T{ live-range f 0 5 } } }
131 T{ live-interval-state
133 { reg-class float-regs }
136 { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } } }
137 { ranges V{ T{ live-range f 0 2 } } }
138 { spill-to T{ spill-slot f 8 } }
139 { spill-rep float-rep }
143 T{ live-interval-state
145 { reg-class float-regs }
148 { 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 } } }
149 { ranges V{ T{ live-range f 0 5 } } }
155 T{ live-interval-state
157 { reg-class float-regs }
160 { uses V{ T{ vreg-use f 0 float-rep f } } }
161 { ranges V{ T{ live-range f 0 1 } } }
162 { spill-to T{ spill-slot f 12 } }
163 { spill-rep float-rep }
165 T{ live-interval-state
167 { reg-class float-regs }
170 { uses V{ T{ vreg-use f 20 f float-rep } T{ vreg-use f 30 f float-rep } } }
171 { ranges V{ T{ live-range f 20 30 } } }
172 { reload-from T{ spill-slot f 12 } }
173 { reload-rep float-rep }
176 T{ live-interval-state
178 { reg-class float-regs }
181 { 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 } } }
182 { ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
187 ! Don't insert reload if first usage is a def
189 T{ live-interval-state
191 { reg-class float-regs }
194 { uses V{ T{ vreg-use f 0 float-rep f } } }
195 { ranges V{ T{ live-range f 0 1 } } }
196 { spill-to T{ spill-slot f 16 } }
197 { spill-rep float-rep }
199 T{ live-interval-state
201 { reg-class float-regs }
204 { uses V{ T{ vreg-use f 20 float-rep f } T{ vreg-use f 30 f float-rep } } }
205 { ranges V{ T{ live-range f 20 30 } } }
208 T{ live-interval-state
210 { reg-class float-regs }
213 { 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 } } }
214 { ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
219 ! Multiple representations
221 T{ live-interval-state
223 { reg-class float-regs }
226 { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 10 double-rep float-rep } } }
227 { ranges V{ T{ live-range f 0 11 } } }
228 { spill-to T{ spill-slot f 24 } }
229 { spill-rep double-rep }
231 T{ live-interval-state
233 { reg-class float-regs }
236 { uses V{ T{ vreg-use f 20 f double-rep } } }
237 { ranges V{ T{ live-range f 20 20 } } }
238 { reload-from T{ spill-slot f 24 } }
239 { reload-rep double-rep }
242 T{ live-interval-state
244 { reg-class float-regs }
247 { 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 } } }
248 { ranges V{ T{ live-range f 0 20 } } }
255 T{ live-interval-state
259 { ranges V{ T{ live-range f 8 8 } } }
260 { uses V{ T{ vreg-use f 8 int-rep } } }
261 { reg-class int-regs }
264 T{ live-interval-state
268 { ranges V{ T{ live-range f 4 8 } } }
269 { uses V{ T{ vreg-use f 8 int-rep } } }
270 { reg-class int-regs }
275 ! trim-before-ranges, trim-after-ranges
277 T{ live-interval-state
281 { ranges V{ T{ live-range f 0 3 } } }
282 { uses V{ T{ vreg-use f 0 f int-rep } T{ vreg-use f 2 f int-rep } } }
283 { reg-class int-regs }
284 { spill-to T{ spill-slot f 32 } }
285 { spill-rep int-rep }
287 T{ live-interval-state
291 { ranges V{ T{ live-range f 14 16 } } }
292 { uses V{ T{ vreg-use f 14 f int-rep } } }
293 { reg-class int-regs }
294 { reload-from T{ spill-slot f 32 } }
295 { reload-rep int-rep }
298 T{ live-interval-state
302 { ranges V{ T{ live-range f 0 4 } T{ live-range f 6 10 } T{ live-range f 12 16 } } }
303 { 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 } } }
304 { reg-class int-regs }
313 } representations set
324 T{ live-interval-state
326 { reg-class int-regs }
330 { 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 } } }
332 T{ live-interval-state
334 { reg-class int-regs }
338 { 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 } } }
340 T{ live-interval-state
342 { reg-class int-regs }
346 { uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 10 f int-rep } } }
350 } active-intervals set
351 H{ } inactive-intervals set
352 T{ live-interval-state
354 { reg-class int-regs }
357 { uses V{ T{ vreg-use f 5 int-rep f } } }
371 T{ live-interval-state
373 { reg-class int-regs }
377 { uses V{ T{ vreg-use f 1 int-rep f } } }
379 T{ live-interval-state
381 { reg-class int-regs }
385 { uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 8 f int-rep } } }
389 } active-intervals set
390 H{ } inactive-intervals set
391 T{ live-interval-state
393 { reg-class int-regs }
396 { uses V{ T{ vreg-use f 5 int-rep f } } }
401 H{ { 1 int-rep } { 2 int-rep } } representations set
405 T{ live-interval-state
407 { reg-class int-regs }
410 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
411 { ranges V{ T{ live-range f 0 100 } } }
414 H{ { int-regs { "A" } } }
420 T{ live-interval-state
422 { reg-class int-regs }
425 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } } }
426 { ranges V{ T{ live-range f 0 10 } } }
428 T{ live-interval-state
430 { reg-class int-regs }
433 { uses V{ T{ vreg-use f 11 int-rep f } T{ vreg-use f 20 f int-rep } } }
434 { ranges V{ T{ live-range f 11 20 } } }
437 H{ { int-regs { "A" } } }
443 T{ live-interval-state
445 { reg-class int-regs }
448 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
449 { ranges V{ T{ live-range f 0 100 } } }
451 T{ live-interval-state
453 { reg-class int-regs }
456 { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 60 f int-rep } } }
457 { ranges V{ T{ live-range f 30 60 } } }
460 H{ { int-regs { "A" } } }
466 T{ live-interval-state
468 { reg-class int-regs }
471 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
472 { ranges V{ T{ live-range f 0 100 } } }
474 T{ live-interval-state
476 { reg-class int-regs }
479 { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 200 f int-rep } } }
480 { ranges V{ T{ live-range f 30 200 } } }
483 H{ { int-regs { "A" } } }
489 T{ live-interval-state
491 { reg-class int-regs }
494 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
495 { ranges V{ T{ live-range f 0 100 } } }
497 T{ live-interval-state
499 { reg-class int-regs }
502 { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 100 f int-rep } } }
503 { ranges V{ T{ live-range f 30 100 } } }
506 H{ { int-regs { "A" } } }
510 ! Problem with spilling intervals with no more usages after the spill location
517 } representations set
521 T{ live-interval-state
523 { reg-class int-regs }
526 { 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 } } }
527 { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
529 T{ live-interval-state
531 { reg-class int-regs }
534 { 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 } } }
535 { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
537 T{ live-interval-state
539 { reg-class int-regs }
542 { uses V{ T{ vreg-use f 6 int-rep f } } }
543 { ranges V{ T{ live-range f 4 8 } } }
545 T{ live-interval-state
547 { reg-class int-regs }
550 { uses V{ T{ vreg-use f 8 int-rep f } } }
551 { ranges V{ T{ live-range f 4 8 } } }
554 ! This guy will invoke the 'spill partially available' code path
555 T{ live-interval-state
557 { reg-class int-regs }
560 { uses V{ T{ vreg-use f 8 int-rep f } } }
561 { ranges V{ T{ live-range f 4 8 } } }
564 H{ { int-regs { "A" "B" } } }
568 ! Test spill-new code path
572 T{ live-interval-state
574 { reg-class int-regs }
577 { 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 } } }
578 { ranges V{ T{ live-range f 0 10 } } }
581 ! This guy will invoke the 'spill new' code path
582 T{ live-interval-state
584 { reg-class int-regs }
587 { uses V{ T{ vreg-use f 8 int-rep f } } }
588 { ranges V{ T{ live-range f 2 8 } } }
591 H{ { int-regs { "A" } } }
595 ! register-status had problems because it used map>assoc where the sequence
602 } representations set
608 T{ live-interval-state
610 { reg-class int-regs }
614 { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
615 { uses V{ 0 2 10 20 } }
618 T{ live-interval-state
620 { reg-class int-regs }
624 { ranges V{ T{ live-range f 4 6 } T{ live-range f 30 40 } } }
625 { uses V{ 4 6 30 40 } }
629 } inactive-intervals set
633 T{ live-interval-state
635 { reg-class int-regs }
639 { ranges V{ T{ live-range f 0 40 } } }
644 } active-intervals set
646 T{ live-interval-state
648 { reg-class int-regs }
651 { ranges V{ T{ live-range f 8 10 } } }
652 { uses V{ T{ vreg-use f 8 int-rep f } T{ vreg-use f 10 f int-rep } } }
654 H{ { int-regs { 0 1 } } } register-status
658 T{ cfg { frame-pointer? f } } admissible-registers machine-registers =
662 T{ cfg { frame-pointer? t } } admissible-registers
663 int-regs of frame-reg swap member?