diff options
author | Richard Musiol <mail@richard-musiol.de> | 2019-03-05 01:56:17 +0100 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2019-03-14 19:46:19 +0000 |
commit | 5ee1b849592787ed050ef3fbd9b2c58aabd20ff3 (patch) | |
tree | 50df3ba82b50ebe09d1fe252b490806be16a1648 /src/cmd/compile/internal/ssa/rewriteWasm.go | |
parent | aa193c0b9623acd7397c0799ffc9efe5845216b2 (diff) | |
download | go-5ee1b849592787ed050ef3fbd9b2c58aabd20ff3.tar.gz go-5ee1b849592787ed050ef3fbd9b2c58aabd20ff3.zip |
math, math/bits: add intrinsics for wasm
This commit adds compiler intrinsics for the packages math and
math/bits on the wasm architecture for better performance.
benchmark old ns/op new ns/op delta
BenchmarkCeil 8.31 3.21 -61.37%
BenchmarkCopysign 5.24 3.88 -25.95%
BenchmarkAbs 5.42 3.34 -38.38%
BenchmarkFloor 8.29 3.18 -61.64%
BenchmarkRoundToEven 9.76 3.26 -66.60%
BenchmarkSqrtLatency 8.13 4.88 -39.98%
BenchmarkSqrtPrime 5246 3535 -32.62%
BenchmarkTrunc 8.29 3.15 -62.00%
BenchmarkLeadingZeros 13.0 4.23 -67.46%
BenchmarkLeadingZeros8 4.65 4.42 -4.95%
BenchmarkLeadingZeros16 7.60 4.38 -42.37%
BenchmarkLeadingZeros32 10.7 4.48 -58.13%
BenchmarkLeadingZeros64 12.9 4.31 -66.59%
BenchmarkTrailingZeros 6.52 4.04 -38.04%
BenchmarkTrailingZeros8 4.57 4.14 -9.41%
BenchmarkTrailingZeros16 6.69 4.16 -37.82%
BenchmarkTrailingZeros32 6.97 4.23 -39.31%
BenchmarkTrailingZeros64 6.59 4.00 -39.30%
BenchmarkOnesCount 7.93 3.30 -58.39%
BenchmarkOnesCount8 3.56 3.19 -10.39%
BenchmarkOnesCount16 4.85 3.19 -34.23%
BenchmarkOnesCount32 7.27 3.19 -56.12%
BenchmarkOnesCount64 8.08 3.28 -59.41%
BenchmarkRotateLeft 4.88 3.80 -22.13%
BenchmarkRotateLeft64 5.03 3.63 -27.83%
Change-Id: Ic1e0c2984878be8defb6eb7eb6ee63765c793222
Reviewed-on: https://go-review.googlesource.com/c/go/+/165177
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/rewriteWasm.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/rewriteWasm.go | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go index 8418e51f6a..c5fc8c815f 100644 --- a/src/cmd/compile/internal/ssa/rewriteWasm.go +++ b/src/cmd/compile/internal/ssa/rewriteWasm.go @@ -17,6 +17,8 @@ var _ = types.TypeMem // in case not otherwise used func rewriteValueWasm(v *Value) bool { switch v.Op { + case OpAbs: + return rewriteValueWasm_OpAbs_0(v) case OpAdd16: return rewriteValueWasm_OpAdd16_0(v) case OpAdd32: @@ -43,6 +45,10 @@ func rewriteValueWasm(v *Value) bool { return rewriteValueWasm_OpAnd8_0(v) case OpAndB: return rewriteValueWasm_OpAndB_0(v) + case OpBitLen64: + return rewriteValueWasm_OpBitLen64_0(v) + case OpCeil: + return rewriteValueWasm_OpCeil_0(v) case OpClosureCall: return rewriteValueWasm_OpClosureCall_0(v) case OpCom16: @@ -71,6 +77,24 @@ func rewriteValueWasm(v *Value) bool { return rewriteValueWasm_OpConstNil_0(v) case OpConvert: return rewriteValueWasm_OpConvert_0(v) + case OpCopysign: + return rewriteValueWasm_OpCopysign_0(v) + case OpCtz16: + return rewriteValueWasm_OpCtz16_0(v) + case OpCtz16NonZero: + return rewriteValueWasm_OpCtz16NonZero_0(v) + case OpCtz32: + return rewriteValueWasm_OpCtz32_0(v) + case OpCtz32NonZero: + return rewriteValueWasm_OpCtz32NonZero_0(v) + case OpCtz64: + return rewriteValueWasm_OpCtz64_0(v) + case OpCtz64NonZero: + return rewriteValueWasm_OpCtz64NonZero_0(v) + case OpCtz8: + return rewriteValueWasm_OpCtz8_0(v) + case OpCtz8NonZero: + return rewriteValueWasm_OpCtz8NonZero_0(v) case OpCvt32Fto32: return rewriteValueWasm_OpCvt32Fto32_0(v) case OpCvt32Fto32U: @@ -143,6 +167,8 @@ func rewriteValueWasm(v *Value) bool { return rewriteValueWasm_OpEqB_0(v) case OpEqPtr: return rewriteValueWasm_OpEqPtr_0(v) + case OpFloor: + return rewriteValueWasm_OpFloor_0(v) case OpGeq16: return rewriteValueWasm_OpGeq16_0(v) case OpGeq16U: @@ -347,10 +373,22 @@ func rewriteValueWasm(v *Value) bool { return rewriteValueWasm_OpOr8_0(v) case OpOrB: return rewriteValueWasm_OpOrB_0(v) + case OpPopCount16: + return rewriteValueWasm_OpPopCount16_0(v) + case OpPopCount32: + return rewriteValueWasm_OpPopCount32_0(v) + case OpPopCount64: + return rewriteValueWasm_OpPopCount64_0(v) + case OpPopCount8: + return rewriteValueWasm_OpPopCount8_0(v) + case OpRotateLeft64: + return rewriteValueWasm_OpRotateLeft64_0(v) case OpRound32F: return rewriteValueWasm_OpRound32F_0(v) case OpRound64F: return rewriteValueWasm_OpRound64F_0(v) + case OpRoundToEven: + return rewriteValueWasm_OpRoundToEven_0(v) case OpRsh16Ux16: return rewriteValueWasm_OpRsh16Ux16_0(v) case OpRsh16Ux32: @@ -429,6 +467,8 @@ func rewriteValueWasm(v *Value) bool { return rewriteValueWasm_OpSignExt8to64_0(v) case OpSlicemask: return rewriteValueWasm_OpSlicemask_0(v) + case OpSqrt: + return rewriteValueWasm_OpSqrt_0(v) case OpStaticCall: return rewriteValueWasm_OpStaticCall_0(v) case OpStore: @@ -447,6 +487,8 @@ func rewriteValueWasm(v *Value) bool { return rewriteValueWasm_OpSub8_0(v) case OpSubPtr: return rewriteValueWasm_OpSubPtr_0(v) + case OpTrunc: + return rewriteValueWasm_OpTrunc_0(v) case OpTrunc16to8: return rewriteValueWasm_OpTrunc16to8_0(v) case OpTrunc32to16: @@ -536,6 +578,17 @@ func rewriteValueWasm(v *Value) bool { } return false } +func rewriteValueWasm_OpAbs_0(v *Value) bool { + // match: (Abs x) + // cond: + // result: (F64Abs x) + for { + x := v.Args[0] + v.reset(OpWasmF64Abs) + v.AddArg(x) + return true + } +} func rewriteValueWasm_OpAdd16_0(v *Value) bool { // match: (Add16 x y) // cond: @@ -705,6 +758,35 @@ func rewriteValueWasm_OpAndB_0(v *Value) bool { return true } } +func rewriteValueWasm_OpBitLen64_0(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (BitLen64 x) + // cond: + // result: (I64Sub (I64Const [64]) (I64Clz x)) + for { + x := v.Args[0] + v.reset(OpWasmI64Sub) + v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) + v0.AuxInt = 64 + v.AddArg(v0) + v1 := b.NewValue0(v.Pos, OpWasmI64Clz, typ.Int64) + v1.AddArg(x) + v.AddArg(v1) + return true + } +} +func rewriteValueWasm_OpCeil_0(v *Value) bool { + // match: (Ceil x) + // cond: + // result: (F64Ceil x) + for { + x := v.Args[0] + v.reset(OpWasmF64Ceil) + v.AddArg(x) + return true + } +} func rewriteValueWasm_OpClosureCall_0(v *Value) bool { // match: (ClosureCall [argwid] entry closure mem) // cond: @@ -888,6 +970,128 @@ func rewriteValueWasm_OpConvert_0(v *Value) bool { return true } } +func rewriteValueWasm_OpCopysign_0(v *Value) bool { + // match: (Copysign x y) + // cond: + // result: (F64Copysign x y) + for { + y := v.Args[1] + x := v.Args[0] + v.reset(OpWasmF64Copysign) + v.AddArg(x) + v.AddArg(y) + return true + } +} +func rewriteValueWasm_OpCtz16_0(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Ctz16 x) + // cond: + // result: (I64Ctz (I64Or x (I64Const [0x10000]))) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v0 := b.NewValue0(v.Pos, OpWasmI64Or, typ.Int64) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) + v1.AuxInt = 0x10000 + v0.AddArg(v1) + v.AddArg(v0) + return true + } +} +func rewriteValueWasm_OpCtz16NonZero_0(v *Value) bool { + // match: (Ctz16NonZero x) + // cond: + // result: (I64Ctz x) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v.AddArg(x) + return true + } +} +func rewriteValueWasm_OpCtz32_0(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Ctz32 x) + // cond: + // result: (I64Ctz (I64Or x (I64Const [0x100000000]))) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v0 := b.NewValue0(v.Pos, OpWasmI64Or, typ.Int64) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) + v1.AuxInt = 0x100000000 + v0.AddArg(v1) + v.AddArg(v0) + return true + } +} +func rewriteValueWasm_OpCtz32NonZero_0(v *Value) bool { + // match: (Ctz32NonZero x) + // cond: + // result: (I64Ctz x) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v.AddArg(x) + return true + } +} +func rewriteValueWasm_OpCtz64_0(v *Value) bool { + // match: (Ctz64 x) + // cond: + // result: (I64Ctz x) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v.AddArg(x) + return true + } +} +func rewriteValueWasm_OpCtz64NonZero_0(v *Value) bool { + // match: (Ctz64NonZero x) + // cond: + // result: (I64Ctz x) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v.AddArg(x) + return true + } +} +func rewriteValueWasm_OpCtz8_0(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Ctz8 x) + // cond: + // result: (I64Ctz (I64Or x (I64Const [0x100]))) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v0 := b.NewValue0(v.Pos, OpWasmI64Or, typ.Int64) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) + v1.AuxInt = 0x100 + v0.AddArg(v1) + v.AddArg(v0) + return true + } +} +func rewriteValueWasm_OpCtz8NonZero_0(v *Value) bool { + // match: (Ctz8NonZero x) + // cond: + // result: (I64Ctz x) + for { + x := v.Args[0] + v.reset(OpWasmI64Ctz) + v.AddArg(x) + return true + } +} func rewriteValueWasm_OpCvt32Fto32_0(v *Value) bool { // match: (Cvt32Fto32 x) // cond: @@ -1409,6 +1613,17 @@ func rewriteValueWasm_OpEqPtr_0(v *Value) bool { return true } } +func rewriteValueWasm_OpFloor_0(v *Value) bool { + // match: (Floor x) + // cond: + // result: (F64Floor x) + for { + x := v.Args[0] + v.reset(OpWasmF64Floor) + v.AddArg(x) + return true + } +} func rewriteValueWasm_OpGeq16_0(v *Value) bool { b := v.Block typ := &b.Func.Config.Types @@ -3492,6 +3707,75 @@ func rewriteValueWasm_OpOrB_0(v *Value) bool { return true } } +func rewriteValueWasm_OpPopCount16_0(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (PopCount16 x) + // cond: + // result: (I64Popcnt (ZeroExt16to64 x)) + for { + x := v.Args[0] + v.reset(OpWasmI64Popcnt) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v0.AddArg(x) + v.AddArg(v0) + return true + } +} +func rewriteValueWasm_OpPopCount32_0(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (PopCount32 x) + // cond: + // result: (I64Popcnt (ZeroExt32to64 x)) + for { + x := v.Args[0] + v.reset(OpWasmI64Popcnt) + v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v0.AddArg(x) + v.AddArg(v0) + return true + } +} +func rewriteValueWasm_OpPopCount64_0(v *Value) bool { + // match: (PopCount64 x) + // cond: + // result: (I64Popcnt x) + for { + x := v.Args[0] + v.reset(OpWasmI64Popcnt) + v.AddArg(x) + return true + } +} +func rewriteValueWasm_OpPopCount8_0(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (PopCount8 x) + // cond: + // result: (I64Popcnt (ZeroExt8to64 x)) + for { + x := v.Args[0] + v.reset(OpWasmI64Popcnt) + v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v0.AddArg(x) + v.AddArg(v0) + return true + } +} +func rewriteValueWasm_OpRotateLeft64_0(v *Value) bool { + // match: (RotateLeft64 x y) + // cond: + // result: (I64Rotl x y) + for { + y := v.Args[1] + x := v.Args[0] + v.reset(OpWasmI64Rotl) + v.AddArg(x) + v.AddArg(y) + return true + } +} func rewriteValueWasm_OpRound32F_0(v *Value) bool { // match: (Round32F x) // cond: @@ -3515,6 +3799,17 @@ func rewriteValueWasm_OpRound64F_0(v *Value) bool { return true } } +func rewriteValueWasm_OpRoundToEven_0(v *Value) bool { + // match: (RoundToEven x) + // cond: + // result: (F64Nearest x) + for { + x := v.Args[0] + v.reset(OpWasmF64Nearest) + v.AddArg(x) + return true + } +} func rewriteValueWasm_OpRsh16Ux16_0(v *Value) bool { b := v.Block typ := &b.Func.Config.Types @@ -4344,6 +4639,17 @@ func rewriteValueWasm_OpSlicemask_0(v *Value) bool { return true } } +func rewriteValueWasm_OpSqrt_0(v *Value) bool { + // match: (Sqrt x) + // cond: + // result: (F64Sqrt x) + for { + x := v.Args[0] + v.reset(OpWasmF64Sqrt) + v.AddArg(x) + return true + } +} func rewriteValueWasm_OpStaticCall_0(v *Value) bool { // match: (StaticCall [argwid] {target} mem) // cond: @@ -4555,6 +4861,17 @@ func rewriteValueWasm_OpSubPtr_0(v *Value) bool { return true } } +func rewriteValueWasm_OpTrunc_0(v *Value) bool { + // match: (Trunc x) + // cond: + // result: (F64Trunc x) + for { + x := v.Args[0] + v.reset(OpWasmF64Trunc) + v.AddArg(x) + return true + } +} func rewriteValueWasm_OpTrunc16to8_0(v *Value) bool { // match: (Trunc16to8 x) // cond: |