-
Notifications
You must be signed in to change notification settings - Fork 3.1k
SI-6723 Don't count @inline
methods when computing the inline budget
#4041
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
Conversation
@@ -0,0 +1 @@ | |||
-optimize -Xfatal-warnings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you also intend to have -Yinline-warnings
enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessary, there's a one-line warning: there were 16 inliner warnings; re-run with -Yinline-warnings for details
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay.
Perhaps it would be more self documenting of the tests intent though? Alternatively, add comment to the test (e.g. "should not create inliner warnings")
Otherwise the inlining budged exceeds when many `@inline` methods are invoked. This triggers inline warnings for those that aren't inlined anymore.
added |
Here's a bytecode diff of http://rawgit.com/retronym/6e6b2899c02be2918afe/raw/out.html (Load into Sublime and set the syntax mode to diff for easier reading) We should take a look at this to get a feeling for the risk of this change (will over-inlining hurt some performance somewhere?) /cc @Ichoran To create these:
|
That diff suggests that the bytecode for scala-library was unchanged. Maybe that's right, but please feel free to reproduce these results to see if I've messed up the comparison.
|
An extensive scientific study under my supervision could not show any performance regression in the following use case. Both compilers were built with
|
@retronym, shall we merge or delay? |
I'll merge the last 2.11.5 PRs my Monday morning, if they have been LGTM'ed by then. |
Is there a possibility for infinite expansion with this patch? I.e. what happens to final class Foo {
@inline def bar(x: Int): Int = if (x <= 0) x else baz(x)-1
@inline def baz(x: Int): Int = if (x >= 100) 100 else bar(x)
def quux = bar(101)
} Other than infinite recursive inlining (or exceeding maximum method bytecode size), I wouldn't worry about over-inlining @inlined methods. In particular, you want a chain of forwarders 100 deep to all disappear. |
Ugh, thanks for pointing that out. Indeed the example causes an infinite loop. Another problem with skipping the budged is unlimited exponential expansion: final class Foo {
@inline def a: Int = 1
@inline def b: Int = a + a
@inline def c: Int = b + b
@inline def d: Int = c + c
def e: Int = d + d // 16 times the body of a
} Maybe a better solution than counting the number of inlines would be to limit the size / growth of the target method. |
@lrytz - I am not sure that it is wrong to have exponential expansion if people really annotate things to be inlined that way. I like the idea of instead limiting the size of the target method (probably with multiple thresholds: don't exceed max method size, don't expand total size of the method more than X, don't expand any individual function call more than Y (note that inlining could actually shrink the size if it allows you to skip boxing)). |
:) |
@lrytz I'm going to close this one, please reopen when we find a way past the infinite inlining problem and have a grip on the not-quite-infinite-but-still-worryingly-large inlining problem. |
I've been taking a cursory look at the inliner in OpenJDK's C1 compiler. I spotted a few things that are relevant to this PR. They also have an annotation to force inlining of a method: This forced inlining is yoked with MaxForceInlineLevel |
Otherwise the inlining budged exceeds when many
@inline
methods areinvoked. This triggers inline warnings for those that aren't inlined
anymore.