mirror of
https://github.com/golang/go.git
synced 2026-01-29 07:02:05 +03:00
cmd/compile: propagate len([]T{}) to make builtin to allow stack allocation
Updates #75620 Change-Id: I6a6a6964af4512e30eb4806e1dc7b0fd0835744f Reviewed-on: https://go-review.googlesource.com/c/go/+/707255 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
committed by
Gopher Robot
parent
5799c139a7
commit
84db201ae1
@@ -563,7 +563,10 @@ func (b *batch) rewriteWithLiterals(n ir.Node, fn *ir.Func) {
|
||||
if ro == nil {
|
||||
base.Fatalf("no ReassignOracle for function %v with closure parent %v", fn, fn.ClosureParent)
|
||||
}
|
||||
if s := ro.StaticValue(*r); s.Op() == ir.OLITERAL {
|
||||
|
||||
s := ro.StaticValue(*r)
|
||||
switch s.Op() {
|
||||
case ir.OLITERAL:
|
||||
lit, ok := s.(*ir.BasicLit)
|
||||
if !ok || lit.Val().Kind() != constant.Int {
|
||||
base.Fatalf("unexpected BasicLit Kind")
|
||||
@@ -577,6 +580,14 @@ func (b *batch) rewriteWithLiterals(n ir.Node, fn *ir.Func) {
|
||||
assignTemp(n.Pos(), *r, n.PtrInit())
|
||||
*r = ir.NewBasicLit(n.Pos(), (*r).Type(), lit.Val())
|
||||
}
|
||||
case ir.OLEN:
|
||||
x := ro.StaticValue(s.(*ir.UnaryExpr).X)
|
||||
if x.Op() == ir.OSLICELIT {
|
||||
x := x.(*ir.CompLitExpr)
|
||||
// Preserve any side effects of the original expression, then update the value.
|
||||
assignTemp(n.Pos(), *r, n.PtrInit())
|
||||
*r = ir.NewBasicLit(n.Pos(), types.Types[types.TINT], constant.MakeInt64(x.Len))
|
||||
}
|
||||
}
|
||||
}
|
||||
case ir.OCONVIFACE:
|
||||
|
||||
@@ -106,3 +106,18 @@ type m struct {
|
||||
func newM(l int) m { // ERROR "can inline"
|
||||
return m{make(map[string]int, l)} // ERROR "make.*escapes to heap"
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func testLenOfSliceLit() {
|
||||
ints := []int{0, 1, 2, 3, 4, 5} // ERROR "\[\]int\{\.\.\.\} does not escape"'
|
||||
_ = make([]int, len(ints)) // ERROR "make\(\[\]int, 6\) does not escape"
|
||||
_ = allocLenOf(ints) // ERROR "inlining call", "make\(\[\]int, 6\) does not escape"
|
||||
|
||||
_ = make([]int, 2, len(ints)) // ERROR "make\(\[\]int, 2, 6\) does not escape"
|
||||
_ = make([]int, len(ints), 2) // ERROR "make\(\[\]int, len\(ints\), 2\) does not escape"
|
||||
_ = make([]int, 10, len(ints)) // ERROR "make\(\[\]int, 10, 6\) does not escape"
|
||||
}
|
||||
|
||||
func allocLenOf(s []int) []int { // ERROR "can inline" "s does not escape"
|
||||
return make([]int, len(s)) // ERROR "escapes to heap"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user