]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: force folding of MOVDaddr into storezero
authorKeith Randall <khr@golang.org>
Fri, 30 Sep 2016 16:03:38 +0000 (09:03 -0700)
committerKeith Randall <khr@golang.org>
Tue, 4 Oct 2016 16:10:27 +0000 (16:10 +0000)
Fold MOVDaddr ops into MOVXstorezero ops.
Also fold ADDconst into MOVDaddr so we're sure there isn't
(MOVDstorezero (ADDconst (MOVDaddr ..)))

Without this CL, we get:

v1 = MOVDaddr {s}
v2 = VARDEF {s}
v3 = MOVDstorezero v1 v2

The liveness pass thinks the MOVDaddr is a read of s, so s is
incorrectly thought to be live at the start of the function.

Fixes #17194

Change-Id: I2b4a2f13b12aa5b072941ee1c7b89f3793650cdc
Reviewed-on: https://go-review.googlesource.com/30086
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Michael Munday <munday@ca.ibm.com>
src/cmd/compile/internal/ssa/gen/PPC64.rules
src/cmd/compile/internal/ssa/rewritePPC64.go
test/fixedbugs/issue17194.go [new file with mode: 0644]

index 9bb8cafadc239b0c7eb816a44c23404a5274684b..3d885a9aaa7636919aafef0d6d4a50bcb2f63426 100644 (file)
 (ADD (MOVDconst [c]) x) && is32Bit(c) -> (ADDconst [c] x)
 (ADD x (MOVDconst [c])) && is32Bit(c) -> (ADDconst [c] x)
 (ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) -> (ADDconst [c+d] x)
+(ADDconst [c] (MOVDaddr [d] {sym} x)) -> (MOVDaddr [c+d] {sym} x)
 (ADDconst [0] x) -> x
 (ANDconst [-1] x) -> x
 (ANDconst [0] _) -> (MOVDconst [0])
 (MOVBstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) ->
     (MOVBstorezero [off1+off2] {sym} x mem)
 
+// Fold symbols into storezero
+(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+    (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+    (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+    (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
+    (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+
 // Lowering extension
 // Note: we always extend to 64 bits even though some ops don't need that many result bits.
 (SignExt8to16  x) -> (MOVBreg x)
index 28b22b9e0a7bcad9847b239dc249f07df7f1e77f..e71f7f5a5577b69fa7c1afc596e0507999701ee5 100644 (file)
@@ -4101,6 +4101,24 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (ADDconst [c] (MOVDaddr [d] {sym} x))
+       // cond:
+       // result: (MOVDaddr [c+d] {sym} x)
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               d := v_0.AuxInt
+               sym := v_0.Aux
+               x := v_0.Args[0]
+               v.reset(OpPPC64MOVDaddr)
+               v.AuxInt = c + d
+               v.Aux = sym
+               v.AddArg(x)
+               return true
+       }
        // match: (ADDconst [0] x)
        // cond:
        // result: x
@@ -5263,6 +5281,30 @@ func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVBstorezero)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValuePPC64_OpPPC64MOVDload(v *Value, config *Config) bool {
@@ -5422,6 +5464,30 @@ func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVDstorezero)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValuePPC64_OpPPC64MOVHZload(v *Value, config *Config) bool {
@@ -5737,6 +5803,30 @@ func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVHstorezero)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValuePPC64_OpPPC64MOVWZload(v *Value, config *Config) bool {
@@ -5948,6 +6038,30 @@ func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVWstorezero)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValuePPC64_OpPPC64NotEqual(v *Value, config *Config) bool {
diff --git a/test/fixedbugs/issue17194.go b/test/fixedbugs/issue17194.go
new file mode 100644 (file)
index 0000000..0594e1c
--- /dev/null
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package foo
+
+func f(x []interface{}) (err error) {
+       for _, d := range x {
+               _, ok := d.(*int)
+               if ok {
+                       return
+               }
+       }
+       return
+}