Commit 1786ecd5 authored by Ben Shi's avatar Ben Shi Committed by Cherry Zhang

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 <powerman1st@163.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRichard Musiol <neelance@gmail.com>
parent cd03fd05
...@@ -201,7 +201,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -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. // Instead, we delay the generation to when the value is used and then directly generate it on the WebAssembly stack.
return return
} }
ssaGenValueOnStack(s, v) ssaGenValueOnStack(s, v, true)
if s.OnWasmStackSkipped != 0 { if s.OnWasmStackSkipped != 0 {
panic("wasm: bad stack") panic("wasm: bad stack")
} }
...@@ -209,7 +209,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -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 { switch v.Op {
case ssa.OpWasmLoweredGetClosurePtr: case ssa.OpWasmLoweredGetClosurePtr:
getReg(s, wasm.REG_CTXT) getReg(s, wasm.REG_CTXT)
...@@ -257,8 +257,7 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) { ...@@ -257,8 +257,7 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpWasmSelect: case ssa.OpWasmSelect:
getValue64(s, v.Args[0]) getValue64(s, v.Args[0])
getValue64(s, v.Args[1]) getValue64(s, v.Args[1])
getValue64(s, v.Args[2]) getValue32(s, v.Args[2])
s.Prog(wasm.AI32WrapI64)
s.Prog(v.Op.Asm()) s.Prog(v.Op.Asm())
case ssa.OpWasmI64AddConst: case ssa.OpWasmI64AddConst:
...@@ -283,13 +282,17 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) { ...@@ -283,13 +282,17 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpWasmI64Eqz: case ssa.OpWasmI64Eqz:
getValue64(s, v.Args[0]) getValue64(s, v.Args[0])
s.Prog(v.Op.Asm()) s.Prog(v.Op.Asm())
if extend {
s.Prog(wasm.AI64ExtendI32U) 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: 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[0])
getValue64(s, v.Args[1]) getValue64(s, v.Args[1])
s.Prog(v.Op.Asm()) s.Prog(v.Op.Asm())
if extend {
s.Prog(wasm.AI64ExtendI32U) 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: 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]) getValue64(s, v.Args[0])
...@@ -348,11 +351,22 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) { ...@@ -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) { func getValue32(s *gc.SSAGenState, v *ssa.Value) {
if v.OnWasmStack { if v.OnWasmStack {
s.OnWasmStackSkipped-- s.OnWasmStackSkipped--
ssaGenValueOnStack(s, v) ssaGenValueOnStack(s, v, false)
if !isCmp(v) {
s.Prog(wasm.AI32WrapI64) s.Prog(wasm.AI32WrapI64)
}
return return
} }
...@@ -366,7 +380,7 @@ func getValue32(s *gc.SSAGenState, v *ssa.Value) { ...@@ -366,7 +380,7 @@ func getValue32(s *gc.SSAGenState, v *ssa.Value) {
func getValue64(s *gc.SSAGenState, v *ssa.Value) { func getValue64(s *gc.SSAGenState, v *ssa.Value) {
if v.OnWasmStack { if v.OnWasmStack {
s.OnWasmStackSkipped-- s.OnWasmStackSkipped--
ssaGenValueOnStack(s, v) ssaGenValueOnStack(s, v, true)
return return
} }
......
...@@ -215,29 +215,34 @@ func CmpLogicalToZero(a, b, c uint32, d, e uint64) uint64 { ...@@ -215,29 +215,34 @@ func CmpLogicalToZero(a, b, c uint32, d, e uint64) uint64 {
// ppc64:"ANDCC",-"CMPW" // ppc64:"ANDCC",-"CMPW"
// ppc64le:"ANDCC",-"CMPW" // ppc64le:"ANDCC",-"CMPW"
// wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
if a&63 == 0 { if a&63 == 0 {
return 1 return 1
} }
// ppc64:"ANDCC",-"CMP" // ppc64:"ANDCC",-"CMP"
// ppc64le:"ANDCC",-"CMP" // ppc64le:"ANDCC",-"CMP"
// wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
if d&255 == 0 { if d&255 == 0 {
return 1 return 1
} }
// ppc64:"ANDCC",-"CMP" // ppc64:"ANDCC",-"CMP"
// ppc64le:"ANDCC",-"CMP" // ppc64le:"ANDCC",-"CMP"
// wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
if d&e == 0 { if d&e == 0 {
return 1 return 1
} }
// ppc64:"ORCC",-"CMP" // ppc64:"ORCC",-"CMP"
// ppc64le:"ORCC",-"CMP" // ppc64le:"ORCC",-"CMP"
// wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
if d|e == 0 { if d|e == 0 {
return 1 return 1
} }
// ppc64:"XORCC",-"CMP" // ppc64:"XORCC",-"CMP"
// ppc64le:"XORCC",-"CMP" // ppc64le:"XORCC",-"CMP"
// wasm:"I32Eqz",-"I64ExtendI32U",-"I32WrapI64"
if e^d == 0 { if e^d == 0 {
return 1 return 1
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment