mirror of
https://github.com/golang/go.git
synced 2025-05-28 02:41:30 +00:00
cmd/compile: fix write barrier control value on wasm
This commit fixes a regression with wasm caused by a367f44c18. It adds optimizations to the lowering rules of wasm to ensure that the lowered version of the code generated for write barriers is simple enough so it can be processed by Liveness.markUnsafePoints. Change-Id: Ic98f0dd3791fe1df23dcb34d2457fbde7ffce441 Reviewed-on: https://go-review.googlesource.com/114375 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
c730a93fb9
commit
8aa57f1e9d
@ -729,7 +729,7 @@ func (lv *Liveness) markUnsafePoints() {
|
||||
v = v.Args[0]
|
||||
continue
|
||||
}
|
||||
case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpPPC64MOVWZload:
|
||||
case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpPPC64MOVWZload, ssa.OpWasmI64Load32U:
|
||||
// Args[0] is the address of the write
|
||||
// barrier control. Ignore Args[1],
|
||||
// which is the mem operand.
|
||||
|
@ -50,10 +50,16 @@
|
||||
(OffPtr [off] ptr) && off > 0 -> (I64AddConst [off] ptr)
|
||||
|
||||
// Lowering extension
|
||||
// It is unnecessary to extend loads
|
||||
(SignExt32to64 x:(I64Load32S _ _)) -> x
|
||||
(SignExt16to(64|32) x:(I64Load16S _ _)) -> x
|
||||
(SignExt8to(64|32|16) x:(I64Load8S _ _)) -> x
|
||||
(ZeroExt32to64 x:(I64Load32U _ _)) -> x
|
||||
(ZeroExt16to(64|32) x:(I64Load16U _ _)) -> x
|
||||
(ZeroExt8to(64|32|16) x:(I64Load8U _ _)) -> x
|
||||
(SignExt32to64 x) -> (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
|
||||
(SignExt16to(64|32) x) -> (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
|
||||
(SignExt8to(64|32|16) x) -> (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
|
||||
(ZeroExt32to64 x) -> (I64ShrU (I64Shl x (I64Const [32])) (I64Const [32]))
|
||||
(ZeroExt16to(64|32) x) -> (I64ShrU (I64Shl x (I64Const [48])) (I64Const [48]))
|
||||
(ZeroExt8to(64|32|16) x) -> (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
@ -364,6 +370,10 @@
|
||||
(I64Ne (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [0])
|
||||
(I64Ne (I64Const [x]) (I64Const [y])) && x != y -> (I64Const [1])
|
||||
|
||||
(I64Shl (I64Const [x]) (I64Const [y])) -> (I64Const [x << uint64(y)])
|
||||
(I64ShrU (I64Const [x]) (I64Const [y])) -> (I64Const [int64(uint64(x) >> uint64(y))])
|
||||
(I64ShrS (I64Const [x]) (I64Const [y])) -> (I64Const [x >> uint64(y)])
|
||||
|
||||
(I64Add (I64Const [x]) y) -> (I64Add y (I64Const [x]))
|
||||
(I64Mul (I64Const [x]) y) -> (I64Mul y (I64Const [x]))
|
||||
(I64And (I64Const [x]) y) -> (I64And y (I64Const [x]))
|
||||
@ -374,6 +384,9 @@
|
||||
(I64Eq (I64Const [x]) y) -> (I64Eq y (I64Const [x]))
|
||||
(I64Ne (I64Const [x]) y) -> (I64Ne y (I64Const [x]))
|
||||
|
||||
(I64Eq x (I64Const [0])) -> (I64Eqz x)
|
||||
(I64Ne x (I64Const [0])) -> (I64Eqz (I64Eqz x))
|
||||
|
||||
(I64Add x (I64Const [y])) -> (I64AddConst [y] x)
|
||||
(I64Eqz (I64Eqz (I64Eqz x))) -> (I64Eqz x)
|
||||
|
||||
|
@ -489,6 +489,12 @@ func rewriteValueWasm(v *Value) bool {
|
||||
return rewriteValueWasm_OpWasmI64Ne_0(v)
|
||||
case OpWasmI64Or:
|
||||
return rewriteValueWasm_OpWasmI64Or_0(v)
|
||||
case OpWasmI64Shl:
|
||||
return rewriteValueWasm_OpWasmI64Shl_0(v)
|
||||
case OpWasmI64ShrS:
|
||||
return rewriteValueWasm_OpWasmI64ShrS_0(v)
|
||||
case OpWasmI64ShrU:
|
||||
return rewriteValueWasm_OpWasmI64ShrU_0(v)
|
||||
case OpWasmI64Store:
|
||||
return rewriteValueWasm_OpWasmI64Store_0(v)
|
||||
case OpWasmI64Store16:
|
||||
@ -4503,6 +4509,20 @@ func rewriteValueWasm_OpSignExt16to32_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (SignExt16to32 x:(I64Load16S _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load16S {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (SignExt16to32 x)
|
||||
// cond:
|
||||
// result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
|
||||
@ -4526,6 +4546,20 @@ func rewriteValueWasm_OpSignExt16to64_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (SignExt16to64 x:(I64Load16S _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load16S {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (SignExt16to64 x)
|
||||
// cond:
|
||||
// result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
|
||||
@ -4549,6 +4583,20 @@ func rewriteValueWasm_OpSignExt32to64_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (SignExt32to64 x:(I64Load32S _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load32S {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (SignExt32to64 x)
|
||||
// cond:
|
||||
// result: (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
|
||||
@ -4572,6 +4620,20 @@ func rewriteValueWasm_OpSignExt8to16_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (SignExt8to16 x:(I64Load8S _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load8S {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (SignExt8to16 x)
|
||||
// cond:
|
||||
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
@ -4595,6 +4657,20 @@ func rewriteValueWasm_OpSignExt8to32_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (SignExt8to32 x:(I64Load8S _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load8S {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (SignExt8to32 x)
|
||||
// cond:
|
||||
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
@ -4618,6 +4694,20 @@ func rewriteValueWasm_OpSignExt8to64_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (SignExt8to64 x:(I64Load8S _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load8S {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (SignExt8to64 x)
|
||||
// cond:
|
||||
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
@ -5232,6 +5322,23 @@ func rewriteValueWasm_OpWasmI64Eq_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (I64Eq x (I64Const [0]))
|
||||
// cond:
|
||||
// result: (I64Eqz x)
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
x := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
if v_1.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
v.reset(OpWasmI64Eqz)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64Eqz_0(v *Value) bool {
|
||||
@ -5540,6 +5647,25 @@ func rewriteValueWasm_OpWasmI64Ne_0(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (I64Ne x (I64Const [0]))
|
||||
// cond:
|
||||
// result: (I64Eqz (I64Eqz x))
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
x := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
if v_1.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
v.reset(OpWasmI64Eqz)
|
||||
v0 := b.NewValue0(v.Pos, OpWasmI64Eqz, typ.Bool)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64Or_0(v *Value) bool {
|
||||
@ -5586,6 +5712,72 @@ func rewriteValueWasm_OpWasmI64Or_0(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64Shl_0(v *Value) bool {
|
||||
// match: (I64Shl (I64Const [x]) (I64Const [y]))
|
||||
// cond:
|
||||
// result: (I64Const [x << uint64(y)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
x := v_0.AuxInt
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
y := v_1.AuxInt
|
||||
v.reset(OpWasmI64Const)
|
||||
v.AuxInt = x << uint64(y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64ShrS_0(v *Value) bool {
|
||||
// match: (I64ShrS (I64Const [x]) (I64Const [y]))
|
||||
// cond:
|
||||
// result: (I64Const [x >> uint64(y)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
x := v_0.AuxInt
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
y := v_1.AuxInt
|
||||
v.reset(OpWasmI64Const)
|
||||
v.AuxInt = x >> uint64(y)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64ShrU_0(v *Value) bool {
|
||||
// match: (I64ShrU (I64Const [x]) (I64Const [y]))
|
||||
// cond:
|
||||
// result: (I64Const [int64(uint64(x) >> uint64(y))])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
x := v_0.AuxInt
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpWasmI64Const {
|
||||
break
|
||||
}
|
||||
y := v_1.AuxInt
|
||||
v.reset(OpWasmI64Const)
|
||||
v.AuxInt = int64(uint64(x) >> uint64(y))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueWasm_OpWasmI64Store_0(v *Value) bool {
|
||||
// match: (I64Store [off] (I64AddConst [off2] ptr) val mem)
|
||||
// cond: isU32Bit(off+off2)
|
||||
@ -6138,6 +6330,20 @@ func rewriteValueWasm_OpZeroExt16to32_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (ZeroExt16to32 x:(I64Load16U _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load16U {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ZeroExt16to32 x)
|
||||
// cond:
|
||||
// result: (I64ShrU (I64Shl x (I64Const [48])) (I64Const [48]))
|
||||
@ -6161,6 +6367,20 @@ func rewriteValueWasm_OpZeroExt16to64_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (ZeroExt16to64 x:(I64Load16U _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load16U {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ZeroExt16to64 x)
|
||||
// cond:
|
||||
// result: (I64ShrU (I64Shl x (I64Const [48])) (I64Const [48]))
|
||||
@ -6184,6 +6404,20 @@ func rewriteValueWasm_OpZeroExt32to64_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (ZeroExt32to64 x:(I64Load32U _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load32U {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ZeroExt32to64 x)
|
||||
// cond:
|
||||
// result: (I64ShrU (I64Shl x (I64Const [32])) (I64Const [32]))
|
||||
@ -6207,6 +6441,20 @@ func rewriteValueWasm_OpZeroExt8to16_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (ZeroExt8to16 x:(I64Load8U _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load8U {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ZeroExt8to16 x)
|
||||
// cond:
|
||||
// result: (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
@ -6230,6 +6478,20 @@ func rewriteValueWasm_OpZeroExt8to32_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (ZeroExt8to32 x:(I64Load8U _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load8U {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ZeroExt8to32 x)
|
||||
// cond:
|
||||
// result: (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
@ -6253,6 +6515,20 @@ func rewriteValueWasm_OpZeroExt8to64_0(v *Value) bool {
|
||||
_ = b
|
||||
typ := &b.Func.Config.Types
|
||||
_ = typ
|
||||
// match: (ZeroExt8to64 x:(I64Load8U _ _))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpWasmI64Load8U {
|
||||
break
|
||||
}
|
||||
_ = x.Args[1]
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ZeroExt8to64 x)
|
||||
// cond:
|
||||
// result: (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
|
||||
|
Loading…
x
Reference in New Issue
Block a user