Skip to content

Commit 3ed13b4

Browse files
committed
faster sccp; cheaper def-use chains
1 parent 2227f13 commit 3ed13b4

File tree

1 file changed

+13
-13
lines changed
  • src/cmd/compile/internal/ssa

1 file changed

+13
-13
lines changed

src/cmd/compile/internal/ssa/sccp.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,16 @@ func isDivByZero(op Op, divisor *Value) bool {
150150
return false
151151
}
152152

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)
156157
func (t *worklist) buildDefUses() {
157158
for _, block := range t.f.Blocks {
158159
for _, val := range block.Values {
159160
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) {
162163
if _, exist := t.defUse[arg]; !exist {
163164
t.defUse[arg] = make([]*Value, 0)
164165
}
@@ -174,14 +175,6 @@ func (t *worklist) buildDefUses() {
174175
t.defBlock[ctl] = append(t.defBlock[ctl], block)
175176
}
176177
}
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-
}
185178
}
186179

187180
// 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) {
272265
}
273266

274267
func (t *worklist) visitValue(val *Value) {
268+
if !possibleConst(val) {
269+
// fast fail
270+
return
271+
}
272+
275273
var oldLt = t.getLatticeCell(val)
276274
defer func() {
277275
// re-visit all uses of value if its lattice is changed
@@ -462,6 +460,8 @@ func sccp(f *Func) {
462460
t.defUse = make(map[*Value][]*Value)
463461
t.defBlock = make(map[*Value][]*Block)
464462
t.latticeCells = make(map[*Value]lattice)
463+
464+
// build it early since we rely heavily on the def-use chain later
465465
t.buildDefUses()
466466

467467
var visitedBlock = f.newSparseSet(f.NumBlocks())

0 commit comments

Comments
 (0)