]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: avoid double-zeroing
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 23 Apr 2020 22:20:56 +0000 (15:20 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Apr 2020 23:58:38 +0000 (23:58 +0000)
This triggers in 131 functions in std+cmd.
In those functions, it often helps considerably
(2-10% text size reduction).

Noticed while working on #38554.

Change-Id: Id0dbb8e7cb21d469ec08ec3d5be9beb9e8291e9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/229707
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go

index 5d64e2635854be4a39aa3c0996e3a6795bd5e0b0..69b37a90ce8d7984974e35053362b582443c7092 100644 (file)
        && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
        => (Move {t1} [s] dst src midmem)
 
+// Don't zero the same bits twice.
+(Zero {t} [s] dst1 zero:(Zero {t} [s] dst2 _)) && isSamePtr(dst1, dst2) => zero
+(Zero {t} [s] dst1 vardef:(VarDef (Zero {t} [s] dst2 _))) && isSamePtr(dst1, dst2) => vardef
+
 // Elide self-moves. This only happens rarely (e.g test/fixedbugs/bug277.go).
 // However, this rule is needed to prevent the previous rule from looping forever in such cases.
 (Move dst src mem) && isSamePtr(dst, src) => mem
index fc2c78eb03014369bf8a8e294319a9d8e03ca780..d73a2e675fa1bfb59fc78cb3de416d76887793b5 100644 (file)
@@ -24204,6 +24204,46 @@ func rewriteValuegeneric_OpZero(v *Value) bool {
                v.AddArg2(dst1, v0)
                return true
        }
+       // match: (Zero {t} [s] dst1 zero:(Zero {t} [s] dst2 _))
+       // cond: isSamePtr(dst1, dst2)
+       // result: zero
+       for {
+               s := auxIntToInt64(v.AuxInt)
+               t := auxToType(v.Aux)
+               dst1 := v_0
+               zero := v_1
+               if zero.Op != OpZero || auxIntToInt64(zero.AuxInt) != s || auxToType(zero.Aux) != t {
+                       break
+               }
+               dst2 := zero.Args[0]
+               if !(isSamePtr(dst1, dst2)) {
+                       break
+               }
+               v.copyOf(zero)
+               return true
+       }
+       // match: (Zero {t} [s] dst1 vardef:(VarDef (Zero {t} [s] dst2 _)))
+       // cond: isSamePtr(dst1, dst2)
+       // result: vardef
+       for {
+               s := auxIntToInt64(v.AuxInt)
+               t := auxToType(v.Aux)
+               dst1 := v_0
+               vardef := v_1
+               if vardef.Op != OpVarDef {
+                       break
+               }
+               vardef_0 := vardef.Args[0]
+               if vardef_0.Op != OpZero || auxIntToInt64(vardef_0.AuxInt) != s || auxToType(vardef_0.Aux) != t {
+                       break
+               }
+               dst2 := vardef_0.Args[0]
+               if !(isSamePtr(dst1, dst2)) {
+                       break
+               }
+               v.copyOf(vardef)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpZeroExt16to32(v *Value) bool {