]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: eliminate WASM's redundant extension & wrapping
authorBen Shi <powerman1st@163.com>
Sat, 24 Aug 2019 12:39:26 +0000 (12:39 +0000)
committerCherry Zhang <cherryyz@google.com>
Fri, 30 Aug 2019 21:20:03 +0000 (21:20 +0000)
This CL eliminates unnecessary pairs of I32WrapI64 and
I64ExtendI32U generated by the WASM backend for IF
statements. And it makes the total size of pkg/js_wasm/
decreases about 490KB.

Change-Id: I16b0abb686c4e30d5624323166ec2d0ec57dbe2d
Reviewed-on: https://go-review.googlesource.com/c/go/+/191758
Run-TryBot: Ben Shi <powerman1st@163.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Richard Musiol <neelance@gmail.com>
src/cmd/compile/internal/wasm/ssa.go
test/codegen/comparisons.go

index 7fdd335ee9fa5e2ac5b280ca46a8303a780641be..b50f662a8b526e52d5ea07be45a2ed032a15c424 100644 (file)
@@ -201,7 +201,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                        // Instead, we delay the generation to when the value is used and then directly generate it on the WebAssembly stack.
                        return
                }
-               ssaGenValueOnStack(s, v)
+               ssaGenValueOnStack(s, v, true)
                if s.OnWasmStackSkipped != 0 {
                        panic("wasm: bad stack")
                }
@@ -209,7 +209,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        }
 }
 
-func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) {
        switch v.Op {
        case ssa.OpWasmLoweredGetClosurePtr:
                getReg(s, wasm.REG_CTXT)
@@ -257,8 +257,7 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpWasmSelect:
                getValue64(s, v.Args[0])
                getValue64(s, v.Args[1])
-               getValue64(s, v.Args[2])
-               s.Prog(wasm.AI32WrapI64)
+               getValue32(s, v.Args[2])
                s.Prog(v.Op.Asm())
 
        case ssa.OpWasmI64AddConst:
@@ -283,13 +282,17 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpWasmI64Eqz:
                getValue64(s, v.Args[0])
                s.Prog(v.Op.Asm())
-               s.Prog(wasm.AI64ExtendI32U)
+               if extend {
+                       s.Prog(wasm.AI64ExtendI32U)
+               }
 
        case ssa.OpWasmI64Eq, ssa.OpWasmI64Ne, ssa.OpWasmI64LtS, ssa.OpWasmI64LtU, ssa.OpWasmI64GtS, ssa.OpWasmI64GtU, ssa.OpWasmI64LeS, ssa.OpWasmI64LeU, ssa.OpWasmI64GeS, ssa.OpWasmI64GeU, ssa.OpWasmF64Eq, ssa.OpWasmF64Ne, ssa.OpWasmF64Lt, ssa.OpWasmF64Gt, ssa.OpWasmF64Le, ssa.OpWasmF64Ge:
                getValue64(s, v.Args[0])
                getValue64(s, v.Args[1])
                s.Prog(v.Op.Asm())
-               s.Prog(wasm.AI64ExtendI32U)
+               if extend {
+                       s.Prog(wasm.AI64ExtendI32U)
+               }
 
        case ssa.OpWasmI64Add, ssa.OpWasmI64Sub, ssa.OpWasmI64Mul, ssa.OpWasmI64DivU, ssa.OpWasmI64RemS, ssa.OpWasmI64RemU, ssa.OpWasmI64And, ssa.OpWasmI64Or, ssa.OpWasmI64Xor, ssa.OpWasmI64Shl, ssa.OpWasmI64ShrS, ssa.OpWasmI64ShrU, ssa.OpWasmF64Add, ssa.OpWasmF64Sub, ssa.OpWasmF64Mul, ssa.OpWasmF64Div, ssa.OpWasmF64Copysign, ssa.OpWasmI64Rotl:
                getValue64(s, v.Args[0])
@@ -348,11 +351,22 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) {
        }
 }
 
+func isCmp(v *ssa.Value) bool {
+       switch v.Op {
+       case ssa.OpWasmI64Eqz, ssa.OpWasmI64Eq, ssa.OpWasmI64Ne, ssa.OpWasmI64LtS, ssa.OpWasmI64LtU, ssa.OpWasmI64GtS, ssa.OpWasmI64GtU, ssa.OpWasmI64LeS, ssa.OpWasmI64LeU, ssa.OpWasmI64GeS, ssa.OpWasmI64GeU, ssa.OpWasmF64Eq, ssa.OpWasmF64Ne, ssa.OpWasmF64Lt, ssa.OpWasmF64Gt, ssa.OpWasmF64Le, ssa.OpWasmF64Ge:
+               return true
+       default:
+               return false
+       }
+}
+
 func getValue32(s *gc.SSAGenState, v *ssa.Value) {
        if v.OnWasmStack {
                s.OnWasmStackSkipped--
-               ssaGenValueOnStack(s, v)
-               s.Prog(wasm.AI32WrapI64)
+               ssaGenValueOnStack(s, v, false)
+               if !isCmp(v) {
+                       s.Prog(wasm.AI32WrapI64)
+               }
                return
        }
 
@@ -366,7 +380,7 @@ func getValue32(s *gc.SSAGenState, v *ssa.Value) {
 func getValue64(s *gc.SSAGenState, v *ssa.Value) {
        if v.OnWasmStack {
                s.OnWasmStackSkipped--
-               ssaGenValueOnStack(s, v)
+               ssaGenValueOnStack(s, v, true)
                return
        }
 
index 62ba184ed4e5cce1ce0c46fee4a82451374ba9ca..123199feee454d8353b91f25bb04b8831d8c6526 100644 (file)
@@ -215,29 +215,34 @@ func CmpLogicalToZero(a, b, c uint32, d, e uint64) uint64 {
 
        // ppc64:"ANDCC",-"CMPW"
        // ppc64le:"ANDCC",-"CMPW"
+       // wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
        if a&63 == 0 {
                return 1
        }
 
        // ppc64:"ANDCC",-"CMP"
        // ppc64le:"ANDCC",-"CMP"
+       // wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
        if d&255 == 0 {
                return 1
        }
 
        // ppc64:"ANDCC",-"CMP"
        // ppc64le:"ANDCC",-"CMP"
+       // wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
        if d&e == 0 {
                return 1
        }
        // ppc64:"ORCC",-"CMP"
        // ppc64le:"ORCC",-"CMP"
+       // wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
        if d|e == 0 {
                return 1
        }
 
        // ppc64:"XORCC",-"CMP"
        // ppc64le:"XORCC",-"CMP"
+       // wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
        if e^d == 0 {
                return 1
        }