mirror of
https://github.com/golang/go.git
synced 2026-02-06 18:00:01 +00:00
cmd/compile: handle loops better during stack allocation of slices
Don't use the move2heap optimization if the move2heap is inside a loop deeper than the declaration of the slice. We really only want to do the move2heap operation once. Change-Id: I4a68d01609c2c9d4e0abe4580839e70059393a81 Reviewed-on: https://go-review.googlesource.com/c/go/+/722440 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
efe9ad501d
commit
3c6bf6fbf3
2 changed files with 53 additions and 1 deletions
|
|
@ -152,6 +152,11 @@ func analyze(fn *ir.Func) {
|
|||
// least weight 2. (Note: appends in loops have weight >= 2.)
|
||||
appendWeight int
|
||||
|
||||
// Loop depth at declaration point.
|
||||
// Use for heuristics only, it is not guaranteed to be correct
|
||||
// in the presence of gotos.
|
||||
declDepth int
|
||||
|
||||
// Whether we ever do cap(s), or other operations that use cap(s)
|
||||
// (possibly implicitly), like s[i:j].
|
||||
capUsed bool
|
||||
|
|
@ -209,6 +214,20 @@ func analyze(fn *ir.Func) {
|
|||
i.s.Opt = nil
|
||||
return
|
||||
}
|
||||
if loopDepth > i.declDepth {
|
||||
// Conservatively, we disable this optimization when the
|
||||
// transition is inside a loop. This can result in adding
|
||||
// overhead unnecessarily in cases like:
|
||||
// func f(n int, p *[]byte) {
|
||||
// var s []byte
|
||||
// for i := range n {
|
||||
// *p = s
|
||||
// s = append(s, 0)
|
||||
// }
|
||||
// }
|
||||
i.s.Opt = nil
|
||||
return
|
||||
}
|
||||
i.transition = loc
|
||||
}
|
||||
|
||||
|
|
@ -237,7 +256,7 @@ func analyze(fn *ir.Func) {
|
|||
// s = append(s, ...) is ok
|
||||
i.okUses += 2
|
||||
i.appends = append(i.appends, y)
|
||||
i.appendWeight += 1 + loopDepth
|
||||
i.appendWeight += 1 + (loopDepth - i.declDepth)
|
||||
}
|
||||
// TODO: s = append(nil, ...)?
|
||||
}
|
||||
|
|
@ -277,6 +296,7 @@ func analyze(fn *ir.Func) {
|
|||
n := n.(*ir.Decl)
|
||||
if i := tracking(n.X); i != nil {
|
||||
i.okUses++
|
||||
i.declDepth = loopDepth
|
||||
}
|
||||
case ir.OINDEX:
|
||||
n := n.(*ir.IndexExpr)
|
||||
|
|
|
|||
|
|
@ -185,6 +185,38 @@ func Append17(n int) []int {
|
|||
return r
|
||||
}
|
||||
|
||||
func Append18(n int, p *[]int) {
|
||||
var r []int
|
||||
for i := range n {
|
||||
// amd64:-`.*moveSliceNoCapNoScan`
|
||||
*p = r
|
||||
// amd64:`.*growslice`
|
||||
r = append(r, i)
|
||||
}
|
||||
}
|
||||
|
||||
func Append19(n int, p [][]int) {
|
||||
for j := range p {
|
||||
var r []int
|
||||
for i := range n {
|
||||
// amd64:`.*growslice`
|
||||
r = append(r, i)
|
||||
}
|
||||
// amd64:`.*moveSliceNoCapNoScan`
|
||||
p[j] = r
|
||||
}
|
||||
}
|
||||
|
||||
func Append20(n int, p [][]int) {
|
||||
for j := range p {
|
||||
var r []int
|
||||
// amd64:`.*growslice`
|
||||
r = append(r, 0)
|
||||
// amd64:-`.*moveSliceNoCapNoScan`
|
||||
p[j] = r
|
||||
}
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func useSlice(s []int) {
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue