1
0
mirror of https://github.com/golang/go synced 2024-10-05 22:21:23 -06:00

[dev.ssa] cmd/compile: use v.Args[x].Op in CSE key

Experimentally, the Ops of v.Args do a good job
of differentiating values that will end up in
different partitions.

Most values have at most two args, so use them.

This reduces the wall time to run test/slice3.go
on my laptop from ~20s to ~12s.

Credit to Todd Neal for the idea.

Change-Id: I55d08f09eb678bbe8366924ca2fabcd32526bf41
Reviewed-on: https://go-review.googlesource.com/12565
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2015-07-22 21:04:25 -07:00
parent 5254be3a9c
commit 317226e61c

View File

@ -25,7 +25,7 @@ func cse(f *Func) {
// It starts with a coarse partition and iteratively refines it // It starts with a coarse partition and iteratively refines it
// until it reaches a fixed point. // until it reaches a fixed point.
// Make initial partition based on opcode/type-name/aux/auxint/nargs/phi-block // Make initial partition based on opcode, type-name, aux, auxint, nargs, phi-block, and the ops of v's first args
type key struct { type key struct {
op Op op Op
typ string typ string
@ -33,6 +33,8 @@ func cse(f *Func) {
auxint int64 auxint int64
nargs int nargs int
block ID // block id for phi vars, -1 otherwise block ID // block id for phi vars, -1 otherwise
arg0op Op // v.Args[0].Op if len(v.Args) > 0, OpInvalid otherwise
arg1op Op // v.Args[1].Op if len(v.Args) > 1, OpInvalid otherwise
} }
m := map[key]eqclass{} m := map[key]eqclass{}
for _, b := range f.Blocks { for _, b := range f.Blocks {
@ -41,7 +43,15 @@ func cse(f *Func) {
if v.Op == OpPhi { if v.Op == OpPhi {
bid = b.ID bid = b.ID
} }
k := key{v.Op, v.Type.String(), v.Aux, v.AuxInt, len(v.Args), bid} arg0op := OpInvalid
if len(v.Args) > 0 {
arg0op = v.Args[0].Op
}
arg1op := OpInvalid
if len(v.Args) > 1 {
arg1op = v.Args[1].Op
}
k := key{v.Op, v.Type.String(), v.Aux, v.AuxInt, len(v.Args), bid, arg0op, arg1op}
m[k] = append(m[k], v) m[k] = append(m[k], v)
} }
} }