-
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: notice when function variables are never reassigned, avoid indirect calls #42569
Comments
We do this at function scope, but not currently for method values like
It shouldn't be hard to teach the inliner that Doing this with package-block variables is trickier. It wouldn't be hard to check for variables that are never reassigned within the package's Go source, but things like |
As an alternative to restricting
could be rewritten as
Obviously that specific syntax can't be used today as function addresses are not directly comparable, but this is allowed and basically equivalent:
|
We could track “is modified” state for both top level vars and linknamed vars and have the linker fail if there’s a mismatch. |
@CAFxX, wouldn't that approach waste branch-predictor resources? |
Yeah, I think we definitely have options for emitting metadata that the linker can then use to complain if things look suspicious. E.g., maybe we could use the new linker ABI stuff to emit symbols under a new ABI if the compiler is making new assumptions about how they can be used. But I think that still depends on us carving out when exactly the Go compiler is allowed to assume it sees all direct uses of a variable. There are certainly other package-wide optimizations we could do if we were allowed to make assumptions like this. |
The language spec is pretty explicit about that, is it not?
I will admit that I don't know what all |
Yes, "Standard Go" specifies that. But "gc Go" specifically provides IIRC, cmd/link's -X flag can also be used to initialize unexported variables, also in contradiction to the spec wording.
I agree that I think most, if not all, use of |
Yes, at least in the non-constant case. And I also agree it would be ideal to implement a smarter solution. Just wanted to add that technique for completeness since it is not uncommon. Also consider that while it's true we'd be using more branch predictor resources (due to the extra |
It's somewhat common for people to have package-level variables like:
So later in their code they can just write
u64(buf[8:])
many times without stuttering a loudbinary.BigEndian.Uint64
etc all over the page.But calling via such a func variable is ~7.5x slower than calling
binary.BigEndian.Uint64
directly: https://play.golang.org/p/eccPzwCSvfiIt'd be nice if the compiler noticed that the
u64
variable was only initialized once and never reassigned to and never had its address taken (so it can't be mutated elsewhere), and did the fast thing automatically, not doing the indirect call./cc @randall77 @mdempsky @ianlancetaylor @cherrymui @josharian @danderson
The text was updated successfully, but these errors were encountered: