aboutsummaryrefslogtreecommitdiff
path: root/test/escape_closure.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2023-08-15 16:45:52 -0700
committerGopher Robot <gobot@golang.org>2023-08-17 16:36:09 +0000
commitff47dd1d665d30d5f3d26f031192afebb4422c3c (patch)
treeb688caf64d48a7c96cbce1e36ce10c865f8418d9 /test/escape_closure.go
parentf278ae61d551ebd12956a1ed21ad6131495a2513 (diff)
downloadgo-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/escape_closure.go')
-rw-r--r--test/escape_closure.go14
1 files changed, 14 insertions, 0 deletions
diff --git a/test/escape_closure.go b/test/escape_closure.go
index bd6c025476..0b19d6f6e8 100644
--- a/test/escape_closure.go
+++ b/test/escape_closure.go
@@ -177,3 +177,17 @@ func ClosureIndirect() {
}
func nopFunc(p *int) {} // ERROR "p does not escape"
+
+func ClosureIndirect2() {
+ f := func(p *int) *int { return p } // ERROR "leaking param: p to result ~r0 level=0" "func literal does not escape"
+
+ f(new(int)) // ERROR "new\(int\) does not escape"
+
+ g := f
+ g(new(int)) // ERROR "new\(int\) does not escape"
+
+ h := nopFunc2
+ h(new(int)) // ERROR "new\(int\) does not escape"
+}
+
+func nopFunc2(p *int) *int { return p } // ERROR "leaking param: p to result ~r0 level=0"