@@ -24,7 +24,7 @@ import (
24
24
//
25
25
// It starts with optimistically assuming that all SSA values are initially Top
26
26
// and then propagates constant facts only along reachable control flow paths.
27
- // Due to certain basic blocks being never accessed, some inputs of phi become
27
+ // Since some basic blocks are not visited yet, corresponding inputs of phi become
28
28
// Top, we use the meet(args...) for phi to compute its lattice.
29
29
//
30
30
// Top ∩ any = any
@@ -75,23 +75,40 @@ func possibleConst(val *Value) bool {
75
75
case OpPhi :
76
76
fallthrough
77
77
case
78
+ // negate
78
79
OpNeg8 , OpNeg16 , OpNeg32 , OpNeg64 , OpNeg32F , OpNeg64F ,
79
80
OpCom8 , OpCom16 , OpCom32 , OpCom64 ,
81
+ // math
80
82
OpFloor , OpCeil , OpTrunc , OpRoundToEven ,
83
+ // conversion
84
+ OpTrunc16to8 , OpTrunc32to8 , OpTrunc32to16 , OpTrunc64to8 ,
85
+ OpTrunc64to16 , OpTrunc64to32 , OpCvt32to32F , OpCvt32to64F ,
86
+ OpCvt64to32F , OpCvt64to64F , OpCvt32Fto32 , OpCvt32Fto64 ,
87
+ OpCvt64Fto32 , OpCvt64Fto64 , OpCvt32Fto64F , OpCvt64Fto32F ,
88
+ OpCvtBoolToUint8 ,
89
+ OpZeroExt8to16 , OpZeroExt8to32 , OpZeroExt8to64 , OpZeroExt16to32 ,
90
+ OpZeroExt16to64 , OpZeroExt32to64 , OpSignExt8to16 , OpSignExt8to32 ,
91
+ OpSignExt8to64 , OpSignExt16to32 , OpSignExt16to64 , OpSignExt32to64 ,
92
+ // not
81
93
OpNot :
82
94
fallthrough
83
95
case
96
+ // add
84
97
OpAdd64 , OpAdd32 , OpAdd16 , OpAdd8 ,
85
98
OpAdd32F , OpAdd64F ,
99
+ // sub
86
100
OpSub64 , OpSub32 , OpSub16 , OpSub8 ,
87
101
OpSub32F , OpSub64F ,
102
+ // mul
88
103
OpMul64 , OpMul32 , OpMul16 , OpMul8 ,
89
104
OpMul32F , OpMul64F ,
105
+ // div
90
106
OpDiv32F , OpDiv64F ,
91
107
OpDiv8 , OpDiv16 , OpDiv32 , OpDiv64 ,
92
108
OpDiv8u , OpDiv16u , OpDiv32u , OpDiv64u ,
93
109
OpMod8 , OpMod16 , OpMod32 , OpMod64 ,
94
110
OpMod8u , OpMod16u , OpMod32u , OpMod64u ,
111
+ // compare
95
112
OpEq64 , OpEq32 , OpEq16 , OpEq8 ,
96
113
OpEq32F , OpEq64F ,
97
114
OpLess64 , OpLess32 , OpLess16 , OpLess8 ,
@@ -101,10 +118,13 @@ func possibleConst(val *Value) bool {
101
118
OpLeq64U , OpLeq32U , OpLeq16U , OpLeq8U ,
102
119
OpLeq32F , OpLeq64F ,
103
120
OpEqB , OpNeqB ,
121
+ // shift
104
122
OpLsh64x64 , OpRsh64x64 , OpRsh64Ux64 , OpLsh32x64 ,
105
123
OpRsh32x64 , OpRsh32Ux64 , OpLsh16x64 , OpRsh16x64 ,
106
124
OpRsh16Ux64 , OpLsh8x64 , OpRsh8x64 , OpRsh8Ux64 ,
125
+ // inbound safety check
107
126
OpIsInBounds , OpIsSliceInBounds ,
127
+ // bit
108
128
OpAnd8 , OpAnd16 , OpAnd32 , OpAnd64 ,
109
129
OpOr8 , OpOr16 , OpOr32 , OpOr64 ,
110
130
OpXor8 , OpXor16 , OpXor32 , OpXor64 :
@@ -158,10 +178,10 @@ func (t *worklist) buildDefUses() {
158
178
for _ , block := range t .f .Blocks {
159
179
for _ , val := range block .Values {
160
180
for _ , arg := range val .Args {
161
- // find its uses, only uses that can become constant takes into account
181
+ // find its uses, only uses that can become constants take into account
162
182
if possibleConst (arg ) && possibleConst (val ) {
163
183
if _ , exist := t .defUse [arg ]; ! exist {
164
- t .defUse [arg ] = make ([]* Value , 0 )
184
+ t .defUse [arg ] = make ([]* Value , 0 , arg . Uses )
165
185
}
166
186
t .defUse [arg ] = append (t .defUse [arg ], val )
167
187
}
@@ -298,6 +318,15 @@ func (t *worklist) visitValue(val *Value) {
298
318
OpCom8 , OpCom16 , OpCom32 , OpCom64 ,
299
319
// math
300
320
OpFloor , OpCeil , OpTrunc , OpRoundToEven ,
321
+ // conversion
322
+ OpTrunc16to8 , OpTrunc32to8 , OpTrunc32to16 , OpTrunc64to8 ,
323
+ OpTrunc64to16 , OpTrunc64to32 , OpCvt32to32F , OpCvt32to64F ,
324
+ OpCvt64to32F , OpCvt64to64F , OpCvt32Fto32 , OpCvt32Fto64 ,
325
+ OpCvt64Fto32 , OpCvt64Fto64 , OpCvt32Fto64F , OpCvt64Fto32F ,
326
+ OpCvtBoolToUint8 ,
327
+ OpZeroExt8to16 , OpZeroExt8to32 , OpZeroExt8to64 , OpZeroExt16to32 ,
328
+ OpZeroExt16to64 , OpZeroExt32to64 , OpSignExt8to16 , OpSignExt8to32 ,
329
+ OpSignExt8to64 , OpSignExt16to32 , OpSignExt16to64 , OpSignExt32to64 ,
301
330
// not
302
331
OpNot :
303
332
var lt1 = t .getLatticeCell (val .Args [0 ])
0 commit comments