Commit Graph

759 Commits

Author SHA1 Message Date
Kavon Farvardin
0eb69d3f0c model the ABISafeConversionComponent as a translation component, rather than physical
Also renaming it to be UncheckedConversionComponent since it's a better name.

As a physical component, we'd run into problems in assignment statements.
The problem was that if we had something like:

```
SomeOtherComponent          // first component
GetterSetterComponent
ABISafeConversionComponent  // last component
```

When emitting the assignment, we always drill down through all but
the last component by calling `project()` on each one. Then on the last
component, we'd do the actual setting operation. But GetterSetterComponent
cannot be projected when the access is for writing.

So, to work around this I decided to model it as a TranslationComponent, because
those are specifically designed to be handled during an assignment by popping those
off the end of the component sequence, untranslating the value we're about to assign
as we go, until we hit the GetterSetterComponent.

By "untranslating" we're effectively putting Sendable back onto the set's argument
prior to calling set, because the underlying property's type still has `@Sendable`
on it (e.g., it's accessors still have that on its argument type). When
"translating" we're effectively taking Sendable off after reading it.

I think actually works really well and makes much more sense now.

resolves rdar://99619834
2022-09-13 13:07:21 -07:00
swift-ci
a66951aa3d Merge pull request #60521 from kavon/preconcurrency-var-access
Add missing function conversion for member access to preconcurrency vardecl.
2022-08-30 00:58:49 -07:00
Kavon Farvardin
6c24bc57cb [AST][SILGen] model ABI-safe casts of LValues
We needed a way to describe an ABI-safe cast of an address
representing an LValue to implement `@preconcurrency` and
its injection of casts during accesses of members.

This new AST node, `ABISafeConversionExpr` models what is
essentially an `unchecked_addr_cast` in SIL when accessing
the LVAlue.

As of now I simply implemented it and the verification of
the node for the concurrency needs to ensure that it's not
misused by accident. If it finds use outside of that,
feel free to update the verifier.
2022-08-29 20:58:26 -07:00
Doug Gregor
5191c315e1 Eliminate ImplicitActorHopTarget in favor of ActorIsolation.
The generalized ActorIsolation is enough to represent everything that
ImplicitActorHopTarget can do, and we were mapping between the two way
too often, so collapse them.
2022-08-23 23:19:46 -07:00
Michael Gottesman
6493886e1d [move-keyword] Wire up support for the move keyword in lvalue/rvalue emission.
I also updated the move function tests to show that this is working. As a nice
bonus, I was able to enable all of the tests also in a non-optimized stdlib.
2022-08-08 12:50:42 -07:00
Michael Gottesman
f1182a73da [no-implicit-copy] Remove auto +1 param signature change called by noimplicit copy in favor of following normal convention.
I also added a bunch of tests for both the trivial/non-trivial case as well as
some docs to SIL.rst.
2022-07-19 16:39:03 -07:00
Doug Gregor
bc8bd4ea60 Emit actor hop as part of call to the getter.
When emitting a call to the getter for storage, emit the actor hop (and
hop back) as part of the call itself, rather than around the whole
initialization. This address a bug involving initialization with an
optional binding in an `if let`, where the hop-back would only be
performed on the non-nil branch.

Fixes rdar://96487805 / FB10562197
2022-07-06 13:14:50 -07:00
Konrad `ktoso` Malawski
ef525424f6 Merge pull request #59700 from xedin/distributed-computed-properties-via-accessor-thunk
[Distributed] Implement distributed computed properties via special accessor
2022-06-30 16:04:36 +09:00
Pavel Yaskevich
2480c99dee [Distributed] Generate thunk for accessor as a regular method
It used to be an accessor but that is not required because
SILDeclRef controls mangling which is the most imprortant
and could be used to emit the right reference.
2022-06-29 17:57:58 -07:00
Pavel Yaskevich
59ec5ab552 [Distributed] SILGen: Remove isDistributed flags from accessor code 2022-06-29 14:49:10 -07:00
Pavel Yaskevich
e8987b4c3e [Distributed] Add a new access strategy - DispatchToDistributedThunk
This strategy is used to dispatch accesses to 'distributed' computed
property to distributed thunk accessor instead of a regular getter
when access happen outside actor isolation context.
2022-06-29 14:49:10 -07:00
Pavel Yaskevich
5bdf94f346 [Distributed] Remove commented out code and print statements 2022-06-29 14:49:10 -07:00
Konrad `ktoso` Malawski
febfef97d4 [Distributed] Skeleton implementation of distributed computed properties 2022-06-29 14:49:04 -07:00
Michael Gottesman
6a24087f90 Merge pull request #59611 from gottesmm/moveonly-rebase
[no-implicit-copy] Update SILGen/move checker to work with new patterns from copyable_to_moveonly and friends.
2022-06-28 13:45:15 -07:00
Konrad `ktoso` Malawski
6a2778645f Revert "Merge pull request #59481 from xedin/distributed-computed-properties"
This reverts commit 8125a85a8f, reversing
changes made to 728971c5b7.
2022-06-25 08:49:00 +09:00
Michael Gottesman
0d11e8ef69 [no-implicit-copy] Update SILGen/move checker to work with new patterns from copyable_to_moveonly and friends.
This involved doing the following:

1. Update the move only checker to look for new patterns.

2. Teach emitSemanticStore to use a moveonlywrapper_to_copyable to store moveonly
   values into memory. The various checkers will validate that this code is
   correct.

3. When emitting an apply, always unwrap move only variables. In the
   future, I am going to avoid this if a parameter is explicitly marked as also
   being moveonly (e.x.: @moveOnly parameter or @noEscape argument).

4. Convert from moveOnly -> copyable on return inst automatically in SILGen.

5. Fix SILGenLValue emission so we emit an error diagnostic later rather than
   crash. This is needed to keep SILGen emitting move only addresses (that is no
   implicit copy address only lets) in a form that the move only checker then
   will error upon. Without this change, SILGen crashes instead of emitting an
   error diagnostic in the following test:
   .//test/SILOptimizer/move_only_checker_addressonly_fail.swift
2022-06-21 16:47:58 -07:00
Pavel Yaskevich
6e1a44dfdc [SILGen] NFC: Remove an unused var left by distributed actor changes 2022-06-21 10:34:59 -07:00
Pavel Yaskevich
567924f7f6 [Distributed] SILGen: Remove isDistributed flags from accessor code 2022-06-17 12:12:16 -07:00
Pavel Yaskevich
b963c6d20f [Distributed] Remove commented out code and print statements 2022-06-17 12:12:16 -07:00
Konrad `ktoso` Malawski
5a5b7c007c towards distributed getters 2022-06-17 12:12:16 -07:00
Konrad `ktoso` Malawski
079bbcf517 wip 2022-06-17 12:12:16 -07:00
Kavon Farvardin
af683dc271 basic implementation of performing an init of the id after an assign of the actorSystem.
The resignID call within the initializer moved into DI, because an assignment to
the actorSystem, and thus initialization of the id, is no longer guaranteed to happen.
Thus, while we previously could model the resignation as a clean-up emitted on all
unwind paths in an initializer, now it's conditional, based on whether the id was
initialized. This is exactly what DI is designed to do, so we inject the resignation
call just before we call the identity's deinit.
2022-03-24 16:20:01 -07:00
Evan Wilde
1815e24445 Merge pull request #40963 from etcwilde/ewilde/global-actor-top-level-vars
Allow global-actor isolation on top-level variables
2022-01-25 11:35:11 -08:00
Erik Eckstein
5fd941eb67 Add the @exclusivity attribute.
The `@exclusivity(unchecked)` attribute can be used on variables to selectively disable exclusivity checking.
For completeness, also the `@exclusivity(checked)` variant is supported: it turns on exclusivity checking for specific variables if exclusivity enforcement is disabled by the command line option.

This new attribute is a missing implementation part of SE-0176 (https://github.com/apple/swift-evolution/blob/main/proposals/0176-enforce-exclusive-access-to-memory.md).

rdar://31121356
2022-01-25 08:06:45 +01:00
Evan Wilde
9907d2426b Allow actor isolation in top-level code variables
Don't crash when we're SILGen'ing accesses to globals in top-level code.
The address is found in the top-level main function because we generate
the initialization code directly. In the case when we're generating the
body of the implicit main function, the presence of the address does not
indicate that the variable is local.
2022-01-21 13:58:22 -08:00
Kavon Farvardin
51f8cd161d gain isolation for static stored property initializer expressions
Some globals, like static stored properties, are lazily initialized.
For situations where we do a direct access to that property,
we will first call a function that tries to initialize the var if needed,
before returning the address of the global to perform the direct access.
In this specific case, we were not on the right actor when invoking
that function.

fixes rdar://83411416
2021-12-22 11:49:08 -08:00
Kavon Farvardin
9bff2b43a6 fix SILGen bug for cross-module actor let accesses
When trying to access a let-bound property of an actor across
a moudule boundary, the operation should be treated as async.
But, upon reaching SILGen, the compiler would crash when trying
to emit the needed hop, because the base of the element reference
was missing. This commit fixes that and adds regression coverage.

resolves rdar://81812013
2021-11-08 14:32:15 -08:00
Andrew Trick
e85228491d Rename AccessedStorage to AccessStorage
to be consistent with AccessPath and AccessBase.

Otherwise, the arbitrary name difference adds constant friction.
2021-09-21 23:18:24 -07:00
Hamish Knight
cead30d639 [SIL] Adopt ArgumentList 2021-09-01 18:40:27 +01:00
Rintaro Ishizaki
49547a5378 [NFC][Basic] Import llvm::isa_and_nonnull to 'swift' namespace
Just for convenicence.

* Replace `llvm::isa_and_nonnull` with imported `isa_and_nonnull`
* Repalce some `EXPR && isa<T>(EXPR)` with `isa_and_nonnull<T>(EXPR)`
2021-08-27 11:36:21 -07:00
Andrew Trick
9984b81de7 MemAccessUtils cleanup: rename hasIdenticalBase
to hasIdenticalStorage.

Be precise in preparation for unifying and clarifying the access base model.
2021-08-07 15:26:46 -07:00
Joe Groff
fc67ba57f2 Merge pull request #37938 from jckarter/async-let-multi-suspend
Handle multiple awaits and suspend-on-exit for async let tasks.
2021-07-23 07:36:54 -07:00
Joe Groff
439edbce1f Handle multiple awaits and suspend-on-exit for async let tasks.
Change the code generation patterns for `async let` bindings to use an ABI based on the following
functions:

- `swift_asyncLet_begin`, which starts an `async let` child task, but which additionally
  now associates the `async let` with a caller-owned buffer to receive the result of the task.
  This is intended to allow the task to emplace its result in caller-owned memory, allowing the
  child task to be deallocated after completion without invalidating the result buffer.
- `swift_asyncLet_get[_throwing]`, which replaces `swift_asyncLet_wait[_throwing]`. Instead of
  returning a copy of the value, this entry point concerns itself with populating the local buffer.
  If the buffer hasn't been populated, then it awaits completion of the task and emplaces the
  result in the buffer; otherwise, it simply returns. The caller can then read the result out of
  its owned memory. These entry points are intended to be used before every read from the
  `async let` binding, after which point the local buffer is guaranteed to contain an initialized
  value.
- `swift_asyncLet_finish`, which replaces `swift_asyncLet_end`. Unlike `_end`, this variant
  is async and will suspend the parent task after cancelling the child to ensure it finishes
  before cleaning up. The local buffer will also be deinitialized if necessary. This is intended
  to be used on exit from an `async let` scope, to handle cleaning up the local buffer if necessary
  as well as cancelling, awaiting, and deallocating the child task.
- `swift_asyncLet_consume[_throwing]`, which combines `get` and `finish`. This will await completion
  of the task, leaving the result value in the result buffer (or propagating the error, if it
  throws), while destroying and deallocating the child task. This is intended as an optimization
  for reading `async let` variables that are read exactly once by their parent task.

To avoid an epoch break with existing swiftinterfaces and ABI clients, the old builtins and entry
points are kept intact for now, but SILGen now only generates code using the new interface.

This new interface fixes several issues with the old async let codegen, including use-after-free
crashes if the `async let` was never awaited, and the inability to read from an `async let` variable
more than once.

rdar://77855176
2021-07-22 10:19:31 -07:00
Kavon Farvardin
7e85bb3d9f fix SILGen of access to isolated wrapper around instance actor property
The fix is to implement part of SILGen that I asserted could not
happen because I couldn't formulate a situation where an access
to instance-isolated state would happen at the point in the code.

But, if a property wrapper's wrapped-value is global-actor
isolated, and is wrapping an actor instance, then it does happen.

Implementation details:

If the address is isolated to an actor instance, then we need the
base in order to perform a hop prior to starting the access,
so I just pass the base value through SILGen to the point it is
needed, since the base is available from all of the callers.
2021-07-14 17:08:26 -07:00
Kavon Farvardin
05f03b0e79 Fix SILGen of access to isolated static properties
When accessing a static property isolated to a
global-actor, such as MainActor, a `hop_to_executor`
was not being emitted. This was caught by an assertion
I had left to catch such cases, but of course in release
builds this will lead to incorrect SIL, etc.

This issue revealed some other problems with how
the implementation was done for other kinds of
accesses starting from a static property, e.g.,
emitting a redundant hop for the same access.
This was fixed by modelling the actor-isolation
placed into a component as only being accessible
by consuming it from the component. This prevents
the emission of the hops more than once.

Thus, the regression test was updated to catch
unexpected hop_to_executor instructions.

Resolves rdar://78292384
2021-06-30 12:33:40 -07:00
Erik Eckstein
5700ddceb3 SILGen: fix a crash when assigning a wrapped property in a convenience initializer
Convenience initializers only contain assignments to self, but not initializations.
This case was not handled when deciding between a regular assignment and assign_by_wrapper.

https://bugs.swift.org/browse/SR-14675
rdar://78892507
2021-06-08 12:58:56 +02:00
Saleem Abdulrasool
25f437e17d mark some switches as covered (NFCI)
Unfortunately, MSVC does not detect covered switches as clang.  Mark
some of the switches as covered to avoid an unnecessary warning from
MSVC.
2021-06-05 15:30:25 -07:00
Doug Gregor
220e29d674 Reinstate "async let", with "spawn let" as an alias. 2021-05-07 00:13:56 -07:00
Doug Gregor
5d8174da57 [Concurrency] Introduce spawn let 2021-04-29 22:42:40 -07:00
Konrad `ktoso` Malawski
d3c5ebc9b7 [AsyncLet] reimplemented with new ABI and builtins 2021-04-19 10:06:23 +09:00
Holly Borla
3ca1292ec2 Merge pull request #36521 from hborla/property-wrapper-request-refactoring
[Property Wrappers] Rework the dependencies between property wrapper requests.
2021-03-19 21:27:31 -07:00
Holly Borla
21a86b5d2f [NFC][Property Wrappers] Split PropertyWrapperBackingPropertyInfoRequest into
two separate requests - one to synthesize the auxiliary declarations, and
another to compute how the backing storage is initialized.
2021-03-19 13:03:13 -07:00
Joe Groff
79fb05b362 Concurrency: Hop back to the previous executor after actor calls.
Tasks shouldn't normally hog the actor context indefinitely after making a call that's bound to
that actor, since that prevents the actor from potentially taking on other jobs it needs to
be able to address. Set up SILGen so that it saves the current executor (using a new runtime
entry point) and hops back to it after every actor call, not only ones where the caller context
is also actor-bound.

The added executor hopping here also exposed a bug in the runtime implementation while processing
DefaultActor jobs, where if an actor job returned to the processing loop having already yielded
the thread back to a generic executor, we would still attempt to make the actor give up the thread
again, corrupting its state.

rdar://71905765
2021-03-18 11:47:50 -07:00
Kavon Farvardin
2d0911cd97 implementation of async actor properties in SILGen
The strategy for implementing them is integrated with the
PathComponent infrastructure in SILGen in order to correctly
support mixtures of chained accesses and forced optionals, etc.

The actor isolation information is only piped into LValues from
the expressions that might be marked implicitly-async.
2021-03-04 18:37:32 -08:00
Kavon Farvardin
bf171edbc0 assert that some implicitly async property/subscript references have not made it to SILGen
For the dynamic versions of LookupExprs, we do not expect these to be
implicitly async. For the other cases, I simply haven't implemented them
yet.
2021-03-04 18:37:32 -08:00
Erik Eckstein
9055e93af9 SIL: some improvements/fixes around assign_by_wrapper
* Refactoring: replace "Destination" and the ownership qualifier by a single "Mode".  This represents much better the mode how the instruction is to be lowered. NFC
* Make assign_by_wrapper printable and parseable.
* Fix lowering of the assign modes for indirect results of the init-closure: The indirect result was initialized and not assigned to. The fix is to insert a destroy_addr before calling the init closure. This fixes a memory lifetime error and/or a memory leak. Found by inspection.
* Fix an iterator-invalidation crash in RawSILInstLowering
* Add tests for lowering assign_by_wrapper.
2021-03-03 18:57:02 +01:00
Holly Borla
9cdecf4703 [Property Wrappers] Compute generic wrapped-value and projected-value
initialization expressions for parameters with attached property wrappers.
2021-02-25 18:35:14 -08:00
Holly Borla
13692fefde [Property Wrappers] Store property wrapper "init from projection" expressions
in PropertyWrapperBackingPropertyInfo.
2021-02-25 18:35:14 -08:00
Erik Eckstein
ec64f2a255 SILLocation: replace CleanupLocation::get(loc) with CleanupLocation(loc)
No need to have a static get function - the constructor can be used directly.
NFC
2021-01-29 20:28:21 +01:00
Holly Borla
3640de3455 [Property Wrappers] Check for ignored assign_by_wrapper loads in
LifetimeChecker::shouldEmitError in order to avoid incorrectly
populating EmittedErrorLocs when no error is emitted.

This fixes a few corner cases where DI would error out or crash
while assigning to a wrapped property with a nonmutating setter.
2020-12-23 20:31:51 -05:00