Thanks for your clarification. I know about recursive inlining,
and you have to admit that if every function that F calls gets
inlined, then F becomes a leaf. With "non-leaf are not inlined"
I was referring to functions like the one OP posted

func foo { big_func() }

that are never inlined if big_func is not inlineable. But I agree
that that sentence, in general, it's not true.

On Tuesday, October 27, 2015 at 12:59:44 AM UTC+1, Carlos Castillo wrote:

Not true. The inliner can inline non-leaf functions. gcflags -m on
http://play.golang.org/p/jZede5GT1r shows:

./foo.go:13: can inline C
./foo.go:9: can inline B
./foo.go:10: inlining call to C
./foo.go:5: can inline A
./foo.go:6: inlining call to B
./foo.go:6: inlining call to C
./foo.go:18: inlining call to A
./foo.go:18: inlining call to B
./foo.go:18: inlining call to C
./foo.go:18: A() escapes to heap
./foo.go:18: main ... argument does not escape

Only C is a leaf function, yet A and B are also inlined according to the
output. The inliner likely has some improvents that can be made, as gcflags
-S shows the code still performing the operations at runtime (although that
might not be the final version of the machine code), but its definitely
collapsing all the calls down into main.

I believe it's the result of https://golang.org/cl/5952/, which allows
non-leaf functions to be inlined if all their children can themselves be
inlined, up to a limit.

On Saturday, October 24, 2015 at 1:55:27 PM UTC-7, alb.do...@gmail.com
At the moment, the inliner will never inline a non-leaf function.
This issue has been discussed in the past, see for example Josharian
comment here:


Il giorno sabato 24 ottobre 2015 22:24:39 UTC+2, tacod...@gmail.com ha
Are there plans to improve the inlining decision making of the compiler?
Or to explicitly state that a function should be inline (through a comment
right before the function for example)?

I'm in general pretty satisfied with the inline decisions, but there is
one case that could benefit inlining.
If a function solely (or almost solely) calls another non-inlinable
function, the "wrapping" function could be inline, even though the
non-inlinable function call within cannot.

func wrapper() { // make inline

For example I have a buffer implementation which occasionally needs to
read-in new data, but in 99% of the cases it just returns the content it
has cached. It looks something like:

func (b *Buffer) Peek(pos int) byte {
if pos > len(b.buf) {
return b.buf[pos]

This is called really often and could benefit from inlining (in my
particular case it would shave off at least 10% of total time).

Op zaterdag 24 oktober 2015 20:39:30 UTC+2 schreef Dave Cheney:
That makes sense then, the extra 500ms difference is the overhead of
512 << 20 function calls.

I've probably got my numbers wrong, but the overhead works out to be
less than a nanosecond per call.
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

Discussion Posts


Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 12 of 16 | next ›
Discussion Overview
groupgolang-nuts @
postedOct 24, '15 at 5:53p
activeOct 28, '15 at 3:27p



site design / logo © 2021 Grokbase