1
2
3
4
5 package ssacompile
6
7 import (
8 "cmd/compile/internal/ssa"
9 "cmd/compile/internal/ssa/block"
10 "cmd/internal/src"
11 )
12
13
14 func deadcode(f *ssa.Func) {
15
16
17
18
19
20
21 if f.RegAlloc != nil {
22 f.Fatalf("deadcode after regalloc")
23 }
24
25
26 reachable := ssa.ReachableBlocks(f)
27
28
29 for _, b := range f.Blocks {
30 if reachable[b.ID] {
31 continue
32 }
33 for i := 0; i < len(b.Succs); {
34 e := b.Succs[i]
35 if reachable[e.B.ID] {
36 b.RemoveEdge(i)
37 } else {
38 i++
39 }
40 }
41 }
42
43
44 for _, b := range f.Blocks {
45 if !reachable[b.ID] {
46 continue
47 }
48 if b.Kind != block.BlockFirst {
49 continue
50 }
51 b.RemoveEdge(1)
52 b.Kind = block.BlockPlain
53 b.Likely = ssa.BranchUnknown
54 }
55
56
57 copyelim(f)
58
59
60 live, order := ssa.LiveValues(f, reachable)
61 defer func() { f.Cache.FreeBoolSlice(live) }()
62 defer func() { f.Cache.FreeValueSlice(order) }()
63
64
65 s := f.NewSparseSet(f.NumValues())
66 defer f.RetSparseSet(s)
67 i := 0
68 for _, name := range f.Names {
69 j := 0
70 s.Clear()
71 values := f.NamedValues[name]
72 for _, v := range values {
73 if live[v.ID] && !s.Contains(v.ID) {
74 values[j] = v
75 j++
76 s.Add(v.ID)
77 }
78 }
79 if j == 0 {
80 delete(f.NamedValues, name)
81 } else {
82 f.Names[i] = name
83 i++
84 for k := len(values) - 1; k >= j; k-- {
85 values[k] = nil
86 }
87 f.NamedValues[name] = values[:j]
88 }
89 }
90 clear(f.Names[i:])
91 f.Names = f.Names[:i]
92
93 pendingLines := f.CachedLineStarts
94 pendingLines.Clear()
95
96
97 for i, b := range f.Blocks {
98 if !reachable[b.ID] {
99
100 b.ResetControls()
101 }
102 for _, v := range b.Values {
103 if !live[v.ID] {
104 v.ResetArgs()
105 if v.Pos.IsStmt() == src.PosIsStmt && reachable[b.ID] {
106 pendingLines.Set(v.Pos, int32(i))
107 }
108 }
109 }
110 }
111
112
113 for i := len(order) - 1; i >= 0; i-- {
114 w := order[i]
115 if j, ok := pendingLines.Get(w.Pos); ok && f.Blocks[j] == w.Block {
116 w.Pos = w.Pos.WithIsStmt()
117 pendingLines.Remove(w.Pos)
118 }
119 }
120
121
122 pendingLines.ForeachEntry(func(j int32, l uint, bi int32) {
123 b := f.Blocks[bi]
124 if b.Pos.Line() == l && b.Pos.FileIndex() == j {
125 b.Pos = b.Pos.WithIsStmt()
126 }
127 })
128
129
130
131 for _, b := range f.Blocks {
132 i := 0
133 for _, v := range b.Values {
134 if live[v.ID] {
135 b.Values[i] = v
136 i++
137 } else {
138 f.FreeValue(v)
139 }
140 }
141 b.TruncateValues(i)
142 }
143
144
145 i = 0
146 for _, b := range f.Blocks {
147 if reachable[b.ID] {
148 f.Blocks[i] = b
149 i++
150 } else {
151 if len(b.Values) > 0 {
152 b.Fatalf("live values in unreachable block %v: %v", b, b.Values)
153 }
154 f.FreeBlock(b)
155 }
156 }
157
158 clear(f.Blocks[i:])
159 f.Blocks = f.Blocks[:i]
160 }
161
View as plain text