mirror of
https://github.com/golang/go.git
synced 2026-06-28 03:40:37 +00:00
cmd/compile: canonicalize x+x into x<<1 in generic.rules
The canonical way to multiply by 2 is x<<1, this is what other generic rules expect. It is slower than x+x but arches rule can turn x<<1 back into x+x, as this avoids adding many special cases for rules optimizing shifts to also search x+x as x<<1. Change-Id: I249c60cd2643db2e2a3503f3934211f80fb2912a Reviewed-on: https://go-review.googlesource.com/c/go/+/774060 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Jorropo <jorropo.pgm@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
f133609b75
commit
74c35fca7a
3 changed files with 80 additions and 21 deletions
|
|
@ -407,6 +407,11 @@
|
|||
(Sub(64|32|16|8) <t> (Mul(64|32|16|8) x y) (Mul(64|32|16|8) x z))
|
||||
=> (Mul(64|32|16|8) x (Sub(64|32|16|8) <t> y z))
|
||||
|
||||
// Canonicalize x+x to x << 1.
|
||||
// This is often slower since most CPUs have more adders than shifters, but it can enable other optimizations.
|
||||
// Arches who care about this like AMD64 convert x << 1 back to x+x in their arch-specific rules which is useful anyhow.
|
||||
(Add(64|32|16|8) x x) => (Lsh(64|32|16|8)x64 x (Const64 <types.Types[types.TUINT64]> [1]))
|
||||
|
||||
// rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce
|
||||
// the number of the other rewrite rules for const shifts
|
||||
(Lsh64x32 <t> x (Const32 [c])) => (Lsh64x64 x (Const64 <t> [int64(uint32(c))]))
|
||||
|
|
|
|||
|
|
@ -553,6 +553,19 @@ func rewriteValuegeneric_OpAdd16(v *Value) bool {
|
|||
}
|
||||
break
|
||||
}
|
||||
// match: (Add16 x x)
|
||||
// result: (Lsh16x64 x (Const64 <types.Types[types.TUINT64]> [1]))
|
||||
for {
|
||||
x := v_0
|
||||
if x != v_1 {
|
||||
break
|
||||
}
|
||||
v.reset(OpLsh16x64)
|
||||
v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64])
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
// match: (Add16 (Const16 [0]) x)
|
||||
// result: x
|
||||
for {
|
||||
|
|
@ -1166,6 +1179,19 @@ func rewriteValuegeneric_OpAdd32(v *Value) bool {
|
|||
}
|
||||
break
|
||||
}
|
||||
// match: (Add32 x x)
|
||||
// result: (Lsh32x64 x (Const64 <types.Types[types.TUINT64]> [1]))
|
||||
for {
|
||||
x := v_0
|
||||
if x != v_1 {
|
||||
break
|
||||
}
|
||||
v.reset(OpLsh32x64)
|
||||
v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64])
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
// match: (Add32 (Const32 [0]) x)
|
||||
// result: x
|
||||
for {
|
||||
|
|
@ -1806,6 +1832,19 @@ func rewriteValuegeneric_OpAdd64(v *Value) bool {
|
|||
}
|
||||
break
|
||||
}
|
||||
// match: (Add64 x x)
|
||||
// result: (Lsh64x64 x (Const64 <types.Types[types.TUINT64]> [1]))
|
||||
for {
|
||||
x := v_0
|
||||
if x != v_1 {
|
||||
break
|
||||
}
|
||||
v.reset(OpLsh64x64)
|
||||
v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64])
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
// match: (Add64 (Const64 [0]) x)
|
||||
// result: x
|
||||
for {
|
||||
|
|
@ -2484,6 +2523,19 @@ func rewriteValuegeneric_OpAdd8(v *Value) bool {
|
|||
}
|
||||
break
|
||||
}
|
||||
// match: (Add8 x x)
|
||||
// result: (Lsh8x64 x (Const64 <types.Types[types.TUINT64]> [1]))
|
||||
for {
|
||||
x := v_0
|
||||
if x != v_1 {
|
||||
break
|
||||
}
|
||||
v.reset(OpLsh8x64)
|
||||
v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64])
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
// match: (Add8 (Const8 [0]) x)
|
||||
// result: x
|
||||
for {
|
||||
|
|
|
|||
|
|
@ -120,47 +120,49 @@ func rshConst64x32(v int64) int64 {
|
|||
}
|
||||
|
||||
func lshConst32x1Add(x int32) int32 {
|
||||
// amd64:"SHLL [$]2"
|
||||
// loong64:"SLL [$]2"
|
||||
// riscv64:"SLLI [$]2"
|
||||
// ppc64x:"SLW [$]2" -"ADD"
|
||||
// amd64:-"ADD" "SHLL [$]2"
|
||||
// loong64:-"ADD" "SLL [$]2"
|
||||
// riscv64:-"ADD" "SLLI [$]2"
|
||||
// ppc64x:-"ADD" "SLW [$]2"
|
||||
return (x + x) << 1
|
||||
}
|
||||
|
||||
func lshConst64x1Add(x int64) int64 {
|
||||
// amd64:"SHLQ [$]2"
|
||||
// loong64:"SLLV [$]2"
|
||||
// riscv64:"SLLI [$]2"
|
||||
// ppc64x:"SLD [$]2" -"ADD"
|
||||
// amd64:-"ADD" "SHLQ [$]2"
|
||||
// loong64:-"ADD" "SLLV [$]2"
|
||||
// riscv64:-"ADD" "SLLI [$]2"
|
||||
// ppc64x:-"ADD" "SLD [$]2"
|
||||
return (x + x) << 1
|
||||
}
|
||||
|
||||
func lshConst32x2Add(x int32) int32 {
|
||||
// amd64:"SHLL [$]3"
|
||||
// loong64:"SLL [$]3"
|
||||
// riscv64:"SLLI [$]3"
|
||||
// ppc64x:"SLW [$]3" -"ADD"
|
||||
// amd64:-"ADD" "SHLL [$]3"
|
||||
// loong64:-"ADD" "SLL [$]3"
|
||||
// riscv64:-"ADD" "SLLI [$]3"
|
||||
// ppc64x:-"ADD" "SLW [$]3"
|
||||
return (x + x) << 2
|
||||
}
|
||||
|
||||
func lshConst64x2Add(x int64) int64 {
|
||||
// amd64:"SHLQ [$]3"
|
||||
// loong64:"SLLV [$]3"
|
||||
// riscv64:"SLLI [$]3"
|
||||
// ppc64x:"SLD [$]3" -"ADD"
|
||||
// amd64:-"ADD" "SHLQ [$]3"
|
||||
// loong64:-"ADD" "SLLV [$]3"
|
||||
// riscv64:-"ADD" "SLLI [$]3"
|
||||
// ppc64x:-"ADD" "SLD [$]3"
|
||||
return (x + x) << 2
|
||||
}
|
||||
|
||||
func lshConst32x31Add(x int32) int32 {
|
||||
// loong64:-"SLL " "MOVV R0"
|
||||
// riscv64:-"SLLI" "MOV [$]0"
|
||||
// ppc64x:"ADD" "SLW [$]31" -"SLW [$]32"
|
||||
// amd64:-"ADD" -"SHL" "XORL AX, AX"
|
||||
// loong64:-"ADD" -"SLL " "MOVV R0"
|
||||
// riscv64:-"ADD" -"SLLI" "MOV [$]0"
|
||||
// ppc64x:-"ADD" -"SLW" "MOVD [$]0"
|
||||
return (x + x) << 31
|
||||
}
|
||||
|
||||
func lshConst64x63Add(x int64) int64 {
|
||||
// loong64:-"SLLV" "MOVV R0"
|
||||
// riscv64:-"SLLI" "MOV [$]0"
|
||||
// amd64:-"ADD" -"SHL" "XORL AX, AX"
|
||||
// loong64:-"ADD" -"SLLV" "MOVV R0"
|
||||
// riscv64:-"ADD" -"SLLI" "MOV [$]0"
|
||||
return (x + x) << 63
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue