Commit bc079228 authored by Todd Neal's avatar Todd Neal

[dev.ssa] cmd/compile: speed up cse

Examine both Aux and AuxInt to form more precise initial partitions.
Restructure loop to avoid repeated type.Equal() call.  Speeds up
compilation of testdata/gen/arithConst_ssa by 25%.

Change-Id: I3cfb1d254adf0601ee69239e1885b0cf2a23575b
Reviewed-on: https://go-review.googlesource.com/19313
Run-TryBot: Todd Neal <todd@tneal.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent faf1bdb4
......@@ -99,17 +99,22 @@ func cse(f *Func) {
eqloop:
for j := 1; j < len(e); {
w := e[j]
equivalent := true
for i := 0; i < len(v.Args); i++ {
if valueEqClass[v.Args[i].ID] != valueEqClass[w.Args[i].ID] || !v.Type.Equal(w.Type) {
// w is not equivalent to v.
// move it to the end and shrink e.
e[j], e[len(e)-1] = e[len(e)-1], e[j]
e = e[:len(e)-1]
valueEqClass[w.ID] = ID(len(partition))
changed = true
continue eqloop
if valueEqClass[v.Args[i].ID] != valueEqClass[w.Args[i].ID] {
equivalent = false
break
}
}
if !equivalent || !v.Type.Equal(w.Type) {
// w is not equivalent to v.
// move it to the end and shrink e.
e[j], e[len(e)-1] = e[len(e)-1], e[j]
e = e[:len(e)-1]
valueEqClass[w.ID] = ID(len(partition))
changed = true
continue eqloop
}
// v and w are equivalent. Keep w in e.
j++
}
......@@ -212,8 +217,12 @@ func partitionValues(a []*Value) []eqclass {
len(v.Args) != len(w.Args) ||
v.Op == OpPhi && v.Block != w.Block ||
v.Aux != w.Aux ||
len(v.Args) >= 1 && v.Args[0].Op != w.Args[0].Op ||
len(v.Args) >= 2 && v.Args[1].Op != w.Args[1].Op ||
len(v.Args) >= 1 && (v.Args[0].Op != w.Args[0].Op ||
v.Args[0].Aux != w.Args[0].Aux ||
v.Args[0].AuxInt != w.Args[0].AuxInt) ||
len(v.Args) >= 2 && (v.Args[1].Op != w.Args[1].Op ||
v.Args[1].Aux != w.Args[1].Aux ||
v.Args[1].AuxInt != w.Args[1].AuxInt) ||
typNames[v.Type] != typNames[w.Type] {
break
}
......@@ -258,16 +267,29 @@ func (sv sortvalues) Less(i, j int) bool {
return v.Block.ID < w.Block.ID
}
if len(v.Args) >= 1 {
x := v.Args[0].Op
y := w.Args[0].Op
if x != y {
return x < y
vOp := v.Args[0].Op
wOp := w.Args[0].Op
if vOp != wOp {
return vOp < wOp
}
vAuxInt := v.Args[0].AuxInt
wAuxInt := w.Args[0].AuxInt
if vAuxInt != wAuxInt {
return vAuxInt < wAuxInt
}
if len(v.Args) >= 2 {
x = v.Args[1].Op
y = w.Args[1].Op
if x != y {
return x < y
vOp = v.Args[1].Op
wOp = w.Args[1].Op
if vOp != wOp {
return vOp < wOp
}
vAuxInt = v.Args[1].AuxInt
wAuxInt = w.Args[1].AuxInt
if vAuxInt != wAuxInt {
return vAuxInt < wAuxInt
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment