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 <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2020-04-23 15:20:56 -07:00
parent 4a7e363288
commit 396833caef
2 changed files with 44 additions and 0 deletions

View File

@ -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

View 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 {