@@ -150,15 +150,16 @@ func isDivByZero(op Op, divisor *Value) bool {
150
150
return false
151
151
}
152
152
153
- // buildDefUses builds def-use chain for some values early, because once lattice of value
154
- // is changed, all uses would be added into re-visit uses worklist, we rely heavily on
155
- // the def-use chain in subsequent propagation.
153
+ // buildDefUses builds def-use chain for some values early, because once the lattice of
154
+ // a value is changed, we need to update lattices of use. But we don't need all uses of
155
+ // it, only uses that can become constants would be added into re-visit worklist since
156
+ // no matter how many times they are revisited, their lattice remains unchanged(Bottom)
156
157
func (t * worklist ) buildDefUses () {
157
158
for _ , block := range t .f .Blocks {
158
159
for _ , val := range block .Values {
159
160
for _ , arg := range val .Args {
160
- if possibleConst ( arg ) {
161
- // for every value, find their uses
161
+ // find its uses, only uses that can become constant takes into account
162
+ if possibleConst ( arg ) && possibleConst ( val ) {
162
163
if _ , exist := t .defUse [arg ]; ! exist {
163
164
t .defUse [arg ] = make ([]* Value , 0 )
164
165
}
@@ -174,14 +175,6 @@ func (t *worklist) buildDefUses() {
174
175
t .defBlock [ctl ] = append (t .defBlock [ctl ], block )
175
176
}
176
177
}
177
- // verify def-use chains
178
- for key , value := range t .defUse {
179
- if int (key .Uses ) != (len (value ) + len (t .defBlock [key ])) {
180
- fmt .Printf ("%v\n " , t .f .String ())
181
- t .f .Fatalf ("def-use chain of %v is problematic: expect %v but got%v\n " ,
182
- key .LongString (), key .Uses , value )
183
- }
184
- }
185
178
}
186
179
187
180
// addUses finds all uses of value and appends them into work list for further process
@@ -272,6 +265,11 @@ func computeConstValue(f *Func, val *Value, args ...*Value) (*Value, bool) {
272
265
}
273
266
274
267
func (t * worklist ) visitValue (val * Value ) {
268
+ if ! possibleConst (val ) {
269
+ // fast fail
270
+ return
271
+ }
272
+
275
273
var oldLt = t .getLatticeCell (val )
276
274
defer func () {
277
275
// re-visit all uses of value if its lattice is changed
@@ -462,6 +460,8 @@ func sccp(f *Func) {
462
460
t .defUse = make (map [* Value ][]* Value )
463
461
t .defBlock = make (map [* Value ][]* Block )
464
462
t .latticeCells = make (map [* Value ]lattice )
463
+
464
+ // build it early since we rely heavily on the def-use chain later
465
465
t .buildDefUses ()
466
466
467
467
var visitedBlock = f .newSparseSet (f .NumBlocks ())
0 commit comments