Previously, the enum representation was fixed to represent the different
cases payloads separately with the unchecked_take_enum_data_addr
instruction consuming all fields but that whose address is obtained.
In a few places, handling for enum deinits was left undone with an
assertion that the enum not have one.
Here, the deinit bit of the enum is shifted to the end. And the
assertions are replaced with handling. Finally, the logic for inserting
destroys after switch_enum_addr instructions is fixed.
It seems really unfortunate that we use SILCloner to, basically,
implement a recursive visitor of the types used in a SIL function,
but apparently it's what we do.
Fixes#72117.
Compute, update and handle borrowed-from instruction in various utilities and passes.
Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`.
Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
The attribute declares that a struct contains "sensitive" data.
It enforces that the contents of such a struct value is zeroed out at the end of its lifetime.
In other words: the content of such a value is not observable in memory after the value's lifetime.
Also add an experimental feature `Sensitive` with which the attribute can be enabled.
enabled. If two modules are in the same package and package cmo is enabled,
v-table or witness-table calls should not be generated at the use site in the
client module. Modified conformance serialization check to allow serializing
witness thunks.
Also reordered SIL functions bottom-up so the most nested referenced functions
can be serialized first. Allowed serializing a function if a shared definition
(e.g. function `print`). Added a check for resilient mode wrt struct instructions.
Added tests for SIL tables and resilient mode on/off.
rdar://124632670
Factor AbstractionPattern::conformsToKnownProtocol and lower ~Escapable using the same logic as ~Copyable.
Adds support for conditionally Escapable enums.
Correctly sets the SILType::isTrivial flags for conditionally escapable structs and enums in environments (extensions)
that provide an Escapable conformance, such as:
struct NE<E: ~Escapable> : ~Escapable {}
extension NE: Escapable {
func foo() -> Self {
// Self is both Escapable and trivial here.
self
}
}
Fixes rdar://125950218 ([nonescapable] support conditionally escapable enums)
This PR implements first set of changes required to support autodiff for coroutines. It mostly targeted to `_modify` accessors in standard library (and beyond), but overall implementation is quite generic.
There are some specifics of implementation and known limitations:
- Only `@yield_once` coroutines are naturally supported
- VJP is a coroutine itself: it yields the results *and* returns a pullback closure as a normal return. This allows us to capture values produced in resume part of a coroutine (this is required for defers and other cleanups / commits)
- Pullback is a coroutine, we assume that coroutine cannot abort and therefore we execute the original coroutine in reverse from return via yield and then back to the entry
- It seems there is no semantically sane way to support `_read` coroutines (as we will need to "accept" adjoints via yields), therefore only coroutines with inout yields are supported (`_modify` accessors). Pullbacks of such coroutines take adjoint buffer as input argument, yield this buffer (to accumulate adjoint values in the caller) and finally return the adjoints indirectly.
- Coroutines (as opposed to normal functions) are not first-class values: there is no AST type for them, one cannot e.g. store them into tuples, etc. So, everywhere where AST type is required, we have to hack around.
- As there is no AST type for coroutines, there is no way one could register custom derivative for coroutines. So far only compiler-produced derivatives are supported
- There are lots of common things wrt normal function apply's, but still there are subtle but important differences. I tried to organize the code to enable code reuse, still it was not always possible, so some code duplication could be seen
- The order of how pullback closures are produced in VJP is a bit different: for normal apply's VJP produces both value and pullback closure via a single nested VJP apply. This is not so anymore with coroutine VJP's: yielded values are produced at `begin_apply` site and pullback closure is available only from `end_apply`, so we need to track the order in which pullbacks are produced (and arrange consumption of the values accordingly – effectively delay them)
- On the way some complementary changes were required in e.g. mangler / demangler
This patch covers the generation of derivatives up to SIL level, however, it is not enough as codegen of `partial_apply` of a coroutine is completely broken. The fix for this will be submitted separately as it is not directly autodiff-related.
---------
Co-authored-by: Andrew Savonichev <andrew.savonichev@gmail.com>
Co-authored-by: Richard Wei <rxwei@apple.com>
drop_deinit forwards ownership while effectively stripping the deinitializer. It is similar to a type cast.
Fixes rdar://125590074 ([NonescapableTypes] Nonescapable types
cannot have deinits)
ActorIsolation already has a "I have no value case": unspecified. Lets just use
that.
Just a mistake I made that I am trying to fix before anything further depends on
this code.
When cloning SIL, it's OK for conformances to Copyable or Escapable to
be carried-over as a builtin conformance, rather than an abstract
conformance.
This is a workaround for a bug introduced in
`6cd5468cceacc1d600c7dafdd4debc6740d1dfd6`.
resolves rdar://125460667
* Allow normal function results of @yield_once coroutines
* Address review comments
* Workaround LLVM coroutine codegen problem: it assumes that unwind path never returns.
This is not true to Swift coroutines as unwind path should end with error result.
[region-isolation] A few improvements + If a value is dynamically actor isolated, do not consider it transferred if the transfer statically was to that same actor isolation.
This issue can come up when a value is initially statically disconnected, but
after we performed dataflow, we discovered that it was actually actor isolated
at the transfer point, implying that we are not actually transferring.
Example:
```swift
@MainActor func testGlobalAndGlobalIsolatedPartialApplyMatch2() {
var ns = (NonSendableKlass(), NonSendableKlass())
// Regions: (ns.0, ns.1), {(mainActorIsolatedGlobal), @MainActor}
ns.0 = mainActorIsolatedGlobal
// Regions: {(ns.0, ns.1, mainActorIsolatedGlobal), @MainActor}
// This is not a transfer since ns is already main actor isolated.
let _ = { @MainActor in
print(ns)
}
useValue(ns)
}
```
To do this, I also added to SILFunction an actor isolation that SILGen puts on
the SILFunction during pre function visitation. We don't print it or serialize
it for now.
rdar://123474616
Change FieldSensitive's enum representation to allow distinguishing
among the elements with associated value. Consider
`unchecked_take_enum_data_addr` to consume all other fields than that
taken.
rdar://125113258