1 USING: tools.test random sorting sequences 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
31 : test-live-intervals ( -- )
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" }
39 [ cfg set ] [ number-instructions ] [ compute-live-intervals ] tri
53 1 live-intervals get at [ start>> ] [ end>> ] bi
56 ! Live interval splitting
57 { } insns>cfg [ stack-frame>> 4 >>spill-area-align drop ] keep cfg set
66 : clean-up-split ( a b -- a b )
67 [ dup [ [ >vector ] change-uses [ >vector ] change-ranges ] when ] bi@ ;
70 T{ live-interval-state
74 { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } } }
75 { ranges V{ { 0 2 } } }
76 { spill-to T{ spill-slot f 0 } }
77 { spill-rep float-rep }
79 T{ live-interval-state
83 { uses V{ T{ vreg-use f 5 f float-rep } } }
84 { ranges V{ { 5 5 } } }
85 { reload-from T{ spill-slot f 0 } }
86 { reload-rep float-rep }
89 T{ live-interval-state
95 T{ vreg-use f 0 float-rep f }
96 T{ vreg-use f 1 f float-rep }
97 T{ vreg-use f 5 f float-rep }
100 { ranges V{ { 0 5 } } }
107 T{ live-interval-state
111 { uses V{ T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
112 { ranges V{ { 1 5 } } }
113 { reload-from T{ spill-slot f 4 } }
114 { reload-rep float-rep }
117 T{ live-interval-state
123 T{ vreg-use f 0 float-rep f }
124 T{ vreg-use f 1 f float-rep }
125 T{ vreg-use f 5 f float-rep }
128 { ranges V{ { 0 5 } } }
134 T{ live-interval-state
138 { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } } }
139 { ranges V{ { 0 2 } } }
140 { spill-to T{ spill-slot f 8 } }
141 { spill-rep float-rep }
145 T{ live-interval-state
151 T{ vreg-use f 0 float-rep f }
152 T{ vreg-use f 1 f float-rep }
153 T{ vreg-use f 5 f float-rep }
156 { ranges V{ { 0 5 } } }
162 T{ live-interval-state
166 { uses V{ T{ vreg-use f 0 float-rep f } } }
167 { ranges V{ { 0 1 } } }
168 { spill-to T{ spill-slot f 12 } }
169 { spill-rep float-rep }
171 T{ live-interval-state
175 { uses V{ T{ vreg-use f 20 f float-rep } T{ vreg-use f 30 f float-rep } } }
176 { ranges V{ { 20 30 } } }
177 { reload-from T{ spill-slot f 12 } }
178 { reload-rep float-rep }
181 T{ live-interval-state
187 T{ vreg-use f 0 float-rep f }
188 T{ vreg-use f 20 f float-rep }
189 T{ vreg-use f 30 f float-rep }
192 { ranges V{ { 0 8 } { 10 18 } { 20 30 } } }
197 ! Don't insert reload if first usage is a def
199 T{ live-interval-state
203 { uses V{ T{ vreg-use f 0 float-rep f } } }
204 { ranges V{ { 0 1 } } }
205 { spill-to T{ spill-slot f 16 } }
206 { spill-rep float-rep }
208 T{ live-interval-state
212 { uses V{ T{ vreg-use f 20 float-rep f } T{ vreg-use f 30 f float-rep } } }
213 { ranges V{ { 20 30 } } }
216 T{ live-interval-state
222 T{ vreg-use f 0 float-rep f }
223 T{ vreg-use f 20 float-rep f }
224 T{ vreg-use f 30 f float-rep }
227 { ranges V{ { 0 8 } { 10 18 } { 20 30 } } }
232 ! Multiple representations
234 T{ live-interval-state
238 { uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 10 double-rep float-rep } } }
239 { ranges V{ { 0 11 } } }
240 { spill-to T{ spill-slot f 24 } }
241 { spill-rep double-rep }
243 T{ live-interval-state
247 { uses V{ T{ vreg-use f 20 f double-rep } } }
248 { ranges V{ { 20 20 } } }
249 { reload-from T{ spill-slot f 24 } }
250 { reload-rep double-rep }
253 T{ live-interval-state
259 T{ vreg-use f 0 float-rep f }
260 T{ vreg-use f 10 double-rep float-rep }
261 T{ vreg-use f 20 f double-rep }
264 { ranges V{ { 0 20 } } }
271 T{ live-interval-state
275 { ranges V{ { 8 8 } } }
276 { uses V{ T{ vreg-use f 8 int-rep } } }
279 T{ live-interval-state
283 { ranges V{ { 4 8 } } }
284 { uses V{ T{ vreg-use f 8 int-rep } } }
289 ! trim-before-ranges, trim-after-ranges
291 T{ live-interval-state
295 { ranges V{ { 0 3 } } }
296 { uses V{ T{ vreg-use f 0 f int-rep } T{ vreg-use f 2 f int-rep } } }
297 { spill-to T{ spill-slot f 32 } }
298 { spill-rep int-rep }
300 T{ live-interval-state
304 { ranges V{ { 14 16 } } }
305 { uses V{ T{ vreg-use f 14 f int-rep } } }
306 { reload-from T{ spill-slot f 32 } }
307 { reload-rep int-rep }
310 T{ live-interval-state
314 { ranges V{ { 0 4 } { 6 10 } { 12 16 } } }
317 T{ vreg-use f 0 f int-rep }
318 T{ vreg-use f 2 f int-rep }
319 T{ vreg-use f 14 f int-rep } }
329 } representations set
340 T{ live-interval-state
347 T{ vreg-use f 1 int-rep f }
348 T{ vreg-use f 3 f int-rep }
349 T{ vreg-use f 7 f int-rep }
350 T{ vreg-use f 10 f int-rep }
351 T{ vreg-use f 15 f int-rep }
355 T{ live-interval-state
362 T{ vreg-use f 3 int-rep f }
363 T{ vreg-use f 4 f int-rep }
364 T{ vreg-use f 8 f int-rep }
368 T{ live-interval-state
373 { uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 10 f int-rep } } }
377 } active-intervals set
378 H{ } inactive-intervals set
379 T{ live-interval-state
383 { uses V{ T{ vreg-use f 5 int-rep f } } }
397 T{ live-interval-state
402 { uses V{ T{ vreg-use f 1 int-rep f } } }
404 T{ live-interval-state
409 { uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 8 f int-rep } } }
413 } active-intervals set
414 H{ } inactive-intervals set
415 T{ live-interval-state
419 { uses V{ T{ vreg-use f 5 int-rep f } } }
424 H{ { 1 int-rep } { 2 int-rep } } representations set
428 T{ live-interval-state
432 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
433 { ranges V{ { 0 100 } } }
436 H{ { int-regs { "A" } } }
442 T{ live-interval-state
446 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } } }
447 { ranges V{ { 0 10 } } }
449 T{ live-interval-state
453 { uses V{ T{ vreg-use f 11 int-rep f } T{ vreg-use f 20 f int-rep } } }
454 { ranges V{ { 11 20 } } }
457 H{ { int-regs { "A" } } }
463 T{ live-interval-state
467 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
468 { ranges V{ { 0 100 } } }
470 T{ live-interval-state
474 { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 60 f int-rep } } }
475 { ranges V{ { 30 60 } } }
478 H{ { int-regs { "A" } } }
484 T{ live-interval-state
488 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
489 { ranges V{ { 0 100 } } }
491 T{ live-interval-state
495 { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 200 f int-rep } } }
496 { ranges V{ { 30 200 } } }
499 H{ { int-regs { "A" } } }
505 T{ live-interval-state
509 { uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
510 { ranges V{ { 0 100 } } }
512 T{ live-interval-state
516 { uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 100 f int-rep } } }
517 { ranges V{ { 30 100 } } }
520 H{ { int-regs { "A" } } }
524 ! Problem with spilling intervals with no more usages after the spill location
531 } representations set
535 T{ live-interval-state
541 T{ vreg-use f 0 int-rep f }
542 T{ vreg-use f 10 f int-rep }
543 T{ vreg-use f 20 f int-rep }
546 { ranges V{ { 0 2 } { 10 20 } } }
548 T{ live-interval-state
554 T{ vreg-use f 0 int-rep f }
555 T{ vreg-use f 10 f int-rep }
556 T{ vreg-use f 20 f int-rep }
559 { ranges V{ { 0 2 } { 10 20 } } }
561 T{ live-interval-state
565 { uses V{ T{ vreg-use f 6 int-rep f } } }
566 { ranges V{ { 4 8 } } }
568 T{ live-interval-state
572 { uses V{ T{ vreg-use f 8 int-rep f } } }
573 { ranges V{ { 4 8 } } }
576 ! This guy will invoke the 'spill partially available' code path
577 T{ live-interval-state
581 { uses V{ T{ vreg-use f 8 int-rep f } } }
582 { ranges V{ { 4 8 } } }
585 H{ { int-regs { "A" "B" } } }
589 ! Test spill-new code path
593 T{ live-interval-state
597 { 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 } } }
598 { ranges V{ { 0 10 } } }
601 ! This guy will invoke the 'spill new' code path
602 T{ live-interval-state
606 { uses V{ T{ vreg-use f 8 int-rep f } } }
607 { ranges V{ { 2 8 } } }
610 H{ { int-regs { "A" } } }
614 ! register-status had problems because it used map>assoc where the sequence
621 } representations set
627 T{ live-interval-state
632 { ranges V{ { 0 2 } { 10 20 } } }
633 { uses V{ 0 2 10 20 } }
636 T{ live-interval-state
641 { ranges V{ { 4 6 } { 30 40 } } }
642 { uses V{ 4 6 30 40 } }
646 } inactive-intervals set
650 T{ live-interval-state
655 { ranges V{ { 0 40 } } }
660 } active-intervals set
662 T{ live-interval-state
666 { ranges V{ { 8 10 } } }
667 { uses V{ T{ vreg-use f 8 int-rep f } T{ vreg-use f 10 f int-rep } } }
669 H{ { int-regs { 0 1 } } } register-status
673 T{ cfg { frame-pointer? f } } admissible-registers machine-registers =
677 T{ cfg { frame-pointer? t } } admissible-registers
678 int-regs of frame-reg swap member?