1
2
3
4
5 package ssacompile
6
7 import (
8 "cmd/compile/internal/ssa"
9 "cmd/compile/internal/ssa/block"
10 "cmd/compile/internal/ssa/ssaop"
11 )
12
13
14
15
16 func critical(f *ssa.Func) {
17
18 blocks := f.Cache.AllocBlockSlice(f.NumValues())
19 defer f.Cache.FreeBlockSlice(blocks)
20
21
22 for j := 0; j < len(f.Blocks); j++ {
23 b := f.Blocks[j]
24 if len(b.Preds) <= 1 {
25 continue
26 }
27
28 var phi *ssa.Value
29
30
31
32 for _, v := range b.Values {
33 if v.Op == ssaop.OpPhi {
34 if phi != nil {
35 phi = nil
36 break
37 }
38 phi = v
39 }
40 }
41
42
43 if phi != nil {
44 for _, v := range phi.Args {
45 blocks[v.ID] = nil
46 }
47 }
48
49
50 for i := 0; i < len(b.Preds); {
51 e := b.Preds[i]
52 p := e.B
53 pi := e.I
54 if p.Kind == block.BlockPlain {
55 i++
56 continue
57 }
58
59 var d *ssa.Block
60 reusedBlock := false
61 if phi != nil {
62 argID := phi.Args[i].ID
63
64
65 if d = blocks[argID]; d == nil {
66
67
68
69 d = f.NewBlock(block.BlockPlain)
70 d.Pos = p.Pos
71
72
73
74 d.CPUfeatures = p.CPUfeatures | b.CPUfeatures
75 blocks[argID] = d
76 if f.Pass.Debug > 0 {
77 f.Warnl(p.Pos, "split critical edge")
78 if d.CPUfeatures != ssa.CPUNone {
79 f.Warnl(p.Pos, "split-edge block b%d has features %v", d.ID, d.CPUfeatures)
80 }
81 }
82 } else {
83 reusedBlock = true
84
85
86
87 d.CPUfeatures &= p.CPUfeatures | b.CPUfeatures
88 if f.Pass.Debug > 0 && d.CPUfeatures != ssa.CPUNone {
89 f.Warnl(p.Pos, "reused split-edge block b%d has features %v", d.ID, d.CPUfeatures)
90 }
91 }
92 } else {
93
94
95 d = f.NewBlock(block.BlockPlain)
96 d.Pos = p.Pos
97
98 d.CPUfeatures = p.CPUfeatures | b.CPUfeatures
99 if f.Pass.Debug > 0 {
100 f.Warnl(p.Pos, "split critical edge")
101 if d.CPUfeatures != ssa.CPUNone {
102 f.Warnl(p.Pos, "split-edge block b%d has features %v", d.ID, d.CPUfeatures)
103 }
104 }
105 }
106
107
108
109
110
111 if reusedBlock {
112
113 p.Succs[pi] = ssa.Edge{B: d, I: len(d.Preds)}
114 d.Preds = append(d.Preds, ssa.Edge{B: p, I: pi})
115
116
117 b.RemovePred(i)
118
119
120 b.RemovePhiArg(phi, i)
121
122
123
124
125
126 } else {
127
128 p.Succs[pi] = ssa.Edge{B: d, I: 0}
129 b.Preds[i] = ssa.Edge{B: d, I: 0}
130 d.Preds = append(d.Preds, ssa.Edge{B: p, I: pi})
131 d.Succs = append(d.Succs, ssa.Edge{B: b, I: i})
132 i++
133 }
134 }
135 }
136 }
137
View as plain text