]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: speed up cse
authorTodd Neal <todd@tneal.org>
Sun, 7 Feb 2016 02:56:50 +0000 (20:56 -0600)
committerTodd Neal <todd@tneal.org>
Mon, 8 Feb 2016 02:43:19 +0000 (02:43 +0000)
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: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/cse.go

index 1cf0dfd4d97724793b093c0c6f3441b9d7482cb4..052d12dd33858f1c7e4ce5d5f5f5784b56fc9a98 100644 (file)
@@ -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
                        }
                }
        }