aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/rewriteWasm.go
diff options
context:
space:
mode:
authorRichard Musiol <mail@richard-musiol.de>2019-03-05 01:56:17 +0100
committerBrad Fitzpatrick <bradfitz@golang.org>2019-03-14 19:46:19 +0000
commit5ee1b849592787ed050ef3fbd9b2c58aabd20ff3 (patch)
tree50df3ba82b50ebe09d1fe252b490806be16a1648 /src/cmd/compile/internal/ssa/rewriteWasm.go
parentaa193c0b9623acd7397c0799ffc9efe5845216b2 (diff)
downloadgo-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.go317
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: