-
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: inlining budget excludes cross-package calls #19261
Comments
Can you post a selfcontained reproducer? I see no Also if you compile with |
Sure, I will create a branch with the modification applied |
With the master branch using binary.BigEndian.Uint64, I get
By copying this function locally into load64, I get
Note that the tool does not report anymore if get64 is inlined or not, is it lost ? |
There was a missing diagnostic message for inlining with -m -m in Go 1.8. Tip should do a better job explaining why get64 was not inlined. At first glance (on my phone), this does look funky, though. |
On tip with binary.BigEndian.Uint64
On tip with load64
|
Here's a smaller reproducer:
|
Thanks! Will look. May take a day or three. |
Looks like for some reason the version that uses The only difference is that Leaving for josharian. |
It's more complex, in the following code, it's also a method and it doesn't work either
|
The cost being applied for the call of binary.bigEndian.Uint64 is currently 0, as opposed to the (correct) cost being applied of the call of load64, which is 59. Since the same thing does not happen for a method in the same package, I suspect that the problem is the importer/exporter. The relevant bit of code from inl.go: case OCALLMETH:
t := n.Left.Type
if t == nil {
Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
}
if t.Nname() == nil {
Fatalf("no function definition for [%p] %+v\n", t, t)
}
if inlfn := t.Nname().Func; inlfn.Inl.Len() != 0 {
*budget -= inlfn.InlCost
break
}
if Debug['l'] < 4 {
*reason = "non-leaf method"
return true
} In this case, And some lines above, we find this: // hack, TODO, check for better way to link method nodes back to the thing with the ->inl
// this is so export can find the body of a method
fn.Type.SetNname(n) I suspect that the exporter fails to record the InlCost attached in this roundabout way, or that the importer fails to restore it. I don't know whether the fix is to make the importer/exporter fully handle this hack, or to remove the hack. Over to you, @mdempsky or @griesemer. |
I don't think this issue is specific to methods. It's that we fail to set InlCost for imported functions/methods at all. |
Change https://golang.org/cl/70151 mentions this issue: |
Please answer these questions before submitting your issue. Thanks!
What did you do?
From https://github.com/bamiaux/iobit
I copied binary.BigEndian.Uint64 implementation, renamed it load64, and replaced the single call in Reader.get64 with the load64 function
What did you expect to see?
I expected no performance changes
What did you see instead?
Severe performance loss, every function using get64 is now not inlined while the code is strictly the same
Using go tool compile -m show that go now consider the get64 function not inlinable anymore
But the function from encoding.binary is inlinable
System details
The text was updated successfully, but these errors were encountered: