Evaluate the approx “code size” for the function body. Main parts of the inliner Decision making. Tells if function is inlineable in general or on a call site. Inlining algorithm and trade-offs handling. How inlining is performed and when it’s not supported. 1) 2) 3)
We almost have it... Mid-stack inlining (inlining of non-leaf calls) Still causes significant code bloating. But it gets better. https://golang.org/issue/19348
syntactical elements means higher cost. Sometimes one can re-write code so it has lower cost but operates in the same way. Cost is a function over syntax
looks like there are so many things to improve... Inlining dichotomy Yet, most of these paths lead to performance regressions. https://golang.org/issue/17566
_, x := range xs { // 90 for _, y := range ys { // 100 if x + y < 100 { // 90 f(x, y) // Won’t inline } // budget is 100 again } // budget is 90 again } // budget is 80 again
simple to implement, doesn’t make compilation slower, avoids code bloating. Pros & Cons The real benefits, apart from the microbenchmarks, are not apparent. It doesn’t seem to work.
int) int { return nonLeafCall(x) } // Inlineable with CL147361. // Functions with a single non-leaf call // inside bodies can be inlineable now. // This is a part of mid-stack enabling // work that is done by David Chase.
one arch, like AMD64, optimal inliner parameters can vary. Not to mention how different it is for the other arch (instruction cache is one of the concerns).
debug inliner decisions. $ go tool compile -m=2 foo.go cannot inline coldPathFunc: marked go:noinline Also works with “go build”: $ go build -gcflags='-m=2' foo.go