-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: eliminate runtime.conv* calls with unused results #22971
Comments
I suspect "certain cases" == "when the function is not inlined". Variadic functions ( |
@ALTree I'm not familiar with inline expansion rules of the Go compiler. Here's what I did, to see if inline expansion mechanism worked on the code above. I've changed the func debug(data string) {
fmt.Println(string)
} I expected to see the call to the
I guess inline expansion is not happening here due to variadic nature of In case when the func debug(data string) {
data = data + "123"
} I see inline expansion happening, though the noop.go:6 0x6cd e800000000 CALL 0x6d2 [1:5]R_CALL:runtime.concatstring2
noop.go:15 0x6d2 e800000000 CALL 0x6d7 [1:5]R_CALL:%22%22.op |
Then debug won’t be a leaf function as it calls the complex fmt.Println. This is being worked ok, search for mid stack inlining, but afaik is not enabled at the moment.
… On 3 Dec 2017, at 04:30, pavel ***@***.***> wrote:
@ALTree I'm not familiar with inline expansion rules of the Go compiler.
Here's what I did, to see if inline expansion mechanism worked on the code above.
I've changed the debug function to be:
func debug(data string) {
fmt.Println(string)
}
I expected to see the call to the debug function to be inlined after compilation, but looking at objdump output it does not seem to be the case on my environment.
noop.go:14 0x640 e800000000 CALL 0x645 [1:5]R_CALL:%22%22.debug
noop.go:15 0x645 e800000000 CALL 0x64a [1:5]R_CALL:%22%22.op
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@pavel as Dave pointed out, it's a different issue.
vs
The former function is variadic, the latter isn't. The former has an empty body, the latter doesn't. It's still not clear to me what issue you are reporting here. Is that we don't inline variadic functions? That we don't inline nonleaf functions? We already have issues for those things, and work has been done to fix them (for example inlining nonleafs). Or is this just about you wanting to understand inlining rules? |
@ALTree Sorry, I've deviated with this inline expansion comments of mine. Discard all my comments regarding inline expansion. My issue is described in the title and my first comment (i.e. compiler does not remove functions with empty body and calls to them). |
FTR: Empty function body is not a sufficient condition for eliminating the call. |
At tip, the no-op function now is indeed elided:
There is no call to So this is fixed? |
https://go-review.googlesource.com/100456 is the fix. |
I wonder if this is working as expected. When I add a couple of more arguments to the call to
here's my modified code:
|
Ok, this is not fully resolved. Thanks, @mirtchovski. |
How hard would it be to do purity optimizations for known-pure runtime functions like |
@aclements I suspect it could be done pretty easily in this special case with a generic rewrite rule that checks for conv functions with unused results and eliminates them. The rewrite rule will be awkward, but that's nothing new. |
Punting to 1.13, too late for anything major in 1.12. |
This bug, as currently specified, was actually fixed when @mdempsky enabled his new escape analysis algorithm. The reason that the runtime.conv* calls were created in the first place was because (I think) the old escape analysis algorithm was not proving that the arguments to debug() were not escaping, probably related to the variadic function call. With the new escape analysis in place, the runtime.conv* routines are not generated. All the args are created on the stack, and therefore all operations related to the debug function call can be and are dead-coded. I think we probably just want to close this bug. We could create a new bug or proposal for the more general case of understanding when functions (like runtime.conv* or user functions) have no side effects, and optimizing/removing when their results are not used. Here's an example of a function where the compiler could get rid of the purefunc() call, after inlining inlinedfunc() and doing constant propagation, etc, but currently purefunc() remains in the code (of course, since the compiler doesn't record that purefunc has no side effects):
|
What version of Go are you using (
go version
)?go version go1.9.2 linux/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?linux/amd64
What did you do?
I'm using the following file (
noop.go
):I compile the file using:
go tool compile noop.go
.Then I inspect the object file using:
go tool objdump noop.o
.What did you expect to see?
Ideally I expect to see no traces of the
debug
function.In a non-ideal, but a good outcome I expect to see no calls to the
debug
function.What did you see instead?
A call to the
debug
function.Additional information
If I replace signature of the
debug
function to:I get the "good" scenarion:
debug
function is presentdebug
function existThe text was updated successfully, but these errors were encountered: