Fix two bugs:
- FirstArgOwnershipForwardingSingleValueInst needs to forward its first operand.
- select_value needs to be a ForwardedBorrow for all cases and the default.
The AsyncEntryPoint represents the thunk that is wrapped in a task. This
thunk is used to ensure that the main function explicitly calls "exit",
and to properly unwrap and report any unhandled errors returned from the
user-written main. The function takes on the name `@async_main` in the
emitted SIL.
Changed the frontend flag to -enable-experimental-lexical-lifetimes from
-enable-experimental-defined-lifetimes.
Changed the attribute on begin_borrow from [defined] to [lexical].
The new flag will be used to track whether a borrow scope corresponds to
a source-level lexical scope. Here, the flag is just documented, added
to the instruction, represented in textual and serialized SIL, and
cloned.
Support for addresses with arbitrary alignment as opposed to their
element type's natural in-memory alignment.
Required for bytestream encoding/decoding without resorting to memcpy.
SIL instruction flag, documentation, printing, parsing, serialization,
and IRGen.
This is a new instruction that can be used by SILGen to perform a semantic move
in between two entities that are considered separate variables at the AST
level. I am going to use it to implement an experimental borrow checker.
This PR contains the following:
1. I define move_value, setup parsing, printing, serializing, deserializing,
cloning, and filled in all of the visitors as appropriate.
2. I added createMoveValue and emitMoveValueOperation SILBuilder
APIs. createMoveValue always creates a move and asserts is passed a trivial
type. emitMoveValueOperation in contrast, will short circuit if passed a
trivial value and just return the trivial value.
3. I added IRGen tests to show that we can push this through the entire system.
This is all just scaffolding for the instruction to live in SIL land and as of
this PR doesn't actually do anything.
This new SIL di-expression represents the dereference on the SSA value.
Similar to DW_OP_deref in DWARF. It is also going to replace the
existing `debug_value_addr`. Namely, replacing the following
instruction:
```
debug_value_addr %a : $*T, name "my_var"
```
with this one:
```
debug_value %a : $*T, name "my_var", expr op_deref
```
The new flag will be used to track whether a borrow scope corresponds to
a source-level lexical scope. Here, the flag is just added to the
instruction and represented in textual and serialized SIL.
Debug variables that are marked 'implicit' on its `debug_value`
instruction mean that they were generated by compiler. Optimizers are
free to remove them (if it becomes a dead code, for instance) even in
-Onone. Since they are barely used by users and keeping them might lead
to incorrect IRGen results.
Start treating the null {Can}GenericSignature as a regular signature
with no requirements and no parameters. This not only makes for a much
safer abstraction, but allows us to simplify a lot of the clients of
GenericSignature that would previously have to check for null before
using the abstraction.
Currently the debug info infrastructure inside SIL can only associate a
source variable with a single (simple) SSA value. Which is insufficient
to preserve (correct) debug info across SIL-level optimizations -- for
example, SROA that decompose or even eliminate aggregate-type obejcts.
By adding DIExpression into SIL, we are able to reconstruct the
connection between a source variable and its SSA value counterpart, even
across optimizations. This patch adds such support into in-memory
representation for SIL instructions and the SILParser/Printer. The
following patch will add changes for the IRGen part.
- If any of the `-g<kind>` flag is given -- except `-gnone`, debug
info will be printed into every generated SIL files.
- The `-gsil` is deprecated in favor of `-sil-based-debuginfo`. The
SILDebugInfoGenerator Pass now generates intermediate SIL file with
name "<output file>.sil_dbg_<n>.sil". Other functionalities of that
Pass remain the same.
SILGen this builtin to a mandatory hop_to_executor with an actor type
operand.
e.g.
Task.detached {
Builtin.hopToActor(MainActor.shared)
await suspend()
}
Required to fix a bug in _runAsyncMain.
Allow SILDeclRef to refer to the main program
entry-point, which will either be for a main
SourceFile, or a synthetic main such as an `@main`
decl. Adjust the various SILDeclRef related
functions to handle this new case, and change the
emission to go through `emitFunctionDefinition`.
This change will allow the entry-point for an `@main`
decl (and eventually a main SourceFile) to be
emitted on-demand from its symbol name.
Through various means, it is possible for a synchronous actor-isolated
function to escape to another concurrency domain and be called from
outside the actor. The problem existed previously, but has become far
easier to trigger now that `@escaping` closures and local functions
can be actor-isolated.
Introduce runtime detection of such data races, where a synchronous
actor-isolated function ends up being called from the wrong executor.
Do this by emitting an executor check in actor-isolated synchronous
functions, where we query the executor in thread-local storage and
ensure that it is what we expect. If it isn't, the runtime complains.
The runtime's complaints can be controlled with the environment
variable `SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL`:
0 - disable checking
1 - warn when a data race is detected
2 - error and abort when a data race is detected
At an implementation level, this introduces a new concurrency runtime
entry point `_checkExpectedExecutor` that checks the given executor
(on which the function should always have been called) against the
executor on which is called (which is in thread-local storage). There
is a special carve-out here for `@MainActor` code, where we check
against the OS's notion of "main thread" as well, so that `@MainActor`
code can be called via (e.g.) the Dispatch library's
`DispatchQueue.main.async`.
The new SIL instruction `extract_executor` performs the lowering of an
actor down to its executor, which is implicit in the `hop_to_executor`
instruction. Extend the LowerHopToExecutor pass to perform said
lowering.
The comment in LowerHopToActor explains the design here.
We want SILGen to emit hops to actors, ignoring executors,
because it's easier to fully optimize in a world where deriving
an executor is a non-trivial operation. But we also want something
prior to IRGen to lower the executor derivation because there are
useful static optimizations we can do, such as doing the derivation
exactly once on a dominance path and strength-reducing the derivation
(e.g. exploiting static knowledge that an actor is a default actor).
There are probably phase-ordering problems with doing this so late,
but hopefully they're restricted to situations like actors that
share an executor. We'll want to optimize that eventually, but
in the meantime, this unblocks the executor work.
If the '[poison]' flag is set, then all references within this debug
value will be overwritten with a sentinel at this point in the
program. This is used in debug builds when shortening non-trivial
value lifetimes to ensure the debugger cannot inspect invalid
memory. `debug_value` instructions with the poison flag are not
generated until OSSA islowered. They are not expected to be serialized
within the module, and the pipeline is not expected to do any
significant code motion after lowering.