Skip to content

[move-only] Batched resilient changes #65842

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 5 commits into from
May 11, 2023

Conversation

gottesmm
Copy link
Contributor

In this PR, I include 3 small batched changes that fix some of the issues we are seeing with resilience. Specifically:

  1. I discovered that a resilient struct's deinit was having its self argument to the deinit created as an object despite the SILFunctionType having an @in argument.
  2. I fixed the move checker to understand how to check a resilient function argument that is concrete within the function implementation. The issue was that we were adding a load_borrow and then performing normal codegen. I just needed to teach the checker to understand how to handle the load_borrow.
  3. I fixed the emission when we were passing a concrete type in a module to a resilient function that took it as a borrowed in_guaranteed. To do this, I just changed it to use a store_borrow.

gottesmm added 3 commits May 10, 2023 14:11
… an address argument instead of an object.

The signature was already correct, just the logic in the deinit code assumed
that we would always have an object.

rdar://109170069
… resilient guaranteed arguments.

The only difference from normal concrete guaranteed parameter emission is we
have a load_borrow on the argument before the copy_value. That is instead of:

```
bb0(%0 : @guaranteed $Type):
  %1 = copy_value %0
  %2 = mark_must_check [no_consume_or_assign] %1
```

we have,

```
bb0(%0 : $*Type): // in_guaranteed
  %1 = load_borrow %0
  %2 = copy_value %1
  %3 = mark_must_check [no_consume_or_assign] %2
```

So I just needed to update the checker to recognize that pattern.

This is tested by just making sure that the checker can handle the borrowVal in
the tests without emitting an error.

rdar://109170906
…ow if we call a resilient function that takes it in_guaranteed.

This ensures that given a class that contains a noncopyable type that contains
another noncopyable type:

```
@_moveOnly struct S2 {}
@_moveOnly struct S { var s2: S2 }
class C { var s: S }
```

if we call a resilient function that takes C.S.S2:

```
borrowVal(c.s.s2)
```

we properly spill s2 onto the stack using a store_borrow.

Why Do This?
------------

Currently SILGenLValue treats ref_element_addr as a base that it needs to load
from for both copyable and non-copyable types. We keep a separation of concerns
and require emission of resilient functions to handle these loaded values. For
copyable types this means copying the value and storing it into a temporary
stack allocation. For noncopyable types, we never actually implemented this so
we would hit an error in SILGenApply telling us that our resilient function
expected an address argument, but we are passing an object.

To work around this, I updated how we emit borrowed lvalue arguments to in this
case to spill the value into a temporary allocation using a store_borrow. I also
included a test that validates that we properly have a read exclusivity scope
around the original loaded from memory for the entire call site so even though
we are performing a load_borrow and then spilling it, we still have read
exclusivity to the original memory for the entire region meaning that we still
preserve the semantics.

rdar://109171001
@gottesmm gottesmm requested review from jckarter and kavon May 10, 2023 21:16
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

I hit a weird bug where for some reason it wasn't working. I can't reproduce it
now, so it makes sense to use the correct syntax.
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

…e_borrow if we are using lowered addresses.

When opaque values are enabled, we do not need this store_borrow. This was
caught by the following tests:

  Swift(macosx-x86_64) :: SILGen/opaque_values_silgen.swift
  Swift(macosx-x86_64) :: SILGen/opaque_values_silgen_resilient.swift
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

@gottesmm gottesmm merged commit 5b5b55f into swiftlang:main May 11, 2023
@gottesmm gottesmm deleted the more-resilient-stuff branch May 11, 2023 22:48
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