Skip to content

[NFC] Add SILGenCleanup::completeOSSLifetimes #64022

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 10 commits into from
Mar 2, 2023

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Mar 2, 2023

Presently under -enable-ossa-complete-lifetimes.

This allows SILGen to skip OSSA cleanups, for example at dead-end
blocks.

Long term, we may remove OSSA cleanups from SILGen entirely (except
for lexical borrow scopes). This changes lets us experiment with that
option.

atrick added 10 commits March 1, 2023 18:29
Add local lifetime-ending operations to any owned or borrowed value.

This puts a single value into valid OSSA form so that linear lifetime
checking will pass.

Also adds UnreachableLifetimeCompletion which fixes OSSA after
converting a code path to unreachable (e.g. DiagnoseUnreachable and MandatoryInlining).
Disabled by default during initial testing.
Add a separate 'verifyOwnership()' entry point so it's possible
to check OSSA lifetimes at various points.

Move SILGenCleanup into a SILGen pass pipeline.

After SILGen, verify incomplete OSSA.

After SILGenCleanup, verify ownership.
Use DeadEndBlocks to ignore missing end-borrows and destroys.

Allow SILGen to be as sloppy as it wants with OSSA cleanups.
Presently under -enable-ossa-complete-lifetimes.

This allows SILGen to skip OSSA cleanups, for example at dead-end
blocks.

Long term, we may remove OSSA cleanups from SILGen entirely (except
for lexical borrow scopes). This changes lets us experiment with that
option.
@atrick
Copy link
Contributor Author

atrick commented Mar 2, 2023

@swift-ci test

@atrick
Copy link
Contributor Author

atrick commented Mar 2, 2023

@swift-ci test

@atrick
Copy link
Contributor Author

atrick commented Mar 2, 2023

@swift-ci smoke test

@atrick
Copy link
Contributor Author

atrick commented Mar 2, 2023

PR testing is blocked by

Reflection/Sources/_Runtime/Utils/PtrAuth.swift:201:7: error: cannot convert value of type 'UInt64' to expected argument type 'Builtin.Int64'
      UInt64(Builtin.typePtrAuthDiscriminator(
      ^

@atrick atrick requested a review from gottesmm March 2, 2023 16:53
@atrick atrick merged commit bffe0e7 into swiftlang:main Mar 2, 2023
@atrick atrick deleted the ossa-complete-util branch March 2, 2023 16:54
Copy link
Contributor

@nate-chandler nate-chandler left a comment

Choose a reason for hiding this comment

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

LGTM!

/// Interior liveness handles the following cases naturally:
///
/// When completing the lifetime if the initial value, %v1, transitively
/// include all dominated reborrows. %phi1 in this example:
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: includes

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 in #64051


static SILInstruction *endOSSALifetime(SILValue value, SILBuilder &builder) {
auto loc =
RegularLocation::getAutoGeneratedLocation(builder.getInsertionPointLoc());
Copy link
Contributor

Choose a reason for hiding this comment

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

CleanupLocation(RegularLocation::...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We use RegularLocation::getAutoGeneratedLocation everywhere for compiler-generated destroys. I really don't know if CleanupLocation will work once we move the destroy somewhere else. CleanupLocation seems to be for proper cleanups generated by the frontend. (@adrian-prantl ). At any rate, if we're doing it wrong, we should probably change our approach everywhere. Until then, I'll be consistent.

Copy link
Contributor

@nate-chandler nate-chandler Mar 3, 2023

Choose a reason for hiding this comment

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

It looks like everywhere that's done we may run afoul of the debug scope hole checking. The code that checks for them https://github.com/apple/swift/blob/main/lib/SIL/Verifier/SILVerifier.cpp#L6216-L6217

// lib/SIL/Verifier/SILVerifier.cpp:6216
if (SI.getLoc().getKind() == SILLocation::CleanupKind)
  continue;

does skip over instructions whose locations are cleanups but not those that are autogenerated. I've encountered this problem before: #62533 . More than once, actually: #40516 .

if CleanupLocation will work once we move the destroy somewhere else

To clarify, the suggestion is

CleanupLocation(RegularLocation::getAutoGeneratedLocation(builder.getInsertionPointLoc()))

which looks to have the same characteristics as RegularLocation::getAutoGeneratedLocation(builder.getInsertionPointLoc())--specifically, the autoGenerated field--but with the kind changed from RegularKind to CleanupKind.

Aside: if it turns out that creating a location that's both autogenerated and of cleanup kind is what we ought to be doing everywhere, a shorter spelling would be nice--like a getAutoGeneratedLocation on CleanupLocation.

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.

2 participants