Skip to content

[OSSALifetimeCompletion] Handle unavailable blocks in dead-end regions. #68975

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 3 commits into from
Oct 5, 2023

Conversation

nate-chandler
Copy link
Contributor

@nate-chandler nate-chandler commented Oct 4, 2023

Not every block in a region which begins with the non-lifetime-ending boundary of a value and ending with unreachable-terminated blocks has the value available. If the unreachable-terminated blocks in this boundary are not available, it is incorrect to insert destroys of the value in them: it is an overconsume on some paths. Previously, however, destroys were simply being inserted at the unreachable.

Here, this is fixed by finding the boundary of availability within that region and inserting destroys before the terminators of the blocks on that boundary.

rdar://116255254

OSSALifetimeCompletion needs to insert not at unreachable instructions
that appear after the non-lifetime-ending boundary of a value but rather
at the terminators of the availability boundary of the value within that
region.  Once it does so, it will no longer be sufficient to check
whether the insertion point is an unreachable because such terminators
may be another terminator that appears on the availability boundary.
Prepare for that by recording the instructions that were found and
checking whether the destroy insertion point is such an instruction
before bailing rather than specifically checking for `unreachable`.
Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The forward data flow looks great. Thanks. This was a big missing OSSA piece.

@@ -1858,8 +1858,7 @@ right:
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @owned $C):
// CHECK: cond_br undef, [[BB1:bb[0-9]+]], [[BB4:bb[0-9]+]]
// CHECK: [[BB1]]:
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why this change eliminated a copy in mem2reg.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This copy was incorrectly introduced in https://github.com/apple/swift/pull/68608/files#diff-8bd51ca385c836620fb33d8b5480d0ab38024c0ba38f83aa599f0a5148c48e7fR1861 . It was introduced because the unreachable instruction was added to liveness although the value is not available at it. This is fixed here by not adding unavailable terminators to liveness.

@@ -409,6 +421,10 @@ class CanonicalizeOSSALifetime final {
void recordConsumingUser(SILInstruction *user) {
consumingBlocks.insert(user->getParent());
}
void recordUnreachableLifetimeEnd(SILInstruction *user) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the definition of consumingBlocks and recordConsumingUser we should comment that these are either the points where the original value was consumed or was available at an unreachable instruction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Not every block in a region which begins with the non-lifetime-ending
boundary of a value and ending with unreachable-terminated blocks has
the value available.  If the unreachable-terminated blocks in this
boundary are not available, it is incorrect to insert destroys of the
value in them: it is an overconsume on some paths.  Previously,
however, destroys were simply being inserted at the unreachable.

Here, this is fixed by finding the boundary of availability within that
region and inserting destroys before the terminators of the blocks on
that boundary.

rdar://116255254
@nate-chandler nate-chandler marked this pull request as ready for review October 5, 2023 16:16
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@meg-gupta
Copy link
Contributor

thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants