mirror of
https://github.com/golang/go.git
synced 2025-10-19 11:03:18 +00:00
cmd/compile: add MakeTuple generic SSA op to remove duplicate Select[01] rules
Change-Id: Id94a5e503f02aa29dc1e334b521770107d4261db Reviewed-on: https://go-review.googlesource.com/c/go/+/656615 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Jorropo <jorropo.pgm@gmail.com>
This commit is contained in:
parent
99411d7847
commit
4ff70cf868
4 changed files with 136 additions and 180 deletions
|
@ -174,8 +174,7 @@
|
|||
(Div64u (Const64 [c]) (Const64 [d])) && d != 0 => (Const64 [int64(uint64(c)/uint64(d))])
|
||||
(Div32F (Const32F [c]) (Const32F [d])) && c/d == c/d => (Const32F [c/d])
|
||||
(Div64F (Const64F [c]) (Const64F [d])) && c/d == c/d => (Const64F [c/d])
|
||||
(Select0 (Div128u (Const64 [0]) lo y)) => (Div64u lo y)
|
||||
(Select1 (Div128u (Const64 [0]) lo y)) => (Mod64u lo y)
|
||||
(Div128u <t> (Const64 [0]) lo y) => (MakeTuple (Div64u <t.FieldType(0)> lo y) (Mod64u <t.FieldType(1)> lo y))
|
||||
|
||||
(Not (ConstBool [c])) => (ConstBool [!c])
|
||||
|
||||
|
@ -186,8 +185,7 @@
|
|||
|
||||
// Convert x * 1 to x.
|
||||
(Mul(8|16|32|64) (Const(8|16|32|64) [1]) x) => x
|
||||
(Select0 (Mul(32|64)uover (Const(32|64) [1]) x)) => x
|
||||
(Select1 (Mul(32|64)uover (Const(32|64) [1]) x)) => (ConstBool [false])
|
||||
(Mul(32|64)uover <t> (Const(32|64) [1]) x) => (MakeTuple x (ConstBool <t.FieldType(1)> [false]))
|
||||
|
||||
// Convert x * -1 to -x.
|
||||
(Mul(8|16|32|64) (Const(8|16|32|64) [-1]) x) => (Neg(8|16|32|64) x)
|
||||
|
@ -592,8 +590,7 @@
|
|||
(Add(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
|
||||
(Sub(64|32|16|8) x x) => (Const(64|32|16|8) [0])
|
||||
(Mul(64|32|16|8) (Const(64|32|16|8) [0]) _) => (Const(64|32|16|8) [0])
|
||||
(Select0 (Mul(64|32)uover (Const(64|32) [0]) x)) => (Const(64|32) [0])
|
||||
(Select1 (Mul(64|32)uover (Const(64|32) [0]) x)) => (ConstBool [false])
|
||||
(Mul(64|32)uover <t> (Const(64|32) [0]) x) => (MakeTuple (Const(64|32) <t.FieldType(0)> [0]) (ConstBool <t.FieldType(1)> [false]))
|
||||
|
||||
(Com(64|32|16|8) (Com(64|32|16|8) x)) => x
|
||||
(Com(64|32|16|8) (Const(64|32|16|8) [c])) => (Const(64|32|16|8) [^c])
|
||||
|
@ -2046,6 +2043,10 @@
|
|||
|
||||
(Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(c)) => (Const64F [math.Sqrt(c)])
|
||||
|
||||
// for rewriting constant folded math/bits ops
|
||||
(Select0 (MakeTuple x y)) => x
|
||||
(Select1 (MakeTuple x y)) => y
|
||||
|
||||
// for rewriting results of some late-expanded rewrites (below)
|
||||
(SelectN [0] (MakeResult x ___)) => x
|
||||
(SelectN [1] (MakeResult x y ___)) => y
|
||||
|
|
|
@ -585,6 +585,7 @@ var genericOps = []opData{
|
|||
// pseudo-ops for breaking Tuple
|
||||
{name: "Select0", argLength: 1, zeroWidth: true}, // the first component of a tuple
|
||||
{name: "Select1", argLength: 1, zeroWidth: true}, // the second component of a tuple
|
||||
{name: "MakeTuple", argLength: 2}, // arg0 arg1 are components of a "Tuple" (like the result from a 128bits op).
|
||||
{name: "SelectN", argLength: 1, aux: "Int64"}, // arg0=result, auxint=field index. Returns the auxint'th member.
|
||||
{name: "SelectNAddr", argLength: 1, aux: "Int64"}, // arg0=result, auxint=field index. Returns the address of auxint'th member. Used for un-SSA-able result types.
|
||||
{name: "MakeResult", argLength: -1}, // arg0 .. are components of a "Result" (like the result from a Call). The last arg should be memory (like the result from a call).
|
||||
|
|
|
@ -3327,6 +3327,7 @@ const (
|
|||
OpCvt64Fto64U
|
||||
OpSelect0
|
||||
OpSelect1
|
||||
OpMakeTuple
|
||||
OpSelectN
|
||||
OpSelectNAddr
|
||||
OpMakeResult
|
||||
|
@ -42299,6 +42300,11 @@ var opcodeTable = [...]opInfo{
|
|||
zeroWidth: true,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "MakeTuple",
|
||||
argLen: 2,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "SelectN",
|
||||
auxType: auxInt64,
|
||||
|
|
|
@ -92,6 +92,8 @@ func rewriteValuegeneric(v *Value) bool {
|
|||
return rewriteValuegeneric_OpCvt64to64F(v)
|
||||
case OpCvtBoolToUint8:
|
||||
return rewriteValuegeneric_OpCvtBoolToUint8(v)
|
||||
case OpDiv128u:
|
||||
return rewriteValuegeneric_OpDiv128u(v)
|
||||
case OpDiv16:
|
||||
return rewriteValuegeneric_OpDiv16(v)
|
||||
case OpDiv16u:
|
||||
|
@ -242,10 +244,14 @@ func rewriteValuegeneric(v *Value) bool {
|
|||
return rewriteValuegeneric_OpMul32(v)
|
||||
case OpMul32F:
|
||||
return rewriteValuegeneric_OpMul32F(v)
|
||||
case OpMul32uover:
|
||||
return rewriteValuegeneric_OpMul32uover(v)
|
||||
case OpMul64:
|
||||
return rewriteValuegeneric_OpMul64(v)
|
||||
case OpMul64F:
|
||||
return rewriteValuegeneric_OpMul64F(v)
|
||||
case OpMul64uover:
|
||||
return rewriteValuegeneric_OpMul64uover(v)
|
||||
case OpMul8:
|
||||
return rewriteValuegeneric_OpMul8(v)
|
||||
case OpNeg16:
|
||||
|
@ -6246,6 +6252,30 @@ func rewriteValuegeneric_OpCvtBoolToUint8(v *Value) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpDiv128u(v *Value) bool {
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (Div128u <t> (Const64 [0]) lo y)
|
||||
// result: (MakeTuple (Div64u <t.FieldType(0)> lo y) (Mod64u <t.FieldType(1)> lo y))
|
||||
for {
|
||||
t := v.Type
|
||||
if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
lo := v_1
|
||||
y := v_2
|
||||
v.reset(OpMakeTuple)
|
||||
v0 := b.NewValue0(v.Pos, OpDiv64u, t.FieldType(0))
|
||||
v0.AddArg2(lo, y)
|
||||
v1 := b.NewValue0(v.Pos, OpMod64u, t.FieldType(1))
|
||||
v1.AddArg2(lo, y)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpDiv16(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
|
@ -18696,6 +18726,47 @@ func rewriteValuegeneric_OpMul32F(v *Value) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpMul32uover(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (Mul32uover <t> (Const32 [1]) x)
|
||||
// result: (MakeTuple x (ConstBool <t.FieldType(1)> [false]))
|
||||
for {
|
||||
t := v.Type
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
x := v_1
|
||||
v.reset(OpMakeTuple)
|
||||
v0 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
|
||||
v0.AuxInt = boolToAuxInt(false)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Mul32uover <t> (Const32 [0]) x)
|
||||
// result: (MakeTuple (Const32 <t.FieldType(0)> [0]) (ConstBool <t.FieldType(1)> [false]))
|
||||
for {
|
||||
t := v.Type
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpMakeTuple)
|
||||
v0 := b.NewValue0(v.Pos, OpConst32, t.FieldType(0))
|
||||
v0.AuxInt = int32ToAuxInt(0)
|
||||
v1 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
|
||||
v1.AuxInt = boolToAuxInt(false)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpMul64(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
|
@ -18971,6 +19042,47 @@ func rewriteValuegeneric_OpMul64F(v *Value) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpMul64uover(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (Mul64uover <t> (Const64 [1]) x)
|
||||
// result: (MakeTuple x (ConstBool <t.FieldType(1)> [false]))
|
||||
for {
|
||||
t := v.Type
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
x := v_1
|
||||
v.reset(OpMakeTuple)
|
||||
v0 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
|
||||
v0.AuxInt = boolToAuxInt(false)
|
||||
v.AddArg2(x, v0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Mul64uover <t> (Const64 [0]) x)
|
||||
// result: (MakeTuple (Const64 <t.FieldType(0)> [0]) (ConstBool <t.FieldType(1)> [false]))
|
||||
for {
|
||||
t := v.Type
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||
if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpMakeTuple)
|
||||
v0 := b.NewValue0(v.Pos, OpConst64, t.FieldType(0))
|
||||
v0.AuxInt = int64ToAuxInt(0)
|
||||
v1 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
|
||||
v1.AuxInt = boolToAuxInt(false)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpMul8(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
|
@ -29095,194 +29207,30 @@ func rewriteValuegeneric_OpRsh8x8(v *Value) bool {
|
|||
}
|
||||
func rewriteValuegeneric_OpSelect0(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (Select0 (Div128u (Const64 [0]) lo y))
|
||||
// result: (Div64u lo y)
|
||||
// match: (Select0 (MakeTuple x y))
|
||||
// result: x
|
||||
for {
|
||||
if v_0.Op != OpDiv128u {
|
||||
if v_0.Op != OpMakeTuple {
|
||||
break
|
||||
}
|
||||
y := v_0.Args[2]
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
lo := v_0.Args[1]
|
||||
v.reset(OpDiv64u)
|
||||
v.AddArg2(lo, y)
|
||||
x := v_0.Args[0]
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
// match: (Select0 (Mul32uover (Const32 [1]) x))
|
||||
// result: x
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
x := v_0_1
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select0 (Mul64uover (Const64 [1]) x))
|
||||
// result: x
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
x := v_0_1
|
||||
v.copyOf(x)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select0 (Mul64uover (Const64 [0]) x))
|
||||
// result: (Const64 [0])
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConst64)
|
||||
v.AuxInt = int64ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select0 (Mul32uover (Const32 [0]) x))
|
||||
// result: (Const32 [0])
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConst32)
|
||||
v.AuxInt = int32ToAuxInt(0)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpSelect1(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
// match: (Select1 (Div128u (Const64 [0]) lo y))
|
||||
// result: (Mod64u lo y)
|
||||
// match: (Select1 (MakeTuple x y))
|
||||
// result: y
|
||||
for {
|
||||
if v_0.Op != OpDiv128u {
|
||||
if v_0.Op != OpMakeTuple {
|
||||
break
|
||||
}
|
||||
y := v_0.Args[2]
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
lo := v_0.Args[1]
|
||||
v.reset(OpMod64u)
|
||||
v.AddArg2(lo, y)
|
||||
y := v_0.Args[1]
|
||||
v.copyOf(y)
|
||||
return true
|
||||
}
|
||||
// match: (Select1 (Mul32uover (Const32 [1]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (Mul64uover (Const64 [1]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (Mul64uover (Const64 [0]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul64uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Select1 (Mul32uover (Const32 [0]) x))
|
||||
// result: (ConstBool [false])
|
||||
for {
|
||||
if v_0.Op != OpMul32uover {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_0_0 := v_0.Args[0]
|
||||
v_0_1 := v_0.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
|
||||
if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = boolToAuxInt(false)
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpSelectN(v *Value) bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue