aboutsummaryrefslogtreecommitdiff
path: root/test/escape_closure.go
AgeCommit message (Collapse)Author
2023-08-17cmd/compile/internal/escape: optimize indirect closure callsMatthew Dempsky
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>
2021-05-26[dev.typeparams] cmd/compile: simplify ~r/~b namingMatthew Dempsky
The compiler renames anonymous and blank result parameters to ~rN or ~bN, but the current semantics for computing N are rather annoying and difficult to reproduce cleanly. They also lead to difficult to read escape analysis results in tests. This CL changes N to always be calculated as the parameter's index within the function's result parameter tuple. E.g., if a function has a single result, it will now always be named "~r0". The normative change to this CL is fairly simple, but it requires updating a lot of test expectations. Change-Id: I58a3c94de00cb822cb94efe52d115531193c993c Reviewed-on: https://go-review.googlesource.com/c/go/+/323010 Trust: Matthew Dempsky <mdempsky@google.com> Trust: Dan Scales <danscales@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
2020-10-15cmd/compile: improve escape analysis of known callsMatthew Dempsky
Escape analysis is currently very naive about identifying calls to known functions: it only recognizes direct calls to a declared function, or direct calls to a closure. This CL adds a new "staticValue" helper function that can trace back through local variables that were initialized and never reassigned based on a similar optimization already used by inlining. (And to be used by inlining in a followup CL.) Updates #41474. Change-Id: I8204fd3b1e150ab77a27f583985cf099a8572b2e Reviewed-on: https://go-review.googlesource.com/c/go/+/256458 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com>
2019-09-16cmd/compile: trim function name prefix from escape diagnosticsMatthew Dempsky
This information is redundant with the position information already provided. Also, no other -m diagnostics print out function name. While here, report parameter leak diagnostics against the parameter declaration position rather than the function, and use Warnl for "moved to heap" messages. Test cases updated programmatically by removing the first word from every "no match for" error emitted by run.go: go run run.go |& \ sed -E -n 's/^(.*):(.*): no match for `([^ ]* (.*))` in:$/\1!\2!\3!\4/p' | \ while IFS='!' read -r fn line before after; do before=$(echo "$before" | sed 's/[.[\*^$()+?{|]/\\&/g') after=$(echo "$after" | sed -E 's/(\&|\\)/\\&/g') fn=$(find . -name "${fn}" | head -1) sed -i -E -e "${line}s/\"${before}\"/\"${after}\"/" "${fn}" done Passes toolstash-check. Change-Id: I6e02486b1409e4a8dbb2b9b816d22095835426b5 Reviewed-on: https://go-review.googlesource.com/c/go/+/195040 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
2019-09-03cmd/compile: silence esc diagnostics about directiface OCONVIFACEsMatthew Dempsky
In general, a conversion to interface type may require values to be boxed, which in turn necessitates escape analysis to determine whether the boxed representation can be stack allocated. However, esc.go used to unconditionally print escape analysis decisions about OCONVIFACE, even for conversions that don't require boxing (e.g., pointers, channels, maps, functions). For test compatibility with esc.go, escape.go similarly printed these useless diagnostics. This CL removes the diagnostics, and updates test expectations accordingly. Change-Id: I97c57a4a08e44d265bba516c78426ff4f2bf1e12 Reviewed-on: https://go-review.googlesource.com/c/go/+/192697 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
2019-08-28test: remove -newescape from regress testsMatthew Dempsky
Prep for subsequent CLs to remove old escape analysis pass. This CL removes -newescape=true from tests that use it, and deletes tests that use -newescape=false. (For history, see CL 170447.) Notably, this removes escape_because.go without any replacement, but this is being tracked by #31489. Change-Id: I6f6058d58fff2c5d210cb1d2713200cc9f501ca7 Reviewed-on: https://go-review.googlesource.com/c/go/+/187617 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
2019-04-16cmd/compile: update escape analysis tests for newescapeMatthew Dempsky
The new escape analysis implementation tries to emit debugging diagnostics that are compatible with the existing implementation, but there's a handful of cases that are easier to handle by updating the test expectations instead. For regress tests that need updating, the original file is copied to oldescapeXXX.go.go with -newescape=false added to the //errorcheck line, while the file is updated in place with -newescape=true and new test requirements. Notable test changes: 1) escape_because.go looks for a lot of detailed internal debugging messages that are fairly particular to how esc.go works and that I haven't attempted to port over to escape.go yet. 2) There are a lot of "leaking param: x to result ~r1 level=-1" messages for code like func(p *int) *T { return &T{p} } that were simply wrong. Here &T must be heap allocated unconditionally (because it's being returned); and since p is stored into it, p escapes unconditionally too. esc.go incorrectly reports that p escapes conditionally only if the returned pointer escaped. 3) esc.go used to print each "leaking param" analysis result as it discovered them, which could lead to redundant messages (e.g., that a param leaks at level=0 and level=1). escape.go instead prints everything at the end, once it knows the shortest path to each sink. 4) esc.go didn't precisely model direct-interface types, resulting in some values unnecessarily escaping to the heap when stored into non-escaping interface values. 5) For functions written in assembly, esc.go only printed "does not escape" messages, whereas escape.go prints "does not escape" or "leaking param" as appropriate, consistent with the behavior for functions written in Go. 6) 12 tests included "BAD" annotations identifying cases where esc.go was unnecessarily heap allocating something. These are all fixed by escape.go. Updates #23109. Change-Id: Iabc9eb14c94c9cadde3b183478d1fd54f013502f Reviewed-on: https://go-review.googlesource.com/c/go/+/170447 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
2019-04-02cmd/compile: skip escape analysis diagnostics for OADDRMatthew Dempsky
For most nodes (e.g., OPTRLIT, OMAKESLICE, OCONVIFACE), escape analysis prints "escapes to heap" or "does not escape" to indicate whether that node's allocation can be heap or stack allocated. These messages are also emitted for OADDR, even though OADDR does not actually allocate anything itself. Moreover, it's redundant because escape analysis already prints "moved to heap" diagnostics when an OADDR node like "&x" causes x to require heap allocation. Because OADDR nodes don't allocate memory, my escape analysis rewrite doesn't naturally emit the "escapes to heap" / "does not escape" diagnostics for them. It's also non-trivial to replicate the exact semantics esc.go uses for OADDR. Since there are so many of these messages, I'm disabling them in this CL by themselves. I modified esc.go to suppress the Warnl calls without any other behavior changes, and then used a shell script to automatically remove any ERROR messages mentioned by run.go in "missing error" or "no match for" lines. Fixes #16300. Updates #23109. Change-Id: I3993e2743c3ff83ccd0893f4e73b366ff8871a57 Reviewed-on: https://go-review.googlesource.com/c/go/+/170319 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com>
2017-02-15cmd/compile/internal/syntax: establish principled position informationRobert Griesemer
Until now, the parser set the position for each Node to the position of the first token belonging to that node. For compatibility with the now defunct gc parser, in many places that position information was modified when the gcCompat flag was set (which it was, by default). Furthermore, in some places, position information was not set at all. This change removes the gcCompat flag and all associated code, and sets position information for all nodes in a more principled way, as proposed by mdempsky (see #16943 for details). Specifically, the position of a node may not be at the very beginning of the respective production. For instance for an Operation `a + b`, the position associated with the node is the position of the `+`. Thus, for `a + b + c` we now get different positions for the two additions. This change does not pass toolstash -cmp because position information recorded in export data and pcline tables is different. There are no other functional changes. Added test suite testing the position of all nodes. Fixes #16943. Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c Reviewed-on: https://go-review.googlesource.com/37017 Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2016-05-02all: make copyright headers consistent with one space after periodEmmanuel Odeke
Follows suit with https://go-review.googlesource.com/#/c/20111. Generated by running $ grep -R 'Go Authors. All' * | cut -d":" -f1 | while read F;do perl -pi -e 's/Go Authors. All/Go Authors. All/g' $F;done The code in cmd/internal/unvendor wasn't changed. Fixes #15213 Change-Id: I4f235cee0a62ec435f9e8540a1ec08ae03b1a75f Reviewed-on: https://go-review.googlesource.com/21819 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-04-05cmd/compile: note escape of parts of closured-capture varsDavid Chase
Missed a case for closure calls (OCALLFUNC && indirect) in esc.go:esccall. Cleanup to runtime code for windows to more thoroughly hide a technical escape. Also made code pickier about failing to late non-optional kernel32.dll. Fixes #14409. Change-Id: Ie75486a2c8626c4583224e02e4872c2875f7bca5 Reviewed-on: https://go-review.googlesource.com/20102 Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2015-05-01cmd/internal/gc: improve flow of input params to output paramsDavid Chase
This includes the following information in the per-function summary: outK = paramJ encoded in outK bits for paramJ outK = *paramJ encoded in outK bits for paramJ heap = paramJ EscHeap heap = *paramJ EscContentEscapes Note that (currently) if the address of a parameter is taken and returned, necessarily a heap allocation occurred to contain that reference, and the heap can never refer to stack, therefore the parameter and everything downstream from it escapes to the heap. The per-function summary information now has a tuneable number of bits (2 is probably noticeably better than 1, 3 is likely overkill, but it is now easy to check and the -m debugging output includes information that allows you to figure out if more would be better.) A new test was added to check pointer flow through struct-typed and *struct-typed parameters and returns; some of these are sensitive to the number of summary bits, and ought to yield better results with a more competent escape analysis algorithm. Another new test checks (some) correctness with array parameters, results, and operations. The old analysis inferred a piece of plan9 runtime was non-escaping by counteracting overconservative analysis with buggy analysis; with the bug fixed, the result was too conservative (and it's not easy to fix in this framework) so the source code was tweaked to get the desired result. A test was added against the discovered bug. The escape analysis was further improved splitting the "level" into 3 parts, one tracking the conventional "level" and the other two computing the highest-level-suffix-from-copy, which is used to generally model the cancelling effect of indirection applied to address-of. With the improved escape analysis enabled, it was necessary to modify one of the runtime tests because it now attempts to allocate too much on the (small, fixed-size) G0 (system) stack and this failed the test. Compiling src/std after touching src/runtime/*.go with -m logging turned on shows 420 fewer heap allocation sites (10538 vs 10968). Profiling allocations in src/html/template with for i in {1..5} ; do go tool 6g -memprofile=mastx.${i}.prof -memprofilerate=1 *.go; go tool pprof -alloc_objects -text mastx.${i}.prof ; done showed a 15% reduction in allocations performed by the compiler. Update #3753 Update #4720 Fixes #10466 Change-Id: I0fd97d5f5ac527b45f49e2218d158a6e89951432 Reviewed-on: https://go-review.googlesource.com/8202 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
2015-03-28test: add tests for escape analysis of interface conversionsDmitry Vyukov
The false positives (var incorrectly escapes) are marked with BAD. Change-Id: If64fabb6ea96de44a1177d9ab12e2ccc579fe0c4 Reviewed-on: https://go-review.googlesource.com/5294 Reviewed-by: Keith Randall <khr@golang.org>
2015-03-28test: add tests for escape analysis of closure argumentsDmitry Vyukov
10 false positives (var incorrectly escapes to heap) are marked with BAD. Change-Id: I773b13a18ff55aaa499a2a28a979118422cc5322 Reviewed-on: https://go-review.googlesource.com/5293 Reviewed-by: Keith Randall <khr@golang.org>