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
11 compiler.cfg.linearization
14 compiler.cfg.comparisons
15 compiler.cfg.linear-scan
16 compiler.cfg.linear-scan.numbering
17 compiler.cfg.linear-scan.live-intervals
18 compiler.cfg.linear-scan.allocation
19 compiler.cfg.linear-scan.allocation.state
20 compiler.cfg.linear-scan.allocation.splitting
21 compiler.cfg.linear-scan.allocation.spilling
22 compiler.cfg.linear-scan.debugger ;
23 FROM: namespaces => set ;
24 IN: compiler.cfg.linear-scan.tests
30 { T{ live-range f 1 10 } T{ live-range f 15 15 } }
31 { T{ live-range f 16 20 } }
34 T{ live-range f 1 10 }
35 T{ live-range f 15 20 }
40 { T{ live-range f 1 10 } T{ live-range f 15 16 } }
41 { T{ live-range f 17 20 } }
44 T{ live-range f 1 10 }
45 T{ live-range f 15 20 }
50 { T{ live-range f 1 10 } }
51 { T{ live-range f 15 20 } }
54 T{ live-range f 1 10 }
55 T{ live-range f 15 20 }
60 { T{ live-range f 1 10 } T{ live-range f 15 17 } }
61 { T{ live-range f 18 20 } }
64 T{ live-range f 1 10 }
65 T{ live-range f 15 20 }
70 { T{ live-range f 1 10 } } 0 split-ranges
74 { T{ live-range f 0 0 } }
75 { T{ live-range f 1 5 } }
77 { T{ live-range f 0 5 } } 0 split-ranges
80 cfg new 0 >>spill-area-size cfg set
92 { reg-class float-regs }
95 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } } }
96 { ranges V{ T{ live-range f 0 2 } } }
97 { spill-to T{ spill-slot f 0 } }
101 { reg-class float-regs }
104 { uses V{ T{ vreg-use f 5 } } }
105 { ranges V{ T{ live-range f 5 5 } } }
106 { reload-from T{ spill-slot f 0 } }
111 { reg-class float-regs }
114 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } }
115 { ranges V{ T{ live-range f 0 5 } } }
122 { reg-class float-regs }
125 { uses V{ T{ vreg-use f 0 } } }
126 { ranges V{ T{ live-range f 0 1 } } }
127 { spill-to T{ spill-slot f 4 } }
131 { reg-class float-regs }
134 { uses V{ T{ vreg-use f 1 } T{ vreg-use f 5 } } }
135 { ranges V{ T{ live-range f 1 5 } } }
136 { reload-from T{ spill-slot f 4 } }
141 { reg-class float-regs }
144 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } }
145 { ranges V{ T{ live-range f 0 5 } } }
152 { reg-class float-regs }
155 { uses V{ T{ vreg-use f 0 } } }
156 { ranges V{ T{ live-range f 0 1 } } }
157 { spill-to T{ spill-slot f 8 } }
161 { reg-class float-regs }
164 { uses V{ T{ vreg-use f 20 } T{ vreg-use f 30 } } }
165 { ranges V{ T{ live-range f 20 30 } } }
166 { reload-from T{ spill-slot f 8 } }
171 { reg-class float-regs }
174 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 20 } T{ vreg-use f 30 } } }
175 { ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
183 } representations set
196 { reg-class int-regs }
200 { uses V{ T{ vreg-use f 1 } T{ vreg-use f 3 } T{ vreg-use f 7 } T{ vreg-use f 10 } T{ vreg-use f 15 } } }
204 { reg-class int-regs }
208 { uses V{ T{ vreg-use f 3 } T{ vreg-use f 4 } T{ vreg-use f 8 } } }
212 { reg-class int-regs }
216 { uses V{ T{ vreg-use f 3 } T{ vreg-use f 10 } } }
220 } active-intervals set
221 H{ } inactive-intervals set
224 { reg-class int-regs }
227 { uses V{ T{ vreg-use f 5 } } }
243 { reg-class int-regs }
247 { uses V{ T{ vreg-use f 1 } } }
251 { reg-class int-regs }
255 { uses V{ T{ vreg-use f 3 } T{ vreg-use f 8 } } }
259 } active-intervals set
260 H{ } inactive-intervals set
263 { reg-class int-regs }
266 { uses V{ T{ vreg-use f 5 } } }
271 H{ { 1 int-rep } { 2 int-rep } } representations set
277 { reg-class int-regs }
280 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
281 { ranges V{ T{ live-range f 0 100 } } }
284 H{ { int-regs { "A" } } }
292 { reg-class int-regs }
295 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } } }
296 { ranges V{ T{ live-range f 0 10 } } }
300 { reg-class int-regs }
303 { uses V{ T{ vreg-use f 11 } T{ vreg-use f 20 } } }
304 { ranges V{ T{ live-range f 11 20 } } }
307 H{ { int-regs { "A" } } }
315 { reg-class int-regs }
318 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
319 { ranges V{ T{ live-range f 0 100 } } }
323 { reg-class int-regs }
326 { uses V{ T{ vreg-use f 30 } T{ vreg-use f 60 } } }
327 { ranges V{ T{ live-range f 30 60 } } }
330 H{ { int-regs { "A" } } }
338 { reg-class int-regs }
341 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
342 { ranges V{ T{ live-range f 0 100 } } }
346 { reg-class int-regs }
349 { uses V{ T{ vreg-use f 30 } T{ vreg-use f 200 } } }
350 { ranges V{ T{ live-range f 30 200 } } }
353 H{ { int-regs { "A" } } }
361 { reg-class int-regs }
364 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } }
365 { ranges V{ T{ live-range f 0 100 } } }
369 { reg-class int-regs }
372 { uses V{ T{ vreg-use f 30 } T{ vreg-use f 100 } } }
373 { ranges V{ T{ live-range f 30 100 } } }
376 H{ { int-regs { "A" } } }
380 ! Problem with spilling intervals with no more usages after the spill location
387 } representations set
393 { reg-class int-regs }
396 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } }
397 { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
401 { reg-class int-regs }
404 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } }
405 { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
409 { reg-class int-regs }
412 { uses V{ T{ vreg-use f 6 } } }
413 { ranges V{ T{ live-range f 4 8 } } }
417 { reg-class int-regs }
420 { uses V{ T{ vreg-use f 8 } } }
421 { ranges V{ T{ live-range f 4 8 } } }
424 ! This guy will invoke the 'spill partially available' code path
427 { reg-class int-regs }
430 { uses V{ T{ vreg-use f 8 } } }
431 { ranges V{ T{ live-range f 4 8 } } }
434 H{ { int-regs { "A" "B" } } }
438 ! Test spill-new code path
444 { reg-class int-regs }
447 { uses V{ T{ vreg-use f 0 } T{ vreg-use f 6 } T{ vreg-use f 10 } } }
448 { ranges V{ T{ live-range f 0 10 } } }
451 ! This guy will invoke the 'spill new' code path
454 { reg-class int-regs }
457 { uses V{ T{ vreg-use f 8 } } }
458 { ranges V{ T{ live-range f 2 8 } } }
461 H{ { int-regs { "A" } } }
466 T{ live-range f 0 10 }
467 T{ live-range f 20 30 }
472 T{ live-range f 0 10 }
473 T{ live-range f 10 30 }
478 T{ live-range f 0 10 }
479 T{ live-range f 5 30 }
484 T{ live-range f 5 30 }
485 T{ live-range f 0 10 }
490 T{ live-range f 5 10 }
491 T{ live-range f 0 15 }
497 T{ live-range f 0 10 }
498 T{ live-range f 20 30 }
499 T{ live-range f 40 50 }
502 T{ live-range f 11 15 }
503 T{ live-range f 31 35 }
504 T{ live-range f 50 55 }
506 intersect-live-ranges
511 T{ live-range f 0 10 }
512 T{ live-range f 20 30 }
513 T{ live-range f 40 50 }
516 T{ live-range f 11 15 }
517 T{ live-range f 31 36 }
518 T{ live-range f 51 55 }
520 intersect-live-ranges
526 { reg-class int-regs }
529 { ranges V{ T{ live-range f 0 10 } } }
533 { reg-class int-regs }
536 { ranges V{ T{ live-range f 5 10 } } }
538 relevant-ranges intersect-live-ranges
541 ! register-status had problems because it used map>assoc where the sequence
548 } representations set
551 H{ { int-regs { 0 1 } } } registers set
557 { reg-class int-regs }
561 { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
562 { uses V{ 0 2 10 20 } }
567 { reg-class int-regs }
571 { ranges V{ T{ live-range f 4 6 } T{ live-range f 30 40 } } }
572 { uses V{ 4 6 30 40 } }
576 } inactive-intervals set
582 { reg-class int-regs }
586 { ranges V{ T{ live-range f 0 40 } } }
591 } active-intervals set
595 { reg-class int-regs }
598 { ranges V{ T{ live-range f 8 10 } } }
599 { uses V{ T{ vreg-use f 8 } T{ vreg-use f 10 } } }
604 :: test-linear-scan-on-cfg ( regs -- )
606 cfg new 0 get >>entry
608 dup fake-representations
609 dup { { int-regs regs } } (linear-scan)
610 flatten-cfg 1array mr.
613 ! Bug in live spill slots calculation
615 V{ T{ ##prologue } T{ ##branch } } 0 test-bb
634 T{ ##compare-imm-branch
670 ! Bug in inactive interval handling
671 ! [ rot dup [ -rot ] when ]
672 V{ T{ ##prologue } T{ ##branch } } 0 test-bb
687 T{ ##compare-imm-branch
751 [ ] [ { 1 2 3 4 } test-linear-scan-on-cfg ] unit-test
753 ! Similar to the above
754 ! [ swap dup [ rot ] when ]
759 { instructions V{ T{ ##prologue } T{ ##branch } } }
771 T{ ##compare-imm-branch
842 [ ] [ { 1 2 3 4 } test-linear-scan-on-cfg ] unit-test
844 ! compute-live-registers was inaccurate since it didn't take
845 ! lifetime holes into account
847 V{ T{ ##prologue } T{ ##branch } } 0 test-bb
854 T{ ##compare-imm-branch
897 [ ] [ { 1 2 3 4 } test-linear-scan-on-cfg ] unit-test
899 ! Inactive interval handling: splitting active interval
900 ! if it fits in lifetime hole only partially
902 V{ T{ ##peek f 3 R 1 } T{ ##branch } } 0 test-bb
906 T{ ##compare-imm-branch f 2 5 cc= }
918 T{ ##replace f 1 D 2 }
923 T{ ##replace f 3 R 2 }
924 T{ ##replace f 0 D 0 }
930 [ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
932 ! Not until splitting is finished
933 ! [ _copy ] [ 3 get instructions>> second class ] unit-test
935 ! Resolve pass; make sure the spilling is done correctly
936 V{ T{ ##peek f 3 R 1 } T{ ##branch } } 0 test-bb
940 T{ ##compare-imm-branch f 2 5 cc= }
948 T{ ##replace f 3 R 1 }
951 T{ ##replace f 1 D 2 }
952 T{ ##replace f 0 D 2 }
957 T{ ##replace f 3 R 2 }
963 [ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
965 [ ##spill ] [ 2 get successors>> first instructions>> first class ] unit-test
967 [ ##spill ] [ 3 get instructions>> second class ] unit-test
969 [ f ] [ 3 get instructions>> [ ##reload? ] any? ] unit-test
971 [ ##reload ] [ 4 get instructions>> first class ] unit-test
980 T{ ##compare-imm-branch f 0 5 cc= }
984 T{ ##replace f 0 D 0 }
987 T{ ##replace f 1 D 0 }
988 T{ ##replace f 2 D 0 }
998 T{ ##compare-imm-branch f 1 5 cc= }
1002 T{ ##replace f 0 D 0 }
1007 T{ ##replace f 0 D 0 }
1017 [ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
1019 [ t ] [ 2 get instructions>> [ ##spill? ] any? ] unit-test
1021 [ t ] [ 3 get predecessors>> first instructions>> [ ##spill? ] any? ] unit-test
1023 [ t ] [ 5 get instructions>> [ ##reload? ] any? ] unit-test
1025 ! A more complicated failure case with resolve that came up after the above
1027 V{ T{ ##branch } } 0 test-bb
1036 V{ T{ ##branch } } 2 test-bb
1037 V{ T{ ##branch } } 3 test-bb
1040 T{ ##replace f 1 D 1 }
1041 T{ ##replace f 2 D 2 }
1042 T{ ##replace f 3 D 3 }
1043 T{ ##replace f 4 D 4 }
1044 T{ ##replace f 0 D 0 }
1047 V{ T{ ##replace f 0 D 0 } T{ ##branch } } 5 test-bb
1048 V{ T{ ##return } } 6 test-bb
1049 V{ T{ ##branch } } 7 test-bb
1051 T{ ##replace f 1 D 1 }
1052 T{ ##replace f 2 D 2 }
1053 T{ ##replace f 3 D 3 }
1058 T{ ##replace f 5 D 1 }
1059 T{ ##replace f 6 D 2 }
1060 T{ ##replace f 7 D 3 }
1061 T{ ##replace f 8 D 4 }
1065 T{ ##replace f 1 D 1 }
1066 T{ ##replace f 2 D 2 }
1067 T{ ##replace f 3 D 3 }
1080 [ ] [ { 1 2 3 4 } test-linear-scan-on-cfg ] unit-test
1082 [ ##spill ] [ 1 get instructions>> second class ] unit-test
1083 [ ##reload ] [ 4 get instructions>> 4 swap nth class ] unit-test
1084 [ V{ 3 2 1 } ] [ 8 get instructions>> [ ##spill? ] filter [ dst>> n>> cell / ] map ] unit-test
1085 [ V{ 3 2 1 } ] [ 9 get instructions>> [ ##reload? ] filter [ src>> n>> cell / ] map ] unit-test
1087 ! Resolve pass should insert this
1088 [ ##reload ] [ 5 get predecessors>> first instructions>> first class ] unit-test
1094 T{ ##replace f 1 D 1 }
1095 T{ ##replace f 2 D 2 }
1101 V{ T{ ##branch } } 1 test-bb
1106 T{ ##replace f 3 D 3 }
1107 T{ ##replace f 1 D 1 }
1108 T{ ##replace f 2 D 2 }
1109 T{ ##replace f 0 D 3 }
1113 V{ T{ ##branch } } 3 test-bb
1121 [ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
1123 ! Spilling an interval immediately after its activated;
1124 ! and the interval does not have a use at the activation point
1128 T{ ##replace f 1 D 1 }
1129 T{ ##replace f 2 D 2 }
1134 V{ T{ ##branch } } 1 test-bb
1142 T{ ##replace f 1 D 1 }
1144 T{ ##replace f 2 D 2 }
1148 V{ T{ ##branch } } 4 test-bb
1151 T{ ##replace f 0 D 0 }
1161 [ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
1163 ! Reduction of push-all regression, x86-32
1164 V{ T{ ##prologue } T{ ##branch } } 0 test-bb
1167 T{ ##load-integer { dst 61 } }
1168 T{ ##peek { dst 62 } { loc D 0 } }
1169 T{ ##peek { dst 64 } { loc D 1 } }
1176 T{ ##copy { dst 79 } { src 69 } { rep int-rep } }
1197 T{ ##replace { src 79 } { loc D 3 } }
1198 T{ ##replace { src 62 } { loc D 4 } }
1199 T{ ##replace { src 79 } { loc D 1 } }
1200 T{ ##replace { src 62 } { loc D 2 } }
1201 T{ ##replace { src 61 } { loc D 5 } }
1202 T{ ##replace { src 62 } { loc R 0 } }
1203 T{ ##replace { src 69 } { loc R 1 } }
1204 T{ ##replace { src 97 } { loc D 0 } }
1205 T{ ##call { word resize-array } }
1210 T{ ##peek { dst 98 } { loc R 0 } }
1211 T{ ##peek { dst 100 } { loc D 0 } }
1218 T{ ##peek { dst 108 } { loc D 2 } }
1219 T{ ##peek { dst 110 } { loc D 3 } }
1220 T{ ##peek { dst 112 } { loc D 0 } }
1221 T{ ##peek { dst 114 } { loc D 1 } }
1222 T{ ##peek { dst 116 } { loc D 4 } }
1223 T{ ##peek { dst 119 } { loc R 0 } }
1224 T{ ##copy { dst 109 } { src 108 } { rep int-rep } }
1225 T{ ##copy { dst 111 } { src 110 } { rep int-rep } }
1226 T{ ##copy { dst 113 } { src 112 } { rep int-rep } }
1227 T{ ##copy { dst 115 } { src 114 } { rep int-rep } }
1228 T{ ##copy { dst 117 } { src 116 } { rep int-rep } }
1229 T{ ##copy { dst 120 } { src 119 } { rep int-rep } }
1234 T{ ##copy { dst 109 } { src 62 } { rep int-rep } }
1235 T{ ##copy { dst 111 } { src 61 } { rep int-rep } }
1236 T{ ##copy { dst 113 } { src 62 } { rep int-rep } }
1237 T{ ##copy { dst 115 } { src 79 } { rep int-rep } }
1238 T{ ##copy { dst 117 } { src 64 } { rep int-rep } }
1239 T{ ##copy { dst 120 } { src 69 } { rep int-rep } }
1244 T{ ##replace { src 120 } { loc D 0 } }
1245 T{ ##replace { src 109 } { loc D 3 } }
1246 T{ ##replace { src 111 } { loc D 4 } }
1247 T{ ##replace { src 113 } { loc D 1 } }
1248 T{ ##replace { src 115 } { loc D 2 } }
1249 T{ ##replace { src 117 } { loc D 5 } }
1260 [ ] [ { 1 2 3 4 5 } test-linear-scan-on-cfg ] unit-test
1262 ! Another reduction of push-all
1263 V{ T{ ##prologue } T{ ##branch } } 0 test-bb
1266 T{ ##peek { dst 85 } { loc D 0 } }
1273 T{ ##peek { dst 91 } { loc D 1 } }
1310 T{ ##load-integer { dst 129 } { val 24 } }
1311 T{ ##inc-d { n 4 } }
1312 T{ ##inc-r { n 1 } }
1313 T{ ##replace { src 109 } { loc D 2 } }
1314 T{ ##replace { src 85 } { loc D 3 } }
1315 T{ ##replace { src 128 } { loc D 0 } }
1316 T{ ##replace { src 85 } { loc D 1 } }
1317 T{ ##replace { src 89 } { loc D 4 } }
1318 T{ ##replace { src 96 } { loc R 0 } }
1319 T{ ##replace { src 129 } { loc R 0 } }
1324 T{ ##peek { dst 134 } { loc D 1 } }
1331 T{ ##inc-d { n 1 } }
1332 T{ ##inc-r { n 1 } }
1333 T{ ##replace { src 140 } { loc D 0 } }
1334 T{ ##replace { src 134 } { loc R 0 } }
1335 T{ ##call { word resize-array } }
1340 T{ ##peek { dst 141 } { loc R 0 } }
1341 T{ ##peek { dst 143 } { loc D 0 } }
1348 T{ ##write-barrier-imm
1354 T{ ##inc-d { n -1 } }
1355 T{ ##inc-r { n -1 } }
1356 T{ ##peek { dst 156 } { loc D 2 } }
1357 T{ ##peek { dst 158 } { loc D 3 } }
1358 T{ ##peek { dst 160 } { loc D 0 } }
1359 T{ ##peek { dst 162 } { loc D 1 } }
1360 T{ ##peek { dst 164 } { loc D 4 } }
1361 T{ ##peek { dst 167 } { loc R 0 } }
1362 T{ ##copy { dst 157 } { src 156 } { rep int-rep } }
1363 T{ ##copy { dst 159 } { src 158 } { rep int-rep } }
1364 T{ ##copy { dst 161 } { src 160 } { rep int-rep } }
1365 T{ ##copy { dst 163 } { src 162 } { rep int-rep } }
1366 T{ ##copy { dst 165 } { src 164 } { rep int-rep } }
1367 T{ ##copy { dst 168 } { src 167 } { rep int-rep } }
1372 T{ ##inc-d { n 3 } }
1373 T{ ##inc-r { n 1 } }
1374 T{ ##copy { dst 157 } { src 85 } }
1375 T{ ##copy { dst 159 } { src 89 } }
1376 T{ ##copy { dst 161 } { src 85 } }
1377 T{ ##copy { dst 163 } { src 109 } }
1378 T{ ##copy { dst 165 } { src 91 } }
1379 T{ ##copy { dst 168 } { src 96 } }
1390 T{ ##inc-d { n 1 } }
1391 T{ ##inc-r { n -1 } }
1392 T{ ##replace { src 168 } { loc D 0 } }
1393 T{ ##replace { src 157 } { loc D 3 } }
1394 T{ ##replace { src 159 } { loc D 4 } }
1395 T{ ##replace { src 161 } { loc D 1 } }
1396 T{ ##replace { src 163 } { loc D 2 } }
1397 T{ ##replace { src 165 } { loc D 5 } }
1409 [ ] [ { 1 2 3 4 5 } test-linear-scan-on-cfg ] unit-test
1411 ! Fencepost error in assignment pass
1412 V{ T{ ##branch } } 0 test-bb
1416 T{ ##compare-imm-branch f 0 5 cc= }
1419 V{ T{ ##branch } } 2 test-bb
1424 T{ ##replace f 1 D 0 }
1425 T{ ##replace f 2 D 0 }
1430 T{ ##replace f 0 D 0 }
1436 [ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
1438 [ 0 ] [ 1 get instructions>> [ ##spill? ] count ] unit-test
1440 [ 1 ] [ 2 get instructions>> [ ##spill? ] count ] unit-test
1442 [ 1 ] [ 3 get predecessors>> first instructions>> [ ##spill? ] count ] unit-test
1444 [ 1 ] [ 4 get instructions>> [ ##reload? ] count ] unit-test
1446 ! Another test case for fencepost error in assignment pass
1447 V{ T{ ##branch } } 0 test-bb
1451 T{ ##compare-imm-branch f 0 5 cc= }
1457 T{ ##replace f 1 D 0 }
1458 T{ ##replace f 2 D 0 }
1459 T{ ##replace f 0 D 0 }
1468 T{ ##replace f 0 D 0 }
1474 [ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
1476 [ 0 ] [ 1 get instructions>> [ ##spill? ] count ] unit-test
1478 [ 1 ] [ 2 get instructions>> [ ##spill? ] count ] unit-test
1480 [ 1 ] [ 2 get instructions>> [ ##reload? ] count ] unit-test
1482 [ 0 ] [ 3 get instructions>> [ ##spill? ] count ] unit-test
1484 [ 0 ] [ 4 get instructions>> [ ##reload? ] count ] unit-test