-
Notifications
You must be signed in to change notification settings - Fork 10.5k
EscapeAnalysis: make the use-point analysis more precise #28502
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
In canEscapeToUsePoint only check the content node if it's a reference (see comment why this is needed). For all other node types, especially addresses, handle defer edges by propagating use-point infomation backward in the graph. This makes escape analysis more precise with address types, e.g. don't consider an inout address to escape to an apply if just the loaded value is passed to an apply argument.
@swift-ci test |
@swift-ci benchmark |
Performance: -O
Code size: -O
Performance: -Osize
Code size: -Osize
Performance: -Onone
Code size: -swiftlibs
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
@eeckstein canEscapeTo makes assumptions in two directions: how the connection graph was built and how the API is used, so let's look at both... This PR assumes that CG nodes are all separate physical objects (from the perspective of SIL pointer conversion/casting/projections) except when the node corresponds to the properties of a class, in which case there is exactly one interior node. It might be possible to make that assumption here, it just isn't formalized in the representation (aside from the hasRC flag) or enforced, or even specified anywhere yet. Even if we prove that the graph is always built that way, we have to be sure that merging content nodes doesn't change the structure. If we get the same benefit without making such assumptions that's better because it's conceptually simpler and the escape analysis representation could be changed later without breaking things in confusing ways. In the other direction, this PR assumes that 'V' will always be a "reference type" when its mapped CGNode represents any memory that might be reachable from a reference. Given all the ways that addresses, raw pointers and references can be converted in SIL it's hard for me to be convinced that it's true. I think that at least requires more clarity on the alias analysis side to ensure that it can always "see through" all an object's interior pointers and never "sees past" a reference type back to a non-reference pointer or address. The the way I wanted to handle this case is just by making one obvious assumption in each direction:
But, there's a problem with that approach. The question is whether the problem is specific to my approach or whether I'm just exposing it. I think the alias analysis query just needs to be adjusted. I'll explain the issue there. |
Already handled with Andy's escape analysis changes |
In canEscapeToUsePoint only check the content node if it's a reference (see comment why this is needed).
For all other node types, especially addresses, handle defer edges by propagating use-point infomation backward in the graph.
This makes escape analysis more precise with address types, e.g. don't consider an inout address to escape to an apply if just the loaded value is passed to an apply argument.
This PR is a re-base and re-apply of #27667 after @atrick's escape analysis changes.