Skip to content

Commit

Permalink
cmd/compile: intrinsify RotateLeft32 on wasm
Browse files Browse the repository at this point in the history
wasm has 32-bit versions of all integer operations. This change
lowers RotateLeft32 to i32.rotl on wasm and intrinsifies the math/bits
call.  Benchmarking on amd64 under node.js this is ~25% faster.

node v10.15.3/amd64
name          old time/op  new time/op  delta
RotateLeft    8.37ns ± 1%  8.28ns ± 0%   -1.05%  (p=0.029 n=4+4)
RotateLeft8   11.9ns ± 1%  11.8ns ± 0%     ~     (p=0.167 n=5+5)
RotateLeft16  11.8ns ± 0%  11.8ns ± 0%     ~     (all equal)
RotateLeft32  11.9ns ± 1%   8.7ns ± 0%  -26.32%  (p=0.008 n=5+5)
RotateLeft64  8.31ns ± 1%  8.43ns ± 2%     ~     (p=0.063 n=5+5)

Updates golang#31265

Change-Id: I5b8e155978faeea536c4f6427ac9564d2f096a46
Reviewed-on: https://go-review.googlesource.com/c/go/+/182359
Run-TryBot: Brian Kessler <brian.m.kessler@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Richard Musiol <neelance@gmail.com>
  • Loading branch information
bmkessler authored and tomocy committed Sep 1, 2019
1 parent 7771445 commit 4bfcc4f
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/ssa.go
Expand Up @@ -3504,7 +3504,7 @@ func init() {
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
return s.newValue2(ssa.OpRotateLeft32, types.Types[TUINT32], args[0], args[1])
},
sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64)
sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
addF("math/bits", "RotateLeft64",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
return s.newValue2(ssa.OpRotateLeft64, types.Types[TUINT64], args[0], args[1])
Expand Down
5 changes: 2 additions & 3 deletions src/cmd/compile/internal/ssa/gen/Wasm.rules
Expand Up @@ -147,7 +147,8 @@
// Lowering rotates
(RotateLeft8 <t> x (I64Const [c])) -> (Or8 (Lsh8x64 <t> x (I64Const [c&7])) (Rsh8Ux64 <t> x (I64Const [-c&7])))
(RotateLeft16 <t> x (I64Const [c])) -> (Or16 (Lsh16x64 <t> x (I64Const [c&15])) (Rsh16Ux64 <t> x (I64Const [-c&15])))
(RotateLeft32 <t> x (I64Const [c])) -> (Or32 (Lsh32x64 <t> x (I64Const [c&31])) (Rsh32Ux64 <t> x (I64Const [-c&31])))
(RotateLeft32 x y) -> (I32Rotl x y)
(RotateLeft64 x y) -> (I64Rotl x y)

// Lowering comparisons
(Less64 x y) -> (I64LtS x y)
Expand Down Expand Up @@ -362,8 +363,6 @@

(BitLen64 x) -> (I64Sub (I64Const [64]) (I64Clz x))

(RotateLeft64 x y) -> (I64Rotl x y)

(PopCount64 x) -> (I64Popcnt x)
(PopCount32 x) -> (I64Popcnt (ZeroExt32to64 x))
(PopCount16 x) -> (I64Popcnt (ZeroExt16to64 x))
Expand Down
1 change: 1 addition & 0 deletions src/cmd/compile/internal/ssa/gen/WasmOps.go
Expand Up @@ -206,6 +206,7 @@ func init() {

{name: "I64Ctz", asm: "I64Ctz", argLength: 1, reg: gp11, typ: "Int64"}, // ctz(arg0)
{name: "I64Clz", asm: "I64Clz", argLength: 1, reg: gp11, typ: "Int64"}, // clz(arg0)
{name: "I32Rotl", asm: "I32Rotl", argLength: 2, reg: gp21, typ: "Int32"}, // rotl(arg0, arg1)
{name: "I64Rotl", asm: "I64Rotl", argLength: 2, reg: gp21, typ: "Int64"}, // rotl(arg0, arg1)
{name: "I64Popcnt", asm: "I64Popcnt", argLength: 1, reg: gp11, typ: "Int64"}, // popcnt(arg0)
}
Expand Down
15 changes: 15 additions & 0 deletions src/cmd/compile/internal/ssa/opGen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 6 additions & 25 deletions src/cmd/compile/internal/ssa/rewriteWasm.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/cmd/compile/internal/wasm/ssa.go
Expand Up @@ -299,6 +299,12 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) {
getValue64(s, v.Args[1])
s.Prog(v.Op.Asm())

case ssa.OpWasmI32Rotl:
getValue32(s, v.Args[0])
getValue32(s, v.Args[1])
s.Prog(wasm.AI32Rotl)
s.Prog(wasm.AI64ExtendI32U)

case ssa.OpWasmI64DivS:
getValue64(s, v.Args[0])
getValue64(s, v.Args[1])
Expand Down
4 changes: 4 additions & 0 deletions test/codegen/mathbits.go
Expand Up @@ -213,6 +213,7 @@ func RotateLeft32(n uint32) uint32 {
// ppc64:"ROTLW"
// ppc64le:"ROTLW"
// s390x:"RLL"
// wasm:"I32Rotl"
return bits.RotateLeft32(n, 9)
}

Expand All @@ -232,6 +233,7 @@ func RotateLeftVariable(n uint, m int) uint {
// ppc64:"ROTL"
// ppc64le:"ROTL"
// s390x:"RLLG"
// wasm:"I64Rotl"
return bits.RotateLeft(n, m)
}

Expand All @@ -241,6 +243,7 @@ func RotateLeftVariable64(n uint64, m int) uint64 {
// ppc64:"ROTL"
// ppc64le:"ROTL"
// s390x:"RLLG"
// wasm:"I64Rotl"
return bits.RotateLeft64(n, m)
}

Expand All @@ -251,6 +254,7 @@ func RotateLeftVariable32(n uint32, m int) uint32 {
// ppc64:"ROTLW"
// ppc64le:"ROTLW"
// s390x:"RLL"
// wasm:"I32Rotl"
return bits.RotateLeft32(n, m)
}

Expand Down

0 comments on commit 4bfcc4f

Please sign in to comment.