From: Josh Bleecher Snyder Date: Thu, 23 Apr 2020 22:20:56 +0000 (-0700) Subject: cmd/compile: avoid double-zeroing X-Git-Tag: go1.15beta1~381 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=396833caef83b20f38199f9d74cb3e768b2fd478;p=gostls13.git cmd/compile: avoid double-zeroing 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index 5d64e26358..69b37a90ce 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -2418,6 +2418,10 @@ && (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 diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index fc2c78eb03..d73a2e675f 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -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 {