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: use devirtualization in escape analysis #33160
Comments
It looks like the compiler does devirtualize all the calls in this function. The problem I think is that the devirtualization happens late in compilation, particularly after escape analysis. So even though the calls are devirtualized, during escape analysis they are still interface calls and cause their arguments to escape. We need earlier devirtualization to catch this. It shouldn't be hard, as inlining has already happened, so we just need some intraprocedural devirtualization as part of escape analysis. Maybe? |
I guess the question is do we just leave escape analysis in the front end and add this other analysis there as well? It would be a lot of work to move escape analysis into (a variant of) SSA, but that might be profitable. |
Yes, I think so. Phase ordering is kind of a fundamental problem in a compiler, this is just one instance of it. We're not going to solve phase ordering generally. But we can do some simple things in escape analysis to catch common cases like this issue. As well as this issue, inlining itself could use devirtualization. Right now none of the method calls on the result of |
A type tightening pass in the frontend seems reasonable to me. I'm assuming we just look for local, non-addrtaken variables of interface type, that are always assigned an OCONVIFACE expressions that were converted from the same concrete type. We can then change the local variable's type, eliminate those OCONVIFACEs, and add new ones as necessary to preserve type correctness. I agree that pushing this forward into inlining probably makes more sense than integrating it into escape analysis though. |
After playing with this a little, I realized this can't be done in the naive control/data-flow-insensitive way I suggested. Since interface-typed variables are always initialized to Maybe there's a slightly more sophisticated solution that (1) works well in practice, but (2) doesn't require a complete SSA analysis or equivalent reimplemented in the frontend. I think I'm leaning towards just continuing to move the frontend's post-typecheck code from Node to SSA; and once escape analysis is done on SSA, it should be easy to implement early de-virtualization. |
Change https://golang.org/cl/264837 mentions this issue: |
Change https://golang.org/cl/266199 mentions this issue: |
When inlining a function call "f()", if "f" contains exactly 1 "return" statement and doesn't name its result parameters, it's inlined to declare+initialize the result value using the AST representation that's compatible with staticValue. Also, extend staticValue to skip over OCONVNOP nodes (often introduced by inlining), and fix various bits of code related to handling method expressions. Updates #33160. Change-Id: If8652e319f0a5700cf9d40a7a62e369a2a359229 Reviewed-on: https://go-review.googlesource.com/c/go/+/266199 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Change https://golang.org/cl/266719 mentions this issue: |
In golang.org/cl/266199, I reused the existing code in inlining that recognizes anonymous variables. However, it turns out that code mistakenly recognizes anonymous return parameters as named when inlining a function from the same package. The issue is funcargs (which is only used for functions parsed from source) synthesizes ~r names for anonymous return parameters, but funcargs2 (which is only used for functions imported from export data) does not. This CL fixes the behavior so that anonymous return parameters are handled identically whether a function is inlined within the same package or across packages. It also adds a proper cross-package test case demonstrating #33160 is fixed in both cases. Change-Id: Iaa39a23f5666979a1f5ca6d09fc8c398e55b784c Reviewed-on: https://go-review.googlesource.com/c/go/+/266719 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> Trust: Matthew Dempsky <mdempsky@google.com>
#19361 introduced devirtualization when the concrete type is known statically. This would be extremely useful to compensate for the unfortunate design of the
hash.Hash
functions, which make it impossible not to make the input escape.However, it looks like it doesn't figure out the sha256.New return value, even if that function gets inlined.
If there is some tweak that can be made in the sha256 package to make this work, I'm happy to make this change, otherwise it would be nice to extend the optimization.
/cc @randall77
The text was updated successfully, but these errors were encountered: