5.10: [OSSALifetimeCompletion] Handle unavailable blocks in dead-end regions. #68997
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.
Description: Fix overconsume on unreachable-terminated paths by handling conditional availability of values in dead-end regions in lifetime completion.
The function
OSSALifetimeCompletion::visitUnreachableLifetimeEnds
is used (1) to complete OSSA lifetimes and--while OSSA lifetime completion remains disabled--(2) to canonicalize lexical OSSA lifetimes. The function visits the instructions at which the lifetime implicitly ends--implicitly because with incomplete lifetimes, it's valid for a value not to be destroyed on paths that terminate inunreachable
.Previously, its determination for those ends was incorrect in the face of unavailable blocks in dead-end regions. Specifically, it simply walked forward from the non-lifetime-ending boundary until finding
unreachable
instructions. (Suchunreachable
instructions are guaranteed to exist because the lifetime is "partially complete" by precondition.) That walk alone is insufficient, however: It's possible that the value isn't available at thoseunreachable
instructions. For example, if a value isn't destroyed on one path to the unreachable but is destroyed on another path to it, then the value isn't available at the unreachable. Inserting a destroy at theunreachable
would result in an overconsume on the path on which the value was destroyed.Here, the determination is fixed by computing availability within the region discovered by that initial walk. This is done via a forward iterative dataflow within the region, propagating availability. The visited instructions are then the terminators of the last blocks in the region in which the value is available. In the preceeding example, rather than visiting the
unreachable
instruction, the terminator of the last block on the path to it where the value has not yet been destroyed would be visited.Risk: Low. The fix uses a well-known dataflow implementation to propagate availability.
Scope: Narrow. Only affects lifetimes in dead end blocks.
Original PR: #68975
Reviewed By: Andrew Trick ( @atrick )
Testing: Added tests.
Resolves: rdar://116255254