1
2
3
4
5 package ssa
6
7 import (
8 "fmt"
9 "testing"
10
11 "cmd/compile/internal/ssa/ssaop"
12 )
13
14 const (
15 SetOrder = "SetOrder"
16 SetOrder_Fail = "SetOrder_Fail"
17 SetOrderOrEqual = "SetOrderOrEqual"
18 SetOrderOrEqual_Fail = "SetOrderOrEqual_Fail"
19 Ordered = "Ordered"
20 Ordered_Fail = "Ordered_Fail"
21 OrderedOrEqual = "OrderedOrEqual"
22 OrderedOrEqual_Fail = "OrderedOrEqual_Fail"
23 SetEqual = "SetEqual"
24 SetEqual_Fail = "SetEqual_Fail"
25 Equal = "Equal"
26 Equal_Fail = "Equal_Fail"
27 SetNonEqual = "SetNonEqual"
28 SetNonEqual_Fail = "SetNonEqual_Fail"
29 NonEqual = "NonEqual"
30 NonEqual_Fail = "NonEqual_Fail"
31 Checkpoint = "Checkpoint"
32 Undo = "Undo"
33 )
34
35 type posetTestOp struct {
36 typ string
37 a, b int
38 }
39
40 func vconst(i int) int {
41 if i < -128 || i >= 128 {
42 panic("invalid const")
43 }
44 return 1000 + 128 + i
45 }
46
47 func testPosetOps(t *testing.T, ops []posetTestOp) {
48 var v [1512]*Value
49 for i := range v {
50 v[i] = new(Value)
51 v[i].ID = ID(i)
52 if i >= 1000 && i < 1256 {
53 v[i].Op = ssaop.OpConst64
54 v[i].AuxInt = int64(i - 1000 - 128)
55 }
56 }
57
58 po := newPoset()
59 for idx, op := range ops {
60 t.Logf("op%d%v", idx, op)
61 switch op.typ {
62 case SetOrder:
63 if !po.SetOrder(v[op.a], v[op.b]) {
64 t.Errorf("FAILED: op%d%v failed", idx, op)
65 }
66 case SetOrder_Fail:
67 if po.SetOrder(v[op.a], v[op.b]) {
68 t.Errorf("FAILED: op%d%v passed", idx, op)
69 }
70 case SetOrderOrEqual:
71 if !po.SetOrderOrEqual(v[op.a], v[op.b]) {
72 t.Errorf("FAILED: op%d%v failed", idx, op)
73 }
74 case SetOrderOrEqual_Fail:
75 if po.SetOrderOrEqual(v[op.a], v[op.b]) {
76 t.Errorf("FAILED: op%d%v passed", idx, op)
77 }
78 case Ordered:
79 if !po.Ordered(v[op.a], v[op.b]) {
80 t.Errorf("FAILED: op%d%v failed", idx, op)
81 }
82 case Ordered_Fail:
83 if po.Ordered(v[op.a], v[op.b]) {
84 t.Errorf("FAILED: op%d%v passed", idx, op)
85 }
86 case OrderedOrEqual:
87 if !po.OrderedOrEqual(v[op.a], v[op.b]) {
88 t.Errorf("FAILED: op%d%v failed", idx, op)
89 }
90 case OrderedOrEqual_Fail:
91 if po.OrderedOrEqual(v[op.a], v[op.b]) {
92 t.Errorf("FAILED: op%d%v passed", idx, op)
93 }
94 case SetEqual:
95 if !po.SetEqual(v[op.a], v[op.b]) {
96 t.Errorf("FAILED: op%d%v failed", idx, op)
97 }
98 case SetEqual_Fail:
99 if po.SetEqual(v[op.a], v[op.b]) {
100 t.Errorf("FAILED: op%d%v passed", idx, op)
101 }
102 case Equal:
103 if !po.Equal(v[op.a], v[op.b]) {
104 t.Errorf("FAILED: op%d%v failed", idx, op)
105 }
106 case Equal_Fail:
107 if po.Equal(v[op.a], v[op.b]) {
108 t.Errorf("FAILED: op%d%v passed", idx, op)
109 }
110 case SetNonEqual:
111 if !po.SetNonEqual(v[op.a], v[op.b]) {
112 t.Errorf("FAILED: op%d%v failed", idx, op)
113 }
114 case SetNonEqual_Fail:
115 if po.SetNonEqual(v[op.a], v[op.b]) {
116 t.Errorf("FAILED: op%d%v passed", idx, op)
117 }
118 case NonEqual:
119 if !po.NonEqual(v[op.a], v[op.b]) {
120 t.Errorf("FAILED: op%d%v failed", idx, op)
121 }
122 case NonEqual_Fail:
123 if po.NonEqual(v[op.a], v[op.b]) {
124 t.Errorf("FAILED: op%d%v passed", idx, op)
125 }
126 case Checkpoint:
127 po.Checkpoint()
128 case Undo:
129 t.Log("Undo stack", po.undo)
130 po.Undo()
131 default:
132 panic("unimplemented")
133 }
134
135 if false {
136 po.DotDump(fmt.Sprintf("op%d.dot", idx), fmt.Sprintf("Last op: %v", op))
137 }
138
139 po.CheckIntegrity()
140 }
141
142
143 if err := po.CheckEmpty(); err != nil {
144 t.Error(err)
145 }
146 }
147
148 func TestPoset(t *testing.T) {
149 testPosetOps(t, []posetTestOp{
150 {Ordered_Fail, 123, 124},
151
152
153 {Checkpoint, 0, 0},
154 {SetOrder, 100, 101},
155 {Ordered, 100, 101},
156 {Ordered_Fail, 101, 100},
157 {SetOrder_Fail, 101, 100},
158 {SetOrder, 100, 101},
159 {NonEqual, 100, 101},
160 {NonEqual, 101, 100},
161 {SetEqual_Fail, 100, 101},
162
163
164 {Checkpoint, 0, 0},
165 {SetOrderOrEqual, 4, 7},
166 {OrderedOrEqual, 4, 7},
167 {SetOrder, 7, 12},
168 {Ordered, 7, 12},
169 {Ordered, 4, 12},
170 {Ordered_Fail, 12, 4},
171 {NonEqual, 4, 12},
172 {NonEqual, 12, 4},
173 {NonEqual_Fail, 4, 100},
174 {OrderedOrEqual, 4, 12},
175 {OrderedOrEqual_Fail, 12, 4},
176 {OrderedOrEqual, 4, 7},
177 {OrderedOrEqual_Fail, 7, 4},
178
179
180 {Checkpoint, 0, 0},
181 {SetOrder, 1, 4},
182 {Ordered, 1, 4},
183 {Ordered, 1, 12},
184 {Ordered_Fail, 12, 1},
185
186
187 {Checkpoint, 0, 0},
188 {SetOrder, 6, 7},
189 {Ordered, 6, 7},
190 {Ordered, 6, 12},
191 {SetOrder_Fail, 7, 4},
192 {SetOrder_Fail, 7, 6},
193 {SetOrder_Fail, 7, 1},
194
195
196 {Checkpoint, 0, 0},
197 {Ordered_Fail, 1, 6},
198 {SetOrder, 1, 6},
199 {Ordered, 1, 6},
200 {SetOrder_Fail, 6, 1},
201
202
203 {Checkpoint, 0, 0},
204 {Ordered_Fail, 4, 6},
205 {Ordered_Fail, 4, 7},
206 {SetOrder, 4, 6},
207 {Ordered, 4, 6},
208 {OrderedOrEqual, 4, 6},
209 {Ordered, 4, 7},
210 {OrderedOrEqual, 4, 7},
211 {SetOrder_Fail, 6, 4},
212 {Ordered_Fail, 7, 6},
213 {Ordered_Fail, 7, 4},
214 {OrderedOrEqual_Fail, 7, 6},
215 {OrderedOrEqual_Fail, 7, 4},
216
217
218 {Checkpoint, 0, 0},
219 {Ordered_Fail, 6, 101},
220 {SetOrder, 6, 101},
221 {Ordered, 6, 101},
222 {Ordered, 1, 101},
223
224
225 {Checkpoint, 0, 0},
226 {Ordered_Fail, 6, 100},
227 {SetOrder, 6, 100},
228 {Ordered, 1, 100},
229
230
231 {Ordered, 100, 101},
232 {Undo, 0, 0},
233 {Ordered, 100, 101},
234 {Ordered_Fail, 6, 100},
235 {Ordered, 6, 101},
236 {Ordered, 1, 101},
237
238
239 {Undo, 0, 0},
240 {Ordered_Fail, 1, 100},
241 {Ordered_Fail, 1, 101},
242 {Ordered_Fail, 6, 100},
243 {Ordered_Fail, 6, 101},
244
245
246 {Checkpoint, 0, 0},
247 {Ordered, 100, 101},
248 {SetOrder, 6, 100},
249 {Ordered, 6, 100},
250 {Ordered, 6, 101},
251 {Ordered, 1, 101},
252
253
254 {Undo, 0, 0},
255 {Undo, 0, 0},
256 {Ordered, 1, 6},
257 {Ordered, 4, 12},
258 {Ordered_Fail, 4, 6},
259 {SetOrder_Fail, 6, 1},
260
261
262 {Undo, 0, 0},
263 {Undo, 0, 0},
264 {Ordered, 1, 12},
265 {Ordered, 7, 12},
266 {Ordered_Fail, 1, 6},
267 {Ordered_Fail, 6, 7},
268 {Ordered, 100, 101},
269 {Ordered_Fail, 1, 101},
270
271
272 {Undo, 0, 0},
273 {Ordered_Fail, 1, 12},
274 {Ordered_Fail, 1, 4},
275 {Ordered, 4, 12},
276 {Ordered, 100, 101},
277
278
279 {Undo, 0, 0},
280 {Ordered_Fail, 4, 7},
281 {Ordered_Fail, 7, 12},
282 {Ordered, 100, 101},
283
284
285
286
287 {Checkpoint, 0, 0},
288 {SetOrder, 101, 102},
289 {SetOrder, 102, 105},
290 {SetOrder, 102, 106},
291 {SetOrder, 106, 107},
292 {SetOrder, 1, 2},
293 {SetOrder, 2, 5},
294 {SetOrder, 2, 6},
295 {SetEqual_Fail, 1, 6},
296 {SetEqual_Fail, 107, 102},
297
298
299
300 {Checkpoint, 0, 0},
301 {SetEqual, 2, 102},
302 {Equal, 2, 102},
303 {SetEqual, 2, 102},
304 {SetNonEqual_Fail, 2, 102},
305 {Ordered, 1, 107},
306 {Ordered, 101, 6},
307 {Ordered, 101, 105},
308 {Ordered, 2, 106},
309 {Ordered, 102, 6},
310
311
312 {Undo, 0, 0},
313 {Equal_Fail, 2, 102},
314 {Ordered_Fail, 2, 102},
315 {Ordered_Fail, 1, 107},
316 {Ordered_Fail, 101, 6},
317 {Checkpoint, 0, 0},
318 {SetEqual, 2, 100},
319 {Ordered, 1, 107},
320 {Ordered, 100, 6},
321
322
323 {Undo, 0, 0},
324 {Checkpoint, 0, 0},
325 {SetEqual, 2, 400},
326 {SetEqual, 401, 2},
327 {Equal, 400, 401},
328 {Ordered, 1, 400},
329 {Ordered, 400, 6},
330 {Ordered, 1, 401},
331 {Ordered, 401, 6},
332 {Ordered_Fail, 2, 401},
333
334
335 {Checkpoint, 0, 0},
336 {SetEqual, 500, 501},
337 {SetEqual, 102, 501},
338 {Equal, 500, 102},
339 {Ordered, 501, 106},
340 {Ordered, 100, 500},
341 {SetEqual, 500, 501},
342 {Ordered_Fail, 500, 501},
343 {Ordered_Fail, 102, 501},
344
345
346 {Undo, 0, 0},
347 {Checkpoint, 0, 0},
348 {SetNonEqual, 600, 601},
349 {NonEqual, 600, 601},
350 {SetNonEqual, 601, 602},
351 {NonEqual, 601, 602},
352 {NonEqual_Fail, 600, 602},
353 {SetEqual_Fail, 601, 602},
354
355
356 {Undo, 0, 0},
357 {Undo, 0, 0},
358 {Undo, 0, 0},
359 {Undo, 0, 0},
360 })
361 }
362
363 func TestPosetStrict(t *testing.T) {
364
365 testPosetOps(t, []posetTestOp{
366 {Checkpoint, 0, 0},
367
368 {SetNonEqual, 20, 30},
369 {SetOrder, 10, 20},
370 {SetOrderOrEqual, 20, 30},
371 {SetOrder, 30, 40},
372
373 {Ordered, 10, 30},
374 {Ordered, 20, 30},
375 {Ordered, 10, 40},
376 {OrderedOrEqual, 10, 30},
377 {OrderedOrEqual, 20, 30},
378 {OrderedOrEqual, 10, 40},
379
380 {Undo, 0, 0},
381
382
383 {Checkpoint, 0, 0},
384 {SetOrder, 10, 20},
385 {SetOrderOrEqual, 20, 30},
386 {SetOrder, 30, 40},
387
388 {Ordered, 10, 30},
389 {Ordered_Fail, 20, 30},
390 {Ordered, 10, 40},
391 {OrderedOrEqual, 10, 30},
392 {OrderedOrEqual, 20, 30},
393 {OrderedOrEqual, 10, 40},
394
395 {Checkpoint, 0, 0},
396 {SetNonEqual, 20, 30},
397 {Ordered, 10, 30},
398 {Ordered, 20, 30},
399 {Ordered, 10, 40},
400 {OrderedOrEqual, 10, 30},
401 {OrderedOrEqual, 20, 30},
402 {OrderedOrEqual, 10, 40},
403 {Undo, 0, 0},
404
405 {Checkpoint, 0, 0},
406 {SetOrderOrEqual, 30, 35},
407 {OrderedOrEqual, 20, 35},
408 {Ordered_Fail, 20, 35},
409 {SetNonEqual, 20, 35},
410 {Ordered, 20, 35},
411 {Undo, 0, 0},
412
413
414 {Checkpoint, 0, 0},
415 {SetOrderOrEqual, 50, 60},
416 {SetOrderOrEqual, 60, 50},
417 {OrderedOrEqual, 50, 60},
418 {OrderedOrEqual, 60, 50},
419 {Ordered_Fail, 50, 60},
420 {Ordered_Fail, 60, 50},
421 {Equal, 50, 60},
422 {Equal, 60, 50},
423 {NonEqual_Fail, 50, 60},
424 {NonEqual_Fail, 60, 50},
425 {Undo, 0, 0},
426
427 {Undo, 0, 0},
428 })
429 }
430
431 func TestPosetCollapse(t *testing.T) {
432 testPosetOps(t, []posetTestOp{
433 {Checkpoint, 0, 0},
434
435 {SetOrderOrEqual, 10, 15},
436 {SetOrderOrEqual, 15, 20},
437 {SetOrderOrEqual, 20, vconst(20)},
438 {SetOrderOrEqual, vconst(20), 25},
439 {SetOrderOrEqual, 10, 12},
440 {SetOrderOrEqual, 12, 16},
441 {SetOrderOrEqual, 16, vconst(20)},
442 {SetOrderOrEqual, 10, 17},
443 {SetOrderOrEqual, 17, 25},
444 {SetOrderOrEqual, 15, 18},
445 {SetOrderOrEqual, 18, vconst(20)},
446 {SetOrderOrEqual, 15, 19},
447 {SetOrderOrEqual, 19, 25},
448
449
450 {SetOrderOrEqual, 10, 11},
451 {SetOrderOrEqual, 11, 26},
452 {SetOrderOrEqual, 13, 25},
453 {SetOrderOrEqual, 100, 25},
454 {SetOrderOrEqual, 101, 15},
455 {SetOrderOrEqual, 102, 10},
456 {SetOrderOrEqual, 25, 103},
457 {SetOrderOrEqual, 20, 104},
458
459 {Checkpoint, 0, 0},
460
461 {SetOrderOrEqual, 25, 10},
462
463
464 {Equal, 10, 12},
465 {Equal, 10, 15},
466 {Equal, 10, 16},
467 {Equal, 10, 17},
468 {Equal, 10, 18},
469 {Equal, 10, 19},
470 {Equal, 10, vconst(20)},
471 {Equal, 10, 25},
472
473 {Equal, 12, 15},
474 {Equal, 12, 16},
475 {Equal, 12, 17},
476 {Equal, 12, 18},
477 {Equal, 12, 19},
478 {Equal, 12, vconst(20)},
479 {Equal, 12, 25},
480
481 {Equal, 15, 16},
482 {Equal, 15, 17},
483 {Equal, 15, 18},
484 {Equal, 15, 19},
485 {Equal, 15, vconst(20)},
486 {Equal, 15, 25},
487
488 {Equal, 16, 17},
489 {Equal, 16, 18},
490 {Equal, 16, 19},
491 {Equal, 16, vconst(20)},
492 {Equal, 16, 25},
493
494 {Equal, 17, 18},
495 {Equal, 17, 19},
496 {Equal, 17, vconst(20)},
497 {Equal, 17, 25},
498
499 {Equal, 18, 19},
500 {Equal, 18, vconst(20)},
501 {Equal, 18, 25},
502
503 {Equal, 19, vconst(20)},
504 {Equal, 19, 25},
505
506 {Equal, vconst(20), 25},
507
508
509 {Equal_Fail, 10, 11},
510 {Equal_Fail, 10, 26},
511 {Equal_Fail, 10, 100},
512 {Equal_Fail, 10, 101},
513 {Equal_Fail, 10, 102},
514 {OrderedOrEqual, 10, 26},
515 {OrderedOrEqual, 25, 26},
516 {OrderedOrEqual, 13, 25},
517 {OrderedOrEqual, 13, 10},
518
519 {Undo, 0, 0},
520 {OrderedOrEqual, 10, 25},
521 {Equal_Fail, 10, 12},
522 {Equal_Fail, 10, 15},
523 {Equal_Fail, 10, 25},
524
525 {Undo, 0, 0},
526 })
527
528 testPosetOps(t, []posetTestOp{
529 {Checkpoint, 0, 0},
530 {SetOrderOrEqual, 10, 15},
531 {SetOrderOrEqual, 15, 20},
532 {SetOrderOrEqual, 20, 25},
533 {SetOrder, 10, 16},
534 {SetOrderOrEqual, 16, 20},
535
536 {SetOrderOrEqual_Fail, 20, 10},
537 {Undo, 0, 0},
538 })
539 }
540
541 func TestPosetSetEqual(t *testing.T) {
542 testPosetOps(t, []posetTestOp{
543
544 {Checkpoint, 0, 0},
545 {SetOrderOrEqual, 10, 20},
546 {SetOrderOrEqual, 20, 30},
547 {SetOrder, 30, 40},
548 {SetOrderOrEqual, 20, 100},
549 {SetOrder, 100, 110},
550 {OrderedOrEqual, 10, 30},
551 {OrderedOrEqual_Fail, 30, 10},
552 {Ordered_Fail, 10, 30},
553 {Ordered_Fail, 30, 10},
554 {Ordered, 10, 40},
555 {Ordered_Fail, 40, 10},
556
557
558 {Checkpoint, 0, 0},
559 {SetEqual, 10, 20},
560 {OrderedOrEqual, 10, 20},
561 {Ordered_Fail, 10, 20},
562 {Equal, 10, 20},
563 {SetOrderOrEqual, 10, 20},
564 {SetOrderOrEqual, 20, 10},
565 {SetOrder_Fail, 10, 20},
566 {SetOrder_Fail, 20, 10},
567 {Undo, 0, 0},
568
569
570 {Checkpoint, 0, 0},
571 {SetEqual, 20, 10},
572 {OrderedOrEqual, 10, 20},
573 {Ordered_Fail, 10, 20},
574 {Equal, 10, 20},
575 {Undo, 0, 0},
576
577
578 {Checkpoint, 0, 0},
579 {SetEqual_Fail, 10, 40},
580 {SetEqual_Fail, 40, 10},
581 {SetEqual_Fail, 30, 40},
582 {SetEqual_Fail, 40, 30},
583 {SetEqual_Fail, 10, 110},
584 {SetEqual_Fail, 110, 10},
585 {Undo, 0, 0},
586
587
588 {Checkpoint, 0, 0},
589 {SetEqual, 40, 110},
590 {SetEqual_Fail, 10, 40},
591 {SetEqual_Fail, 40, 10},
592 {SetEqual_Fail, 10, 110},
593 {SetEqual_Fail, 110, 10},
594 {Undo, 0, 0},
595
596
597 {Checkpoint, 0, 0},
598 {SetOrder_Fail, 40, 20},
599 {SetOrder_Fail, 30, 20},
600 {SetOrder_Fail, 110, 10},
601 {Undo, 0, 0},
602
603
604 {Checkpoint, 0, 0},
605 {SetOrderOrEqual, 30, 20},
606 {Equal, 30, 20},
607 {OrderedOrEqual, 30, 100},
608 {Ordered, 30, 110},
609 {Undo, 0, 0},
610
611 {Undo, 0, 0},
612 })
613 }
614
615 func TestPosetNonEqual(t *testing.T) {
616 testPosetOps(t, []posetTestOp{
617 {Equal_Fail, 10, 20},
618 {NonEqual_Fail, 10, 20},
619
620
621 {Checkpoint, 0, 0},
622 {SetNonEqual, 10, 20},
623 {Equal_Fail, 10, 20},
624 {NonEqual, 10, 20},
625 {SetEqual_Fail, 10, 20},
626
627
628 {Checkpoint, 0, 0},
629 {SetNonEqual, 10, 20},
630 {Equal_Fail, 10, 20},
631 {NonEqual, 10, 20},
632
633
634 {Undo, 0, 0},
635 {Equal_Fail, 10, 20},
636 {NonEqual, 10, 20},
637 {SetEqual_Fail, 10, 20},
638
639
640 {Undo, 0, 0},
641 {Equal_Fail, 10, 20},
642 {NonEqual_Fail, 10, 20},
643
644
645 {Checkpoint, 0, 0},
646 {SetEqual, 10, 20},
647 {Equal, 10, 20},
648 {NonEqual_Fail, 10, 20},
649 {SetNonEqual_Fail, 10, 20},
650
651
652 {Checkpoint, 0, 0},
653 {SetEqual, 10, 20},
654 {Equal, 10, 20},
655 {NonEqual_Fail, 10, 20},
656 {SetNonEqual_Fail, 10, 20},
657
658
659 {Undo, 0, 0},
660 {Equal, 10, 20},
661 {NonEqual_Fail, 10, 20},
662 {SetNonEqual_Fail, 10, 20},
663
664
665 {Undo, 0, 0},
666 {Equal_Fail, 10, 20},
667 {NonEqual_Fail, 10, 20},
668 })
669 }
670
View as plain text