From 1786ecd502364ac92493acbdee5ddca50c80afde Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Sat, 24 Aug 2019 12:39:26 +0000 Subject: [PATCH] cmd/compile: eliminate WASM's redundant extension & wrapping 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 TryBot-Result: Gobot Gobot Reviewed-by: Richard Musiol --- src/cmd/compile/internal/wasm/ssa.go | 32 ++++++++++++++++++++-------- test/codegen/comparisons.go | 5 +++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/cmd/compile/internal/wasm/ssa.go b/src/cmd/compile/internal/wasm/ssa.go index 7fdd335ee9..b50f662a8b 100644 --- a/src/cmd/compile/internal/wasm/ssa.go +++ b/src/cmd/compile/internal/wasm/ssa.go @@ -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 } diff --git a/test/codegen/comparisons.go b/test/codegen/comparisons.go index 62ba184ed4..123199feee 100644 --- a/test/codegen/comparisons.go +++ b/test/codegen/comparisons.go @@ -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 } -- 2.50.0