Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: Escape analysis and liveness analysis do not interact well #12397

Closed
encryptio opened this issue Aug 29, 2015 · 3 comments
Closed

Comments

@encryptio
Copy link
Contributor

I'm writing some recursive code, and have been very careful to avoid allocations by being very nice to the escape analysis routines. However, I have some dead code in the source for debugging, whose body does cause escaping values if used (fmt and panic in my original code). The presence of the body of the debugging code, even though it is dead and removed by liveness analysis causes the escape analysis pass to consider the state to escape, forcing a heap allocation.

Here's a simplified example:

package recursiveescapebug

const debugMode = false

func A() int {
        b := 0
        B(&b, 5)
        return b
}

func B(state *int, recursions int) {
        switch recursions {
        case 0:
        default:
                *state++

                if debugMode {
                        // this is dead code, removed by the optimizer.
                        // however, its presence causes the compiler to consider B's state argument to escape.
                        panic(state)
                }

                B(state, recursions-1)
        }
}

When compiling this:

$ go build -gcflags='-live -m'
# _/home/username/testthing
./recursiveescapebug.go:11: leaking param: state
./recursiveescapebug.go:6: moved to heap: b
./recursiveescapebug.go:7: &b escapes to heap
./recursiveescapebug.go:7: live at call to B: &b
./recursiveescapebug.go:11: live at entry to B: state
./recursiveescapebug.go:23: live at call to B: state

Without the dead debug code in the source code, I see the escape analysis properly determines that state does not escape.

Happens with Go 1.5 and on a development version as of efeeee38 on x86_64/linux, but is likely not related to versions or platforms.

@bradfitz bradfitz added this to the Unplanned milestone Aug 29, 2015
@minux
Copy link
Member

minux commented Aug 30, 2015 via email

@gopherbot
Copy link

CL https://golang.org/cl/37508 mentions this issue.

@gopherbot
Copy link

Change https://golang.org/cl/54610 mentions this issue: test: add missing escape analysis test

gopherbot pushed a commit that referenced this issue Aug 11, 2017
https://golang.org/cl/37508 added an escape analysis test for #12397 to
escape2.go but missed to add it to escape2n.go. The comment at the top
of the former states that the latter should contain all the same tests
and the tests only differ in using -N to compile. Conform to this by
adding the function issue12397 to escape2n.go as well.

Also fix a whitespace difference in escape2.go, so the two files match
exactly (except for the comment at the top).

Change-Id: I3a09cf95169bf2150a25d6b4ec9e147265d36760
Reviewed-on: https://go-review.googlesource.com/54610
Reviewed-by: Avelino <t@avelino.xxx>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
@golang golang locked and limited conversation to collaborators Aug 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants