-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[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
Conversation
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`.
3fdab98
to
dcf8e68
Compare
dcf8e68
to
b3b4d38
Compare
There was a problem hiding this 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]] |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
b3b4d38
to
ad33b5d
Compare
@swift-ci please test |
thank you! |
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 theunreachable
-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 theunreachable
.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