Why does this function not inline ?

4,274 views
Skip to first unread message

Dave Cheney

unread,
Jan 5, 2012, 5:58:55 AM1/5/12
to golang-nuts
Hello,

Why does the min function not get inlined ?

% cat min.go
package main

import "fmt"

func min(a, b int) int {
if a < b {
return a
}
return b
}

func main() {
fmt.Println(min(5, 10))
}

% 8g -l -l min.go
%

Cheers

Dave

Johann Höchtl

unread,
Jan 5, 2012, 6:10:07 AM1/5/12
to golan...@googlegroups.com
Not implemented yet. AFAIK there is no inlining performed by the compiler.

roger peppe

unread,
Jan 5, 2012, 6:10:27 AM1/5/12
to Dave Cheney, golang-nuts

from CL 5400043:
"Cross- and intra package inlining of single assignments or return
<expression>."

i don't think if statements are there yet.

David Symonds

unread,
Jan 5, 2012, 6:11:21 AM1/5/12
to Dave Cheney, golang-nuts
The inliner is still primitive. This func will be inlined:

func min(a, b int) int {

return b
}


Dave.

Philipp Schumann

unread,
Jan 31, 2013, 1:00:47 AM1/31/13
to golan...@googlegroups.com, Dave Cheney
Hi everyone, it's been over a year: just curious, is the inliner *still* "still primitive" or has it progressed since this thread was created?

Dave Cheney

unread,
Jan 31, 2013, 1:12:40 AM1/31/13
to Philipp Schumann, golan...@googlegroups.com
The inliner has improved, along with escape analysis, but local variables and branches still prevent inlining. 

Have a read of cmd/gc/inl.c for some hints. 

Philipp Schumann

unread,
Jan 31, 2013, 2:21:39 AM1/31/13
to golan...@googlegroups.com, Philipp Schumann
Hmm, that's ... better, I guess  ;-)  gonna check out that source file in spite of my very limited C-ability...

Also wondering if this includes cross-package inlining?

Philipp Schumann

unread,
Jan 31, 2013, 2:25:37 AM1/31/13
to golan...@googlegroups.com, Philipp Schumann
And also wondering if "local variables" here includes the inlined-functions call args (including named or unnamed returns and receivers)?

Dave Cheney

unread,
Jan 31, 2013, 3:26:02 AM1/31/13
to Philipp Schumann, golan...@googlegroups.com, Philipp Schumann
Yes, exported functions can be inlined across package boundaries (Take that lto)
--
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...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Dave Cheney

unread,
Jan 31, 2013, 3:26:37 AM1/31/13
to Philipp Schumann, golan...@googlegroups.com, Philipp Schumann
I don't know, Minux, LVD or Remy will probably know 
--

Philipp Schumann

unread,
Jan 31, 2013, 6:56:33 AM1/31/13
to golan...@googlegroups.com, Philipp Schumann
Perfect, x-pkg inlining is a big win for me.

> I don't know, Minux, LVD or Remy will probably know

Here's hoping!  :)

Anthony Martin

unread,
Jan 31, 2013, 8:16:17 AM1/31/13
to Dave Cheney, Philipp Schumann, golan...@googlegroups.com
Dave Cheney <da...@cheney.net> once said:
> The inliner has improved, along with escape analysis, but local variables
> and branches still prevent inlining.

It can handle both of these as long as it's
with the inlining budget.

$ cat a.go
package main

func foo(a int) int {
b := a + 1
c := a - 1
return b * c
}

func bar(a int) int {
if a == 0 {
return -1
}
if a == 1 {
return 0
}
return (a+1)*(a-1)
}

func main() {
for i := 0; i < 10; i++ {
if foo(i) != bar(i) {
panic("math is hard")
}
}
}

$ go build -gcflags -m a.go
# command-line-arguments
./a.go:3: can inline foo
./a.go:9: can inline bar
./a.go:21: inlining call to foo
./a.go:21: inlining call to bar

Cheers,
Anthony

Philipp Schumann

unread,
Jan 31, 2013, 8:27:22 AM1/31/13
to golan...@googlegroups.com, Dave Cheney, Philipp Schumann
Oh this is neat! No idea what or how high the "budget" is in the current implementation, but I trust it is chosen wisely  =)

minux

unread,
Jan 31, 2013, 9:01:06 AM1/31/13
to Philipp Schumann, golan...@googlegroups.com, Dave Cheney
On Thu, Jan 31, 2013 at 9:27 PM, Philipp Schumann <philipp....@gmail.com> wrote:
Oh this is neat! No idea what or how high the "budget" is in the current implementation, but I trust it is chosen wisely  =)
by default, the inliner will try to inline leaf function (doesn't call other functions/method/interfaces)
that doesn't call panic or recover or select or switch or create closure or go/defer functions (see
example below) and which is less than 40 nodes when represented (roughly corresponding to 40
simple operations).
But please beware that this only describes the current status quo of the gc compiler, and it will
surely improve in the future. Thus please try not to depend on this.

you can view whether your function is eligible for inline by passing "-gcflags -m" to go build/install, etc.

all of the simple functions called by main in the following example is not currently inlinable.
package main

func dummy() {}

func NonLeafFunc() {
dummy()
}

func ClosureCreation() {
_ = func() {}
}

var x = []byte{0}

func RangeLoop() {
for _ = range x {
}
}

var ch chan struct{}

func Select() {
select {
case <-ch:
default:
}
}

func Switch() {
switch x[0] {
default:
case 0:
}
}

func Go() {
go dummy()
}

func Defer() {
defer dummy()
}

func LocalTypeDecl() {
type I int
}

func LocalConst() {
const e = 2.71828
}

func main() {
NonLeafFunc()
ClosureCreation()
RangeLoop()
Select()
Switch()
Go()
Defer()
LocalTypeDecl()
LocalConst()
}

Philipp Schumann

unread,
Jan 31, 2013, 9:16:53 AM1/31/13
to golan...@googlegroups.com, Philipp Schumann, Dave Cheney
That's the kind of detail I'm always hungry for... thanks!

Well most of these constraints are not a big issue... but the "doesn't call other functions" constraint kind of is. That's really unfortunate. That means LOTS of little maths functions that are combined in all kinds of permutations (vector stuff and such) don't  get inlined even though they would have been *ideal* candidates for inlining.

Well anyway, thanks for clearing that up!

Philipp Schumann

unread,
Jan 31, 2013, 9:19:10 AM1/31/13
to golan...@googlegroups.com, Philipp Schumann, Dave Cheney
I'm thinking... at least functions that only invoke "inlineable functions" should be themselves inlineable eventually if those other constraints aren't violated, no? Or would this slow down Go's fast compilation substantially?

John Asmuth

unread,
Jan 31, 2013, 9:34:28 AM1/31/13
to golan...@googlegroups.com, Philipp Schumann, Dave Cheney
I think that one motivation is that if the go compiler inlines a function, it will never ever affect a stack trace. If an inlined function *did* panic, it might be confusing to figure out the source of the error (since the stack doesn't correspond to the code).

minux

unread,
Jan 31, 2013, 11:09:35 AM1/31/13
to John Asmuth, golan...@googlegroups.com, Philipp Schumann, Dave Cheney
On Thu, Jan 31, 2013 at 10:34 PM, John Asmuth <jas...@gmail.com> wrote:
I think that one motivation is that if the go compiler inlines a function, it will never ever affect a stack trace. If an inlined function *did* panic, it might be confusing to figure out the source of the error (since the stack doesn't correspond to the code).
Yeah, this is reason behind that.

However, if we can adopt a modern debugging metadata standard like DWARF, this kind of issue
will become non-issue (for example, newer gdb is able to break at a function entry even the function
is inlined thanks to this capability).
btw, that will be an extremely big project, as i've heard that DWARF is a very complex standard.

Ian Lance Taylor

unread,
Jan 31, 2013, 2:08:44 PM1/31/13
to minux, John Asmuth, golan...@googlegroups.com, Philipp Schumann, Dave Cheney
On Thu, Jan 31, 2013 at 8:09 AM, minux <minu...@gmail.com> wrote:
>
> btw, that will be an extremely big project, as i've heard that DWARF is a
> very complex standard.

It's not all that bad. DWARF can support arbitrary complexity, but
that matters a lot more for a reader than for a writer.

(I recently implemented a DWARF reader that can, among other things,
track inlined functions in 3000 lines of C code (this only reads line
number and function call information, not type information).
http://gcc.gnu.org/viewcvs/trunk/libbacktrace/dwarf.c?revision=195620&view=markup
)

Ian

Maxim Khitrov

unread,
May 21, 2013, 1:57:57 PM5/21/13
to minux, John Asmuth, golan...@googlegroups.com, Philipp Schumann, Dave Cheney
On Thu, Jan 31, 2013 at 11:09 AM, minux <minu...@gmail.com> wrote:
>
> On Thu, Jan 31, 2013 at 10:34 PM, John Asmuth <jas...@gmail.com> wrote:
>>
>> I think that one motivation is that if the go compiler inlines a function,
>> it will never ever affect a stack trace. If an inlined function *did* panic,
>> it might be confusing to figure out the source of the error (since the stack
>> doesn't correspond to the code).
>
> Yeah, this is reason behind that.

Just ran into this very problem:

http://play.golang.org/p/H-pcjuhoFX

Figured out my error eventually, but it did require a bit of
head-scratching. Should there be an issue for this?

hen...@harmsen.se

unread,
Jan 29, 2014, 9:05:23 AM1/29/14
to golan...@googlegroups.com, Philipp Schumann, Dave Cheney
Just curious, can go inline functions defined in a different package?
Let's say I implement a vector math package and use in a 3d engine, would the compiler inline calls to the vector math functions?

-- Henrik

Aram Hăvărneanu

unread,
Jan 29, 2014, 2:21:10 PM1/29/14
to hen...@harmsen.se, golang-nuts, Philipp Schumann, Dave Cheney
On Wed, Jan 29, 2014 at 3:05 PM, <hen...@harmsen.se> wrote:
> Just curious, can go inline functions defined in a different package?

Yes.

>Let's say I implement a vector math package and use in a 3d engine,
> would the compiler inline calls to the vector math functions?

Maybe, maybe not. The inliner is still primitive.

--
Aram Hăvărneanu

Dave Cheney

unread,
Jan 29, 2014, 2:52:11 PM1/29/14
to hen...@harmsen.se, golang-nuts, Philipp Schumann
On Thu, Jan 30, 2014 at 1:05 AM, <hen...@harmsen.se> wrote:
Just curious, can go inline functions defined in a different package?
Let's say I implement a vector math package and use in a 3d engine, would the compiler inline calls to the vector math functions?

Yes, but only for small leaf functions.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages