mirror of
https://github.com/golang/go.git
synced 2025-10-19 19:13:18 +00:00
cmd/compile: rewrite to elide Slicemask from len==c>0 slicing
This might have been something that prove could be educated into figuring out, but this also works, and it also helps prove downstream. Adjusted the prove test, because this change moved a message. Cherry-picked from the dev.simd branch. This CL is not necessarily SIMD specific. Apply early to reduce risk. Change-Id: I5eabe639eff5db9cd9766a6a8666fdb4973829cb Reviewed-on: https://go-review.googlesource.com/c/go/+/697715 Commit-Queue: David Chase <drchase@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Bypass: David Chase <drchase@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/708858 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com>
This commit is contained in:
parent
10e7968849
commit
ec70d19023
3 changed files with 93 additions and 2 deletions
|
@ -989,6 +989,10 @@
|
||||||
(Const64 <typ.Int> [0])
|
(Const64 <typ.Int> [0])
|
||||||
(Const64 <typ.Int> [0]))
|
(Const64 <typ.Int> [0]))
|
||||||
|
|
||||||
|
// Special rule to help constant slicing; len > 0 implies cap > 0 implies Slicemask is all 1
|
||||||
|
(SliceMake (AddPtr <t> x (And64 y (Slicemask _))) w:(Const64 [c]) z) && c > 0 => (SliceMake (AddPtr <t> x y) w z)
|
||||||
|
(SliceMake (AddPtr <t> x (And32 y (Slicemask _))) w:(Const32 [c]) z) && c > 0 => (SliceMake (AddPtr <t> x y) w z)
|
||||||
|
|
||||||
// interface ops
|
// interface ops
|
||||||
(ConstInterface) =>
|
(ConstInterface) =>
|
||||||
(IMake
|
(IMake
|
||||||
|
|
|
@ -422,6 +422,8 @@ func rewriteValuegeneric(v *Value) bool {
|
||||||
return rewriteValuegeneric_OpSliceCap(v)
|
return rewriteValuegeneric_OpSliceCap(v)
|
||||||
case OpSliceLen:
|
case OpSliceLen:
|
||||||
return rewriteValuegeneric_OpSliceLen(v)
|
return rewriteValuegeneric_OpSliceLen(v)
|
||||||
|
case OpSliceMake:
|
||||||
|
return rewriteValuegeneric_OpSliceMake(v)
|
||||||
case OpSlicePtr:
|
case OpSlicePtr:
|
||||||
return rewriteValuegeneric_OpSlicePtr(v)
|
return rewriteValuegeneric_OpSlicePtr(v)
|
||||||
case OpSlicemask:
|
case OpSlicemask:
|
||||||
|
@ -30514,6 +30516,91 @@ func rewriteValuegeneric_OpSliceLen(v *Value) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
func rewriteValuegeneric_OpSliceMake(v *Value) bool {
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
b := v.Block
|
||||||
|
// match: (SliceMake (AddPtr <t> x (And64 y (Slicemask _))) w:(Const64 [c]) z)
|
||||||
|
// cond: c > 0
|
||||||
|
// result: (SliceMake (AddPtr <t> x y) w z)
|
||||||
|
for {
|
||||||
|
if v_0.Op != OpAddPtr {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
t := v_0.Type
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
x := v_0.Args[0]
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpAnd64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_1.Args[1]
|
||||||
|
v_0_1_0 := v_0_1.Args[0]
|
||||||
|
v_0_1_1 := v_0_1.Args[1]
|
||||||
|
for _i0 := 0; _i0 <= 1; _i0, v_0_1_0, v_0_1_1 = _i0+1, v_0_1_1, v_0_1_0 {
|
||||||
|
y := v_0_1_0
|
||||||
|
if v_0_1_1.Op != OpSlicemask {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
w := v_1
|
||||||
|
if w.Op != OpConst64 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c := auxIntToInt64(w.AuxInt)
|
||||||
|
z := v_2
|
||||||
|
if !(c > 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v.reset(OpSliceMake)
|
||||||
|
v0 := b.NewValue0(v.Pos, OpAddPtr, t)
|
||||||
|
v0.AddArg2(x, y)
|
||||||
|
v.AddArg3(v0, w, z)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// match: (SliceMake (AddPtr <t> x (And32 y (Slicemask _))) w:(Const32 [c]) z)
|
||||||
|
// cond: c > 0
|
||||||
|
// result: (SliceMake (AddPtr <t> x y) w z)
|
||||||
|
for {
|
||||||
|
if v_0.Op != OpAddPtr {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
t := v_0.Type
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
x := v_0.Args[0]
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpAnd32 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_1.Args[1]
|
||||||
|
v_0_1_0 := v_0_1.Args[0]
|
||||||
|
v_0_1_1 := v_0_1.Args[1]
|
||||||
|
for _i0 := 0; _i0 <= 1; _i0, v_0_1_0, v_0_1_1 = _i0+1, v_0_1_1, v_0_1_0 {
|
||||||
|
y := v_0_1_0
|
||||||
|
if v_0_1_1.Op != OpSlicemask {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
w := v_1
|
||||||
|
if w.Op != OpConst32 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c := auxIntToInt32(w.AuxInt)
|
||||||
|
z := v_2
|
||||||
|
if !(c > 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v.reset(OpSliceMake)
|
||||||
|
v0 := b.NewValue0(v.Pos, OpAddPtr, t)
|
||||||
|
v0.AddArg2(x, y)
|
||||||
|
v.AddArg3(v0, w, z)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
func rewriteValuegeneric_OpSlicePtr(v *Value) bool {
|
func rewriteValuegeneric_OpSlicePtr(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
// match: (SlicePtr (SliceMake (SlicePtr x) _ _))
|
// match: (SlicePtr (SliceMake (SlicePtr x) _ _))
|
||||||
|
|
|
@ -511,10 +511,10 @@ func f19() (e int64, err error) {
|
||||||
|
|
||||||
func sm1(b []int, x int) {
|
func sm1(b []int, x int) {
|
||||||
// Test constant argument to slicemask.
|
// Test constant argument to slicemask.
|
||||||
useSlice(b[2:8]) // ERROR "Proved slicemask not needed$"
|
useSlice(b[2:8]) // optimized away earlier by rewrite
|
||||||
// Test non-constant argument with known limits.
|
// Test non-constant argument with known limits.
|
||||||
if cap(b) > 10 {
|
if cap(b) > 10 {
|
||||||
useSlice(b[2:])
|
useSlice(b[2:]) // ERROR "Proved slicemask not needed$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue