-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Unrevert EscapeAnalysis commits #28871
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Categorize three kinds of pointers: NoPointer (don't create a node) ReferenceOnly (safe to make normal assumptions) AnyPointer (may have addresses, rawpointers, or any mix of thoses with references) Flag ConnectionGraph nodes as - hasReferenceOnly - isInterior An interior node always has an additional content node. All sorts of arbitrary node merging is supported. Nodes with totally different properties can be safely merged. Interior nodes can safely be merged with their field content (which does happen surprisingly often). Alias analysis will use these flags to safely make assumptions about properties of the connection graph.
…ent node only. For alias analysis query to be generally correct, we need to effectively merge the escape state and use points for everything in a defer web. It was unclear from the current design whether the "escaping" property applied to the pointer value or its content. The implementation is inconsistent in how it was treated. It appears that some bugs have been worked around by propagating forward through defer edges, some have been worked around by querying the content instead of the pointer, and others have been worked around be creating fake use points at block arguments. If we always simply query the content for escape state and use points, then we never need to propagate along defer edges. The current code that propagates escape state along defer edges in one direction is simply incorrect from the perspective of alias analysis. One very attractive solution is to merge nodes eagerly without creating any defer edges, but that would be a much more radical change even than what I've done here. It would also pose some new issues: how to resolve the current "node types" when merging and how to deal with missing content nodes. This solution of applying escape state to content nodes solves all these problems without too radical of a change at the expense of eagerly creating content nodes. (The potential graph memory usage is not really an issue because it's possible to drastically shrink the size of the graph anyway in a future commit--I've been able to fit a node within one cache line). This solution nicely preserves graph structure which makes it easy to debug and relate to the IR. Eagerly creating content nodes also solves the missing content node problem. For example, when querying canEscapeTo, we need to know whether to look at the escape state for just the pointer value itself, or also for its content. It may be possible the its content node is actually part of the same object at the IR level. If the content node is missing, then we don't know if the object's interior address is not recognizable/representable or whether we simply never saw an access to the interior address. We can't simply look at whether the current IR value happens to be a reference, because that doesn't tell us whether the graph node may have been merged with a non-reference node or even with it's own content node. To be correct in general, this query would need to be extremely conservative. However, if content nodes are always created for references, then we only need to query the escape state of a pointer's content node. The content node's flag tells us if it's an interior node, in which case it will always point to another content node which also needs to be queried.
That appears to have been a partial workaround for the real problem that usepoints need to be propagated across the entire defer web. This is now solved by considering use points on the reference node's content, not the reference node itself.
Correctness: do not make any unenforced assumptions about how the connection graph is built (I don't think the previous assumption about the structure of the graph node mapped to a reference-type value would always hold if content nodes can be arbitrarily merged). Only make one assumption about the client code: the access being checked must be to some address within the provided value, not another object indirectly reachable from that value. Optimization: Allow escape analysis to prove that an addressable object does not escape even when one of its reference-type fields escapes.
Fix tests for changes to EscapeAnalysis output - New node flags - Only content nodes are marked escaping - Content nodes are eagerly created - No defer edges for block args
@swift-ci test |
@swift-ci test source compatibility |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is an obvious two line fix that I meant to get checked in before these commits were reverted. I'm including a SIL test case. It's unclear why source compat testing didn't catch the original PR.