1
2
3
4
5 package ssa
6
7 import (
8 "cmd/compile/internal/types"
9 "testing"
10 )
11
12 func TestSchedule(t *testing.T) {
13 c := testConfig(t)
14 cases := []fun{
15 c.Fun("entry",
16 Bloc("entry",
17 Valu("mem0", OpInitMem, types.TypeMem, 0, nil),
18 Valu("ptr", OpConst64, c.config.Types.Int64, 0xABCD, nil),
19 Valu("v", OpConst64, c.config.Types.Int64, 12, nil),
20 Valu("mem1", OpStore, types.TypeMem, 0, c.config.Types.Int64, "ptr", "v", "mem0"),
21 Valu("mem2", OpStore, types.TypeMem, 0, c.config.Types.Int64, "ptr", "v", "mem1"),
22 Valu("mem3", OpStore, types.TypeMem, 0, c.config.Types.Int64, "ptr", "sum", "mem2"),
23 Valu("l1", OpLoad, c.config.Types.Int64, 0, nil, "ptr", "mem1"),
24 Valu("l2", OpLoad, c.config.Types.Int64, 0, nil, "ptr", "mem2"),
25 Valu("sum", OpAdd64, c.config.Types.Int64, 0, nil, "l1", "l2"),
26 Goto("exit")),
27 Bloc("exit",
28 Exit("mem3"))),
29 }
30 for _, c := range cases {
31 schedule(c.f)
32 if !isSingleLiveMem(c.f) {
33 t.Error("single-live-mem restriction not enforced by schedule for func:")
34 printFunc(c.f)
35 }
36 }
37 }
38
39 func isSingleLiveMem(f *Func) bool {
40 for _, b := range f.Blocks {
41 var liveMem *Value
42 for _, v := range b.Values {
43 for _, w := range v.Args {
44 if w.Type.IsMemory() {
45 if liveMem == nil {
46 liveMem = w
47 continue
48 }
49 if w != liveMem {
50 return false
51 }
52 }
53 }
54 if v.Type.IsMemory() {
55 liveMem = v
56 }
57 }
58 }
59 return true
60 }
61
62 func TestStoreOrder(t *testing.T) {
63
64
65 c := testConfig(t)
66 fun := c.Fun("entry",
67 Bloc("entry",
68 Valu("mem0", OpInitMem, types.TypeMem, 0, nil),
69 Valu("a", OpAdd64, c.config.Types.Int64, 0, nil, "b", "c"),
70 Valu("b", OpLoad, c.config.Types.Int64, 0, nil, "ptr", "mem1"),
71 Valu("c", OpNeg64, c.config.Types.Int64, 0, nil, "b"),
72 Valu("mem1", OpStore, types.TypeMem, 0, c.config.Types.Int64, "ptr", "v", "mem0"),
73 Valu("mem2", OpStore, types.TypeMem, 0, c.config.Types.Int64, "ptr", "a", "mem1"),
74 Valu("ptr", OpConst64, c.config.Types.Int64, 0xABCD, nil),
75 Valu("v", OpConst64, c.config.Types.Int64, 12, nil),
76 Goto("exit")),
77 Bloc("exit",
78 Exit("mem2")))
79
80 CheckFunc(fun.f)
81 order := storeOrder(fun.f.Blocks[0].Values, fun.f.newSparseSet(fun.f.NumValues()), make([]int32, fun.f.NumValues()))
82
83
84 var ai, bi, ci, si int
85 for i, v := range order {
86 switch v.ID {
87 case 2:
88 ai = i
89 case 3:
90 bi = i
91 case 4:
92 ci = i
93 case 5:
94 si = i
95 }
96 }
97 if ai < si || bi < si || ci < si {
98 t.Logf("Func: %s", fun.f)
99 t.Errorf("store order is wrong: got %v, want v2 v3 v4 after v5", order)
100 }
101 }
102
View as plain text