This is exactly like copy_addr except that it is not viewed from the verifiers
perspective as an "invalid" copy of a move only value. It is intended to be used
in two contexts:
1. When the move checker emits a diagnostic since it could not eliminate a copy,
we still need to produce valid SIL without copy_addr on move only types since we
will hit canonical SIL eventually even if we don't actually codegen the SIL. The
pass can just convert said copy_addr to explicit_copy_addr and everyone is
happy.
2. To implement the explicit copy function for address only types.
The old syntax was
@opened("UUID") constraintType
Where constraintType was the right hand side of a conformance requirement.
This would always create an archetype where the interface type was `Self`,
so it couldn't cope with member types of opened existential types.
Member types of opened existential types is now a thing with SE-0309, so
this lack of support prevented writing SIL test cases using this feature.
The new syntax is
@opened("UUID", constraintType) interfaceType
The interfaceType is a type parameter rooted in an implicit `Self`
generic parameter, which is understood to be the underlying type of the
existential.
Fixes rdar://problem/93771238.
These instructions have the following attributes:
1. copyably_to_moveonlywrapper takes in a 'T' and maps it to a '@moveOnly
T'. This is semantically used when initializing a new moveOnly binding from a
copyable value. It semantically destroys its input @owned value and returns a
brand new independent @owned @moveOnly value. It also is used to convert a
trivial copyable value with type 'Trivial' into an owned non-trivial value of
type '@moveOnly Trivial'. If one thinks of '@moveOnly' as a monad, this is how
one injects a copyable value into the move only space.
2. moveonlywrapper_to_copyable takes in a '@moveOnly T' and produces a new 'T'
value. This is a 'forwarding' instruction where at parse time, we only allow for
one to choose it to be [owned] or [guaranteed].
* moveonlywrapper_to_copyable [owned] is used to signal the end of lifetime of
the '@moveOnly' wrapper. SILGen inserts these when ever a move only value has
its ownership passed to a situation where a copyable value is needed. Since it
is consuming, we know that the no implicit copy checker will ensure that if we
need a copy for it, the program will emit a diagnostic.
* moveonlywrapper_to_copyable [guaranteed] is used to pass a @moveOnly T value
as a copyable guaranteed parameter with type 'T' to a function. In the case of
using no-implicit-copy checking this is always fine since no-implicit-copy is a
local pattern. This would be an error when performing no escape
checking. Importantly, this instruction also is where in the case of an
@moveOnly trivial type, we convert from the non-trivial representation to the
trivial representation.
Some important notes:
1. In a forthcoming commit, I am going to rebase the no implicit copy checker on
top of these instructions. By using '@moveOnly' in the type system, we can
ensure that later in the SIL pipeline, we can have optimizations easily ignore
the code.
2. Be aware of is that due to SILGen only emitting '@moveOnly T' along immediate
accesses to the variable and always converts to a copyable representation when
calling other code, we can simply eliminate from the IR all moveonly-ness from
the IR using a lowering pass (that I am going to upstream). In the evil scheme
we are accomplishing here, we perform lowering of trivial values right after
ownership lowering and before diagnostics to simplify the pipeline.
On another note, I also fixed a few things in SILParsing around getASTType() vs
getRawASTType().
The ComputeEffects pass derives escape information for function arguments and adds those effects in the function.
This needs a lot of changes in check-lines in the tests, because the effects are printed in SIL
The ComputeEffects pass derives escape information for function arguments and adds those effects in the function.
This needs a lot of changes in check-lines in the tests, because the effects are printed in SIL
Merge the AddressLowering pass from its old development branch and update
it so we can begin incrementally enabling it under a flag.
This has been reimplemented for simplicity. There's no point in
looking at the old code.
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.
As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
The main effect of this will be that in IRGen we will use llvm.dbg.addr instead
of llvm.dbg.declare. We must do this since llvm.dbg.declare implies that the
given address is valid throughout the program.
This just adds the instructions/printing/parsing/serialization/deserialization.
rdar://85020571
The new flag will be used to track whether a move_value corresponds to a
source-level lexical scope. Here, the flag is just added to the
instruction and represented in textual and serialized SIL.
The "regular" CMO is done with the option `-cross-module-optimization`. It's good for performance but can increase code size.
Now, which this change CMO is also done if the option is not given, but in a very conservative way. Only very small functions are serialized and not additional type metadata is kept alive.
rdar://70082202
Introduce a new instruction `dealloc_stack_ref ` and remove the `stack` flag from `dealloc_ref`.
The `dealloc_ref [stack]` was confusing, because all it does is to mark the deallocation of the stack space for a stack promoted object.
Required for UnsafeRawPointer.withMemoryReboud(to:).
%out_token = rebind_memory %0 : $Builtin.RawPointer to %in_token
%0 must be of $Builtin.RawPointer type
%in_token represents a cached set of bound types from a prior memory state.
%out_token is an opaque $Builtin.Word representing the previously bound
types for this memory region.
This instruction's semantics are identical to ``bind_memory``, except
that the types to which memory will be bound, and the extent of the
memory region is unknown at compile time. Instead, the bound-types are
represented by a token that was produced by a prior memory binding
operation. ``%in_token`` must be the result of bind_memory or
Required for UnsafeRawPointer.withMemoryRebound(to:)
%token = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T
%0 must be of $Builtin.RawPointer type
%1 must be of $Builtin.Word type
%token is an opaque $Builtin.Word representing the previously bound types
for this memory region.
This is a signal to the move value kill analysis that this is a move that should
have diagnostics emitted for it. It is a temporary addition until we add
MoveOnly to the SIL type system.
I am purposely doing this in SILGen rather than at the type system level to
avoid having to have to add a bunch of boilerplate to the type system. Instead
of doing that, I am in SILGen checking for the isNoImplicitCopy bit on the
ParamDecl when we emit arguments. At that point, I set on the specific
SILArgument being emitted the bit that it is no implicit copy. In terms of
printing at the SIL level, I just printed it in front of the function argument
type like @owned, e.x.:
func myFunc(_ x: @_noImplicitCopy T) -> T {
...
}
becomes:
bb0(%0 : @noImplicitCopy @owned $T):
Some notes:
* Just to be explicit, I am making it so that no implicit copy parameters by
default are always passed at +1. The reason why I think this makes sense is
that this is the natural way of working with a move only value.
* As always, one can not write no implicit copy the attribute without passing
the flag -enable-experimental-move-only so this is NFC.
rdar://83957088
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 patch replace all in-memory objects of DebugValueAddrInst with
DebugValueInst + op_deref, and duplicates logics that handles
DebugValueAddrInst with the latter. All related check in the tests
have been updated as well.
Note that this patch neither remove the DebugValueAddrInst class nor
remove `debug_value_addr` syntax in the test inputs.
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.
The `forwarding` directive should be optional for SIL instructions.
However, the current SIL parser put it as a requirement when there is a
comma follows after the main instruction components, which conflicts
with debug info directives like `loc` or `scope`. This patch teaches the
parser to treat `forwarding` as an optional directive.
Resolves SR-14814.
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.
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.
Refactor SILGen's ApplyOptions into an OptionSet, add a
DoesNotAwait flag to go with DoesNotThrow, and sink it
all down into SILInstruction.h.
Then, replace the isNonThrowing() flag in ApplyInst and
BeginApplyInst with getApplyOptions(), and plumb it
through to TryApplyInst as well.
Set the flag when SILGen emits a sync call to a reasync
function.
When set, this disables the SIL verifier check against
calling async functions from sync functions.
Finally, this allows us to add end-to-end tests for
rdar://problem/71098795.
While removing an invalid cast and inserting traps, we are currently
inserting a store of undef to the cast destination and delete all
instructions after the cast except for dealloc_stack.
If the cast destination was an alloc_stack, the verifier could raise
an error saying the cast destination was initialized at the dealloc.
This PR deletes the store to undef, destroy_addr of the cast src,
and gets rid of the code that was retaining the dealloc_stack.
None of this is necessary anymore and the SIL is going to be legal
because we insert unreachable instruction.
This patch updates the `actor class` spelling to `actor` in almost all
of the tests. There are places where I verify that we sanely handle
`actor` as an attribute though. These include:
- test/decl/class/actor/basic.swift
- test/decl/protocol/special/Actor.swift
- test/SourceKit/CursorInfo/cursor_info_concurrency.swift
- test/attr/attr_objc_async.swift
- test/ModuleInterface/actor_protocol.swift
Specifically, I made it so that assuming our instruction is inserted into a
block already that we:
1. Return a constraint of {OwnershipKind::Any, UseLifetimeConstraint::NonLifetimeEnding}.
2. Return OwnershipKind::None for all values.
Noticed above I said that if the instruction is already inserted into a block
then we do this. The reason why is that if this is called before an instruction
is inserted into a block, we can't get access to the SILFunction that has the
information on whether or not we are in OSSA form. The only time this can happen
is if one is using these APIs from within SILBuilder since SILBuilder is the
only place where we allow this to happen. In SILBuilder, we already know whether
or not our function is in ossa or not and already does different things as
appropriate (namely in non-ossa does not call getOwnershipKind()). So we know
that if these APIs are called in such a situation, we will only be calling it if
we are in OSSA already. Given that, we just assume we are in OSSA if we do not
have a function.
To make sure that no mistakes are made as a result of that assumption, I put in
a verifier check that all values when ownership is disabled return a
OwnershipKind::None from getOwnershipKind().
The main upside to this is this means that we can write code for both
OSSA/non-OSSA and write code for non-None ownership without needing to check if
ownership is enabled.