mirror of https://github.com/golang/go.git
cmd/compile: add rule for post-decomposed growslice optimization
The recently added rule only works before decomposing slices. Add a rule that works after decomposing slices. The reason we need the latter is because although the length may be a constant, it can be hidden inside a slice that is not constant (its pointer or capacity might be changing). By applying this optimization after decomposing slices, we can find more cases where it applies. Fixes #56440 Change-Id: I0094e59eee3065ab4d210defdda8227a6e897420 Reviewed-on: https://go-review.googlesource.com/c/go/+/446277 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
204be97d24
commit
9ce27feaeb
|
|
@ -2544,7 +2544,10 @@
|
||||||
// The exception here is that if the new length is a constant, avoiding spilling it
|
// The exception here is that if the new length is a constant, avoiding spilling it
|
||||||
// is pointless and its constantness is sometimes useful for subsequent optimizations.
|
// is pointless and its constantness is sometimes useful for subsequent optimizations.
|
||||||
// See issue 56440.
|
// See issue 56440.
|
||||||
|
// Note there are 2 rules here, one for the pre-decomposed []T result and one for
|
||||||
|
// the post-decomposed (*T,int,int) result. (The latter is generated after call expansion.)
|
||||||
(SliceLen (SelectN [0] (StaticLECall {sym} _ newLen:(Const(64|32)) _ _ _ _))) && isSameCall(sym, "runtime.growslice") => newLen
|
(SliceLen (SelectN [0] (StaticLECall {sym} _ newLen:(Const(64|32)) _ _ _ _))) && isSameCall(sym, "runtime.growslice") => newLen
|
||||||
|
(SelectN [1] (StaticCall {sym} _ newLen:(Const(64|32)) _ _ _ _)) && v.Type.IsInteger() && isSameCall(sym, "runtime.growslice") => newLen
|
||||||
|
|
||||||
// Collapse moving A -> B -> C into just A -> C.
|
// Collapse moving A -> B -> C into just A -> C.
|
||||||
// Later passes (deadstore, elim unread auto) will remove the A -> B move, if possible.
|
// Later passes (deadstore, elim unread auto) will remove the A -> B move, if possible.
|
||||||
|
|
|
||||||
|
|
@ -26621,6 +26621,38 @@ func rewriteValuegeneric_OpSelectN(v *Value) bool {
|
||||||
v.copyOf(x)
|
v.copyOf(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// match: (SelectN [1] (StaticCall {sym} _ newLen:(Const64) _ _ _ _))
|
||||||
|
// cond: v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")
|
||||||
|
// result: newLen
|
||||||
|
for {
|
||||||
|
if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStaticCall || len(v_0.Args) != 6 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sym := auxToCall(v_0.Aux)
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
newLen := v_0.Args[1]
|
||||||
|
if newLen.Op != OpConst64 || !(v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.copyOf(newLen)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (SelectN [1] (StaticCall {sym} _ newLen:(Const32) _ _ _ _))
|
||||||
|
// cond: v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")
|
||||||
|
// result: newLen
|
||||||
|
for {
|
||||||
|
if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStaticCall || len(v_0.Args) != 6 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sym := auxToCall(v_0.Aux)
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
newLen := v_0.Args[1]
|
||||||
|
if newLen.Op != OpConst32 || !(v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.copyOf(newLen)
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
func rewriteValuegeneric_OpSignExt16to32(v *Value) bool {
|
func rewriteValuegeneric_OpSignExt16to32(v *Value) bool {
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,19 @@ func f(x []int) int {
|
||||||
// amd64:`MOVQ\t40\(.*\),`
|
// amd64:`MOVQ\t40\(.*\),`
|
||||||
return x[len(s)]
|
return x[len(s)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func g(x []int, p *bool) int {
|
||||||
|
s := make([]int, 3)
|
||||||
|
for {
|
||||||
|
s = s[:3]
|
||||||
|
if cap(s) < 5 {
|
||||||
|
s = make([]int, 3, 5)
|
||||||
|
}
|
||||||
|
s = append(s, 4, 5)
|
||||||
|
if *p {
|
||||||
|
// amd64:`MOVQ\t40\(.*\),`
|
||||||
|
return x[len(s)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue