...
Source file src/pkg/cmd/compile/internal/ssa/zcse.go
1
2
3
4
5 package ssa
6
7 import "cmd/compile/internal/types"
8
9
10
11
12
13
14 func zcse(f *Func) {
15 vals := make(map[vkey]*Value)
16
17 for _, b := range f.Blocks {
18 for i := 0; i < len(b.Values); {
19 v := b.Values[i]
20 next := true
21 if opcodeTable[v.Op].argLen == 0 {
22 key := vkey{v.Op, keyFor(v), v.Aux, v.Type}
23 if vals[key] == nil {
24 vals[key] = v
25 if b != f.Entry {
26
27
28
29 v.Block = f.Entry
30 f.Entry.Values = append(f.Entry.Values, v)
31 last := len(b.Values) - 1
32 b.Values[i] = b.Values[last]
33 b.Values[last] = nil
34 b.Values = b.Values[:last]
35
36
37 next = false
38 }
39 }
40 }
41 if next {
42 i++
43 }
44 }
45 }
46
47 for _, b := range f.Blocks {
48 for _, v := range b.Values {
49 for i, a := range v.Args {
50 if opcodeTable[a.Op].argLen == 0 {
51 key := vkey{a.Op, keyFor(a), a.Aux, a.Type}
52 if rv, ok := vals[key]; ok {
53 v.SetArg(i, rv)
54 }
55 }
56 }
57 }
58 }
59 }
60
61
62 type vkey struct {
63 op Op
64 ai int64
65 ax interface{}
66 t *types.Type
67 }
68
69
70
71 func keyFor(v *Value) int64 {
72 switch v.Op {
73 case OpConst64, OpConst64F, OpConst32F:
74 return v.AuxInt
75 case OpConst32:
76 return int64(int32(v.AuxInt))
77 case OpConst16:
78 return int64(int16(v.AuxInt))
79 case OpConst8, OpConstBool:
80 return int64(int8(v.AuxInt))
81 default:
82 return v.AuxInt
83 }
84 }
85
View as plain text