]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize const rotates for wasm architecture
authorAgniva De Sarker <agnivade@yahoo.co.in>
Sun, 8 Sep 2019 17:25:01 +0000 (22:55 +0530)
committerAgniva De Sarker <agniva.quicksilver@gmail.com>
Tue, 10 Sep 2019 09:12:32 +0000 (09:12 +0000)
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>
src/cmd/compile/internal/ssa/gen/Wasm.rules
src/cmd/compile/internal/ssa/rewriteWasm.go

index 72080703f5571dde8460f585470ffb638dddcefc..c9dd6e808418586fd4aca5e7e7b7bc8a02da5ed5 100644 (file)
 // 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))
 
 (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))
 
 // 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))
 
index 45b855027d853f1cb2d52a7123a710f96e9606af..c9384af16ae567f9a1271d3fd03677a27fe8bbf7 100644 (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]))))