The underlying C++ code expects a non-null `Instruction*` or `SILArgument*` pointer, and
most of the contextual information in a verifier error is derived from these arguments,
so it doesn't really make sense for the Swift level interface to present these arguments
as optional.
This also required me to change how we handled which instruction/argument we
emit an error about in the verifier. Previously we were using two global
variables that we made nullptr to control which thing we emitted an error about.
This was unnecessary. Instead I added a little helper struct that internally
controls what we will emit an error about and an external "guard" RAII struct
that makes sure we push/pop the instruction/argument we are erroring upon
correctly.
This function will give the wrong convention in SILGen when
using -enable-sil-opaque-values. In particular, it will say
arguments are indirect when they are not.
The `shouldExpand` in `OptUtils.swift` was incorrectly returning `true`
unconditionally when `useAggressiveReg2MemForCodeSize` was disabled. The
expansion might be invalid for types with addr-only types and structs
with deinit, but we didn't check them before. This could lead to invalid
`destructure_struct` instructions without `drop_deinit` being emitted.
This is necessary because we need to model its stack-allocation
behavior, although I'm not yet doing that in this patch because
StackNesting first needs to be taught to not try to move the
deallocation.
I'm not convinced that `async let` *should* be doing a stack allocation,
but it undoubtedly *is* doing a stack allocation, and until we have an
alternative to that, we will need to model it properly.
We were reusing the SILLocation from return instructions
to generate projections to ultimately destroy values.
This fix improves on what we were doing before, by
converting the insertion point's SILLocation into a
RegularLocation _without dropping_ the source location.
If the SILLocation was tied to an ASTNode, it'll carry
over the line location for this new regular location.
Otherwise, it'll fallback to the prior strategy of
producing a line 0 autogenerated location.
resolves rdar://163281183
SILGen may produce a borrow accessor result from within a local borrow scope. Such as:
```
%ld = load_borrow %self
%fwd = unchecked_ownership %ld
%ex = struct_extract %fwd, #Struct.storedProperty
end_borrow %ld
return %ex
```
This is illegal OSSA, since the return uses a value outside it's borrow scope.
Add a new SILGenCleanup transform, to turn this into valid OSSA:
```
%ld = load_borrow %self
%ex = struct_extract %ld, #Struct.storedProperty
return_borrow %ex from_scopes %ld
```
This instruction can be used to disable ownership verification on it's result and
will be allowed only in raw SIL.
Sometimes SILGen can produce invalid ownership SSA, that cannot be resolved until
mandatory passes run. We have a few ways to piecewise disable verification.
With unchecked_ownership instruction we can provide a uniform way to disable ownership
verification for a value.
Specifically, when TBI is available we use the bottom two bits of the top nibble
(bits 60,61). On platforms without TBI, we use the bottom two tagged pointer
bits (bits 0, 1).
rdar://156525771
NOTE: We are not performing any bitmasking at all now. This is so that we can
transition the code base/tests to expect Builtin.ImplicitActor instead
of Optional<any Actor>.
NOTE: The actual test changes are in the next commit. I did this to make it
easier to review the changes.
This should not have any user visible changes.
This instruction converts Builtin.ImplicitActor to Optional<any Actor>. In the
process of doing so, it masks out the bits we may have stolen from the witness
table pointer of Builtin.ImplicitActor. The bits that we mask out are the bottom
two bits of the top nibble of the TBI space on platforms that support TBI (that
is bit 60,61 on arm64). On platforms that do not support TBI, we just use the
bottom two tagged pointer bits (0,1).
By using an instruction, we avoid having to represent the bitmasking that we are
performing at the SIL level and can instead just make the emission of the
bitmasking an IRGen detail. It also allows us to move detection if we are
compiling for AArch64 to be an IRGen flag instead of a LangOpts flag.
The instruction is a guaranteed forwarding instruction since we want to treat
its result as a borrowed projection from the Builtin.ImplicitActor.
This is subtly different from just checking whether the destination of
an edge is dead-end, because edges *internal* to dead-end regions
generally still need to be treated normally. Fundamentally, such an edge
must be part of a loop.
We need to pass down the generic signature of the caller to correctly
mangle the substitution map, because the replacement types in this
substitution maps are interface types for the caller's generic signature.
Fixes rdar://problem/161968922.
Introduce copy_value + mark_unresolved_non_copyable_value + begin_borrow at the return value of
borrow accessor apply to drive move-only diagnostics.
Also strip the copy_value + mark_unresolved_non_copyable_value + begin_borrow trio in a few places, since
they create an artificial scope out of which we cannot return values in a borrow accessor
without resorting to unsafe SIL operations currently.
Borrow accessor diagnostics allow stripping these instructions safely in the following places:
- return value of a borrow accessor
- self argument reference in the borrow accessor return expression and borrow accessor apply
The intent for `@inline(always)` is to act as an optimization control.
The user can rely on inlining to happen or the compiler will emit an error
message.
Because function values can be dynamic (closures, protocol/class lookup)
this guarantee can only be upheld for direct function references.
In cases where the optimizer can resolve dynamic function values the
attribute shall be respected.
rdar://148608854
This attribute forces programmers to acknowledge every
copy that is required to happen in the body of the
function. Only those copies that make sense according
to Swift's ownership rules should be "required".
The way this is implemented as of now is to flag each
non-explicit copy in a function, coming from SILGen, as
an error through PerformanceDiagnostics.
Based on what I see from OwnershipModelEliminator,
`%x = load [copy] %y` can turn into a plain load
followed by a retain of the loaded value.
See `NonTrivialLoadableTypeLowering::emitLoad`
* move some Cloner utilities from ContextCommon.swift directly into Cloner.swift
* add an `cloneRecursively` overload which doesn't require the `customGetCloned` closure argument
* some small cleanups
Enum types may have incomplete lifetimes in address form for trivial case values. When promoted to value form, they will end up with incomplete ossa lifetimes.
Because we know that the incomplete enum values are trivial enum cases we complete their lifetimes with `end_lifetime` instead of `destroy_value`.
This is especially important for Embedded Swift where we are not allowed to insert destroys which were not there before.
Fixes a compiler crash in Embedded Swift caused by de-virtualizing such an inserted destroy and ending up with a non-specialized generic function.
rdar://158807801
The utility effectively determines whether a value leaks as part of its
work, a subset of the checking done by the ownership verifier. Disable
that checking when the flag that disables the ownership verifier is
passed.