...
Source file src/pkg/cmd/compile/internal/ssa/trim.go
1
2
3
4
5 package ssa
6
7
8
9 func trim(f *Func) {
10 n := 0
11 for _, b := range f.Blocks {
12 if !trimmableBlock(b) {
13 f.Blocks[n] = b
14 n++
15 continue
16 }
17
18
19
20 p, i := b.Preds[0].b, b.Preds[0].i
21 s, j := b.Succs[0].b, b.Succs[0].i
22 ns := len(s.Preds)
23 p.Succs[i] = Edge{s, j}
24 s.Preds[j] = Edge{p, i}
25
26 for _, e := range b.Preds[1:] {
27 p, i := e.b, e.i
28 p.Succs[i] = Edge{s, len(s.Preds)}
29 s.Preds = append(s.Preds, Edge{p, i})
30 }
31
32
33
34 if ns > 1 {
35 for _, v := range s.Values {
36 if v.Op == OpPhi {
37 mergePhi(v, j, b)
38 }
39 }
40
41
42 k := 0
43 for _, v := range b.Values {
44 if v.Op == OpPhi {
45 if v.Uses == 0 {
46 v.resetArgs()
47 continue
48 }
49
50
51
52
53
54
55 args := make([]*Value, len(v.Args))
56 copy(args, v.Args)
57 v.resetArgs()
58 for x := 0; x < j; x++ {
59 v.AddArg(v)
60 }
61 v.AddArg(args[0])
62 for x := j + 1; x < ns; x++ {
63 v.AddArg(v)
64 }
65 for _, a := range args[1:] {
66 v.AddArg(a)
67 }
68 }
69 b.Values[k] = v
70 k++
71 }
72 b.Values = b.Values[:k]
73 }
74
75
76 for _, v := range b.Values {
77 v.Block = s
78 }
79 k := len(b.Values)
80 m := len(s.Values)
81 for i := 0; i < k; i++ {
82 s.Values = append(s.Values, nil)
83 }
84 copy(s.Values[k:], s.Values[:m])
85 copy(s.Values, b.Values)
86 }
87 if n < len(f.Blocks) {
88 f.invalidateCFG()
89 tail := f.Blocks[n:]
90 for i := range tail {
91 tail[i] = nil
92 }
93 f.Blocks = f.Blocks[:n]
94 }
95 }
96
97
98
99 func emptyBlock(b *Block) bool {
100 for _, v := range b.Values {
101 if v.Op != OpPhi {
102 return false
103 }
104 }
105 return true
106 }
107
108
109
110
111
112
113
114
115 func trimmableBlock(b *Block) bool {
116 if b.Kind != BlockPlain || b == b.Func.Entry {
117 return false
118 }
119 s := b.Succs[0].b
120 return s != b && (len(s.Preds) == 1 || emptyBlock(b))
121 }
122
123
124
125 func mergePhi(v *Value, i int, b *Block) {
126 u := v.Args[i]
127 if u.Block == b {
128 if u.Op != OpPhi {
129 b.Func.Fatalf("value %s is not a phi operation", u.LongString())
130 }
131
132
133
134
135
136 v.SetArg(i, u.Args[0])
137 v.AddArgs(u.Args[1:]...)
138 } else {
139
140
141
142
143
144
145 for j := 1; j < len(b.Preds); j++ {
146 v.AddArg(v.Args[i])
147 }
148 }
149 }
150
View as plain text