From: Todd Neal Date: Sun, 7 Feb 2016 02:56:50 +0000 (-0600) Subject: [dev.ssa] cmd/compile: speed up cse X-Git-Tag: go1.7beta1~1623^2^2~54 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=bc0792284306ade896db24002a52d00901ce5f69;p=gostls13.git [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 Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go index 1cf0dfd4d9..052d12dd33 100644 --- a/src/cmd/compile/internal/ssa/cse.go +++ b/src/cmd/compile/internal/ssa/cse.go @@ -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 } } }