package-wide resilience domain if Package CMO is enabled.
The purpose of the attribute includes:
- Indicates that certain types such as loadable types are
allowed in serialized functions in resiliently built module
if the optimization is enabled, which are otherwise disallowed.
- Used during SIL deserialization to determine whether such
functions are allowed.
- Used to determine if a callee can be inlined into a caller
that's serialized without package-cmo, e.g. with an explicit
annotation like @inlinable, where the callee was serialized
due to package-cmo.
Resolves rdar://127870822
LLVM is gearing up to move to `std::endianness` and as part of that has
moved `llvm::support::endianness` to `llvm::endianness`
(bbdbcd83e6702f314d147a680247058a899ba261). Rename our uses.
* 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.
* Add a new flag -experimental-package-cmo that requires -experimental-allow-non-resilient-access.
* Support serializing package decls for CMO in package if enabled.
* Only applies to default mode CMO.
* Unlike the existing CMO, package CMO can be built with -enable-library-evolution as package
modules are required to be built together in the same project.
* Create hasPublicOrPackageVisibility to opt in for package decls; needed for CMO, SILVerifier,
and other call sites that verify or determine codegen.
Resolves rdar://121976014
For years, optimizer engineers have been hitting a common bug caused by passes
assuming all SILValues have a parent function only to be surprised by SILUndef.
Generally we see SILUndef not that often so we see this come up later in
testing. This patch eliminates that problem by making SILUndef uniqued at the
function level instead of the module level. This ensures that it makes sense for
SILUndef to have a parent function, eliminating this possibility since we can
define an API to get its parent function.
rdar://123484595
We want to preserve the borrow scope during switch dispatch so that move-only
checking doesn't try to analyze destructures or consumes out of it. SILGen
should mark anywhere that's a potential possibility with its own marker so that
it gets borrow checked independently.
Relax some existing pattern matches and add some unhandled instructions to the
walkers so that borrowing switches over address-only enums are properly analyzed
for incorrect consumption. Add a `[strict]` flag to `mark_unresolved_move_only_value`
to indicate a borrow access that should remain a borrow access even if the subject
is later stack-promoted from a box.
Ad-hoc requirements are now obsolete by making `remoteCall`,
`record{Argument, ReturnType}`, `decodeNextArgument` protocols
requirements and injecting witness tables for `SerializationRequirement`
conformances during IRGen.
In preparation for inserting mark_dependence instructions for lifetime
dependencies early, immediately after SILGen. That will simplify the
implementation of borrowed arguments.
Marking them unresolved is needed to make OSSA verification
conservative until lifetime dependence diagnostics runs.
This adds SIL-level support and LLVM codegen for normal results of a coroutine.
The main user of this will be autodiff as VJP of a coroutine must be a coroutine itself (in order to produce the yielded result) and return a pullback closure as a normal result.
For now only direct results are supported, but this seems to be enough for autodiff purposes.
Decls with a package access level are currently set to public SIL
linkages. This limits the ability to have more fine-grained control
and optimize around resilience and serialization.
This PR introduces a separate SIL linkage and FormalLinkage for
package decls, pipes them down to IRGen, and updates linkage checks
at call sites to include package linkage.
Resolves rdar://121409846
Optionally, the dependency to the initialization of the global can be specified with a dependency token `depends_on <token>`.
This is usually a `builtin "once"` which calls the initializer for the global variable.
The dependent 'value' may be marked 'nonescaping', which guarantees that the
lifetime dependence is statically enforceable. In this case, the compiler
must be able to follow all values forwarded from the dependent 'value', and
recognize all final (non-forwarded, non-escaping) use points. This implies
that `findPointerEscape` is false. A diagnostic pass checks that the
incoming SIL to verify that these use points are all initially within the
'base' lifetime. Regular 'mark_dependence' semantics ensure that
optimizations cannot violate the lifetime dependence after diagnostics.
Some notes:
This is not emitted by SILGen. This is just intended to be used so I can write
SIL test cases for transfer non sendable. I did this by adding an
ActorIsolationCrossing field to all FullApplySites rather than adding it into
the type system on a callee. The reason that this makes sense from a modeling
perspective is that an actor isolation crossing is a caller concept since it is
describing a difference in between the caller's and callee's isolation. As a
bonus it makes this a less viral change.
For simplicity, I made it so that the isolation is represented as an optional
modifier on the instructions:
apply [callee_isolation=XXXX] [caller_isolation=XXXX]
where XXXX is a printed representation of the actor isolation.
When neither callee or caller isolation is specified then the
ApplyIsolationCrossing is std::nullopt. If only one is specified, we make the
other one ActorIsolation::Unspecified.
This required me to move ActorIsolationCrossing from AST/Expr.h ->
AST/ActorIsolation.h to work around compilation issues... Arguably that is where
it should exist anyways so it made sense.
rdar://118521597
* `alloc_vector`: allocates an uninitialized vector of elements on the stack or in a statically initialized global
* `vector`: creates an initialized vector in a statically initialized global
This commit just introduces the instruction. In a subsequent commit, I am going
to add support to SILGen to emit this. This ensures that when we assign into a
tuple var we initialize it with one instruction instead of doing it in pieces.
The problem with doing it in pieces is that when one is emitting diagnostics it
looks semantically like SILGen actually is emitting code for initializing in
pieces which could be an error.
When building complex projects, there may cases of static libraries
which expose `@inlinable` functions which reference functions from
dynamically linked dependencies. In such a case, we need to consider the
provenance of the `function_ref` when determining the DLL storage for
linkage. We would previously use the deserialised metadata on the
`SILFunction` as there are entities where the `DeclContext` may not be
deserialised. However, this leaves us in a state where we are unable to
determine the actual provenance correctly in some cases. By simply
accessing the parent module directly from the `SILFunction` we ensure
that we properly identify the origin of the function allowing us to
query the DLL storage property. This further allows us to remove the
extra storage required for whether the `SILFunction` is statically
linked.