1
0
mirror of https://github.com/golang/go synced 2024-11-18 18:54:42 -07:00

cmd/compile: optimize const rotates for wasm architecture

This removes the unnecessary code to check whether the shift
is within limits or not when the shift amount is a constant.

The rules hit 23034 times when building std cmd.

grep -E "Wasm.rules:(106|107|121|122|139|140)" rulelog | wc -l
23034

Reduces the size of pkg/js_wasm by 132 bytes.

Change-Id: I64a2b8faca08c3b5039d6a027d4676130d2db18d
Reviewed-on: https://go-review.googlesource.com/c/go/+/194239
Run-TryBot: Agniva De Sarker <agniva.quicksilver@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Richard Musiol <neelance@gmail.com>
This commit is contained in:
Agniva De Sarker 2019-09-08 22:55:01 +05:30 committed by Agniva De Sarker
parent b6ec56bc26
commit b38be35e4c
2 changed files with 124 additions and 0 deletions

View File

@ -103,6 +103,8 @@
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
(Lsh64x64 x y) && shiftIsBounded(v) -> (I64Shl x y)
(Lsh64x64 x (I64Const [c])) && uint64(c) < 64 -> (I64Shl x (I64Const [c]))
(Lsh64x64 x (I64Const [c])) && uint64(c) >= 64 -> (I64Const [0])
(Lsh64x64 x y) -> (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
(Lsh64x(32|16|8) x y) -> (Lsh64x64 x (ZeroExt(32|16|8)to64 y))
@ -116,6 +118,8 @@
(Lsh8x(32|16|8) x y) -> (Lsh64x64 x (ZeroExt(32|16|8)to64 y))
(Rsh64Ux64 x y) && shiftIsBounded(v) -> (I64ShrU x y)
(Rsh64Ux64 x (I64Const [c])) && uint64(c) < 64 -> (I64ShrU x (I64Const [c]))
(Rsh64Ux64 x (I64Const [c])) && uint64(c) >= 64 -> (I64Const [0])
(Rsh64Ux64 x y) -> (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
(Rsh64Ux(32|16|8) x y) -> (Rsh64Ux64 x (ZeroExt(32|16|8)to64 y))
@ -132,6 +136,8 @@
// We implement this by setting the shift value to (width - 1) if the shift value is >= width.
(Rsh64x64 x y) && shiftIsBounded(v) -> (I64ShrS x y)
(Rsh64x64 x (I64Const [c])) && uint64(c) < 64 -> (I64ShrS x (I64Const [c]))
(Rsh64x64 x (I64Const [c])) && uint64(c) >= 64 -> (I64ShrS x (I64Const [63]))
(Rsh64x64 x y) -> (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))
(Rsh64x(32|16|8) x y) -> (Rsh64x64 x (ZeroExt(32|16|8)to64 y))

View File

@ -2742,6 +2742,44 @@ func rewriteValueWasm_OpLsh64x64_0(v *Value) bool {
v.AddArg(y)
return true
}
// match: (Lsh64x64 x (I64Const [c]))
// cond: uint64(c) < 64
// result: (I64Shl x (I64Const [c]))
for {
_ = v.Args[1]
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
c := v_1.AuxInt
if !(uint64(c) < 64) {
break
}
v.reset(OpWasmI64Shl)
v.AddArg(x)
v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
v0.AuxInt = c
v.AddArg(v0)
return true
}
// match: (Lsh64x64 x (I64Const [c]))
// cond: uint64(c) >= 64
// result: (I64Const [0])
for {
_ = v.Args[1]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
c := v_1.AuxInt
if !(uint64(c) >= 64) {
break
}
v.reset(OpWasmI64Const)
v.AuxInt = 0
return true
}
// match: (Lsh64x64 x y)
// cond:
// result: (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
@ -4264,6 +4302,44 @@ func rewriteValueWasm_OpRsh64Ux64_0(v *Value) bool {
v.AddArg(y)
return true
}
// match: (Rsh64Ux64 x (I64Const [c]))
// cond: uint64(c) < 64
// result: (I64ShrU x (I64Const [c]))
for {
_ = v.Args[1]
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
c := v_1.AuxInt
if !(uint64(c) < 64) {
break
}
v.reset(OpWasmI64ShrU)
v.AddArg(x)
v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
v0.AuxInt = c
v.AddArg(v0)
return true
}
// match: (Rsh64Ux64 x (I64Const [c]))
// cond: uint64(c) >= 64
// result: (I64Const [0])
for {
_ = v.Args[1]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
c := v_1.AuxInt
if !(uint64(c) >= 64) {
break
}
v.reset(OpWasmI64Const)
v.AuxInt = 0
return true
}
// match: (Rsh64Ux64 x y)
// cond:
// result: (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
@ -4355,6 +4431,48 @@ func rewriteValueWasm_OpRsh64x64_0(v *Value) bool {
v.AddArg(y)
return true
}
// match: (Rsh64x64 x (I64Const [c]))
// cond: uint64(c) < 64
// result: (I64ShrS x (I64Const [c]))
for {
_ = v.Args[1]
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
c := v_1.AuxInt
if !(uint64(c) < 64) {
break
}
v.reset(OpWasmI64ShrS)
v.AddArg(x)
v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
v0.AuxInt = c
v.AddArg(v0)
return true
}
// match: (Rsh64x64 x (I64Const [c]))
// cond: uint64(c) >= 64
// result: (I64ShrS x (I64Const [63]))
for {
_ = v.Args[1]
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
c := v_1.AuxInt
if !(uint64(c) >= 64) {
break
}
v.reset(OpWasmI64ShrS)
v.AddArg(x)
v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
v0.AuxInt = 63
v.AddArg(v0)
return true
}
// match: (Rsh64x64 x y)
// cond:
// result: (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))