]> Cypherpunks repositories - gostls13.git/commit
cmd/compile/internal/escape: make escape analysis -m=2 logs more accessible
authorthepudds <thepudds1460@gmail.com>
Wed, 21 May 2025 20:50:17 +0000 (16:50 -0400)
committerGopher Robot <gobot@golang.org>
Thu, 22 May 2025 02:02:51 +0000 (19:02 -0700)
commit8bf816ae6879fa4537cc6e6e292769df2d7dbb78
tree873e114e160b5d44f2b0146b24b5c7a35d26ce8b
parent83df0afc4e5c3719a6aca08a798460d38e78fc95
cmd/compile/internal/escape: make escape analysis -m=2 logs more accessible

This was the first CL in a series of CLs aimed at reducing
how often interface arguments escape for the print functions in fmt.

This CL makes some small improvements to the escape analysis logging.

Here is a sample snippet of the current -m=2 logs:

./print.go:587:7: parameter p leaks to {heap} with derefs=0:
./print.go:587:7:   flow: p = p:
./print.go:587:7:     from (*pp).printArg(p, err, 'v') (call parameter) at ./print.go:613:13
./print.go:587:7:   flow: p = p:
./print.go:587:7:     from (*pp).handleMethods(p, verb) (call parameter) at ./print.go:749:22
[..]

If we attempt to tease apart some reasons why the -m=2 logs can be
challenging to understand for the uninitiated:

- The "flow" lines are very useful, but contain more-or-less abstracted
pseudocode. The "from" lines most often use actual code. When first
looking at the logs, that distinction might not be apparent, which can
result in looking back to the original code to hunt for pseudocode
that doesn't exist there. (The log example shows 'p = p', but there is
no 'p = p' in the original source).

- Escape analysis can be most interesting with inlining, but that can
result in seeing overlapping short variable names (e.g., p, b, v...).

- The directionality of the "flow" lines might not be obvious,
including whether they build top-to-bottom or bottom-to-top.

- The use of '{' and '}' in the -m=2 logs somewhat intersects with Go
literals (e.g., if the log says "{temp}", an initial thought might
be that represents some temp inside of some Go literal).

- And of course, escape analysis itself is subtle.

This CL:

- Adds the function name to the first -m=2 line to provide more context
and reduce how often the reader needs to lookup line numbers.

- Uses the Unicode left arrow '←' rather than '=' on the flow lines
to make it clearer that these lines are abstracted away from the
original Go code and to help the directionality jump out.

In the future, we can consider changing "{heap}", "{temp}",
"{storage for foo}" to something else, but we leave them as is for now.

Two examples with the modifications:

./f1.go:3:9: parameter inptr leaks to outptr for func1 with derefs=0:
./f1.go:3:9:   flow: localptr ← inptr:
./f1.go:3:9:     from localptr := inptr (assign) at ./f1.go:4:11
./f1.go:3:9:   flow: outptr ← localptr:
./f1.go:3:9:     from return localptr (return) at ./f1.go:5:2

./b.go:14:20: []byte{...} escapes to heap in byteOrderExample:
./b.go:14:20:   flow: b ← &{storage for []byte{...}}:
./b.go:14:20:     from []byte{...} (spill) at ./byteorder.go:14:20
./b.go:14:20:     from b := []byte{...} (assign) at ./byteorder.go:14:11
./b.go:14:20:   flow: <heap> ← b:
./b.go:14:20:     from byteOrder.Uint32(b) (call parameter) at ./byteorder.go:15:32

These changes only affect the -m=2 output and leave the -m=1 output
as is.

Updates #8618
Updates #62653

Change-Id: Ic082a371c3d3fa0d8fd8bfbe4d64ec3e1e53c173
Reviewed-on: https://go-review.googlesource.com/c/go/+/524937
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/escape/graph.go
src/cmd/compile/internal/escape/solve.go
src/cmd/compile/internal/logopt/logopt_test.go