diff options
author | Matthew Dempsky <mdempsky@google.com> | 2023-08-15 16:45:52 -0700 |
---|---|---|
committer | Gopher Robot <gobot@golang.org> | 2023-08-17 16:36:09 +0000 |
commit | ff47dd1d665d30d5f3d26f031192afebb4422c3c (patch) | |
tree | b688caf64d48a7c96cbce1e36ce10c865f8418d9 /test/inline_big.go | |
parent | f278ae61d551ebd12956a1ed21ad6131495a2513 (diff) | |
download | go-ff47dd1d665d30d5f3d26f031192afebb4422c3c.tar.gz go-ff47dd1d665d30d5f3d26f031192afebb4422c3c.zip |
cmd/compile/internal/escape: optimize indirect closure calls
This CL extends escape analysis in two ways.
First, we already optimize directly called closures. For example,
given:
var x int // already stack allocated today
p := func() *int { return &x }()
we don't need to move x to the heap, because we can statically track
where &x flows. This CL extends the same idea to work for indirectly
called closures too, as long as we know everywhere that they're
called. For example:
var x int // stack allocated after this CL
f := func() *int { return &x }
p := f()
This will allow a subsequent CL to move the generation of go/defer
wrappers earlier.
Second, this CL adds tracking to detect when pointer values flow to
the pointee operand of an indirect assignment statement (i.e., flows
to p in "*p = x") or to builtins that modify memory (append, copy,
clear). This isn't utilized in the current CL, but a subsequent CL
will make use of it to better optimize string->[]byte conversions.
Updates #2205.
Change-Id: I610f9c531e135129c947684833e288ce64406f35
Reviewed-on: https://go-review.googlesource.com/c/go/+/520259
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'test/inline_big.go')
-rw-r--r-- | test/inline_big.go | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/test/inline_big.go b/test/inline_big.go index 7dd1abdb6a..f579fc0910 100644 --- a/test/inline_big.go +++ b/test/inline_big.go @@ -9,18 +9,18 @@ package foo -func small(a []int) int { // ERROR "can inline small with cost .* as:.*" "a does not escape" +func small(a []int) int { // ERROR "can inline small with cost .* as:.*" "a does not escape" "does not mutate param: a" "does not call param: a" // Cost 16 body (need cost < 20). // See cmd/compile/internal/gc/inl.go:inlineBigFunction* return a[0] + a[1] + a[2] + a[3] } -func medium(a []int) int { // ERROR "can inline medium with cost .* as:.*" "a does not escape" +func medium(a []int) int { // ERROR "can inline medium with cost .* as:.*" "a does not escape" "does not mutate param: a" "does not call param: a" // Cost 32 body (need cost > 20 and cost < 80). // See cmd/compile/internal/gc/inl.go:inlineBigFunction* return a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] } -func f(a []int) int { // ERROR "cannot inline f:.*" "a does not escape" "function f considered 'big'" +func f(a []int) int { // ERROR "cannot inline f:.*" "a does not escape" "function f considered 'big'" "mutates param: a derefs=0" "does not call param: a" // Add lots of nodes to f's body. We need >5000. // See cmd/compile/internal/gc/inl.go:inlineBigFunction* a[0] = 0 |