This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
Load splitting converts an aggregate load into a set of subobject
loads. This is required at -Onone for exclusivity diagnostics.
We cannot preserve the original debug information by redirecting debug
info to the memory address, because that might result in incorrect
debug values if the memory is reused.
Before this fix, we "conservatively" drop debug info in those
cases. This fix preserves full debug info by keeping the original
aggregate load intact alongside the new subobject loads. To avoid
exclusivity violations, it create a new unsafe access scope for the
old load.
Fixes LLDB missing variables in certain case #62241
I am adding this to make it easy to determine if a SILFunction that is not inout
aliasable is captured. This is useful when emitting certain types of
diagnostics like I need to emit with move only.
In this case, we know the checked_cast_br will have a false outcome.
It is sufficient to transform checked_cast_br into a br and delete the success path.
Before this, we were trying to do an OSSA rauw the successarg which is incorrect.
Rather than inserting dealloc_stacks at the end of blocks in the
dominance frontier of the alloc_stack, walk backward in the block to the
last user (if any) and insert after that (or at the beginning of the
block if not). If the transitive uses aren't understood, just insert at
the end of the blocks as before.
Previously, the dealloc_stacks created for the alloc_stacks used to pass
@in_guaranteed arguments to on_stack closures were created after the
users of the closure. When SILGen created these alloc_stacks in the
same block as the users, this happened to work. Now that
AddressLowering creates such alloc_stacks elsewhere, this approach
results in invalid SIL.
Here, the dealloc_stacks are instead at the end of each block in the
dominance frontier of the alloc_stack.
Add TermInst::forwardedOperand.
Add SILArgument::forwardedTerminatorResultOperand. This API will be
moved into a proper TerminatorResult abstraction.
Remove getSingleTerminatorOperand, which could be misused because it's
not necessarilly forwarding ownership.
Remove the isTransformationTerminator API, which is not useful or well
defined.
Rewrite several instances of complex logic to handle block arguments
with the simple terminator result API. This defines away potential
bugs where we don't detect casts that perform implicit conversion.
Replace uses of the SILPhiArgument type and code that explicitly
handle block arguments. Control flow is irrelevant in these
situations. SILPhiArgument needs to be deleted ASAP. Instead, use
simple APIs like SILArgument::isTerminatorResult(). Eventually this
will be replaced by a TerminatorResult type.
When inlining a begin_apply, if one of the values is yielded by
guaranteed convention, if the yielded value is itself owned, borrow it
during inlining.
Doing so is necessary because users of the yielded value are expecting a
value with guaranteed ownership. For example, it's valid to
store_borrow such a value but not an owned value.
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
Now that it can be called on partial_apply instructions,
insertAfterFullEvaluation does not name what the function does. One
could imagine a function which inserted after the applies of
(non-escaping) partial_applies.
Begin adding support for OSSA to checked-cast jump-threading based on
the new ownership utilities.
TODO:
Finish migrating to the new utilities in OwnershipOptUtils.
Ensure full unit test coverage.
When shrinking a borrow scope like
%borrow = begin_borrow %value
barrier
%copy = copy_value %borrow
end_borrow %borrow
the copy will be rewritten to be a copy of the borrowee:
%borrow = begin_borrow %value
barrier
%copy = copy_value %value
^^^^^^
end_borrow %borrow
If, as here, shrinking next encounters a barrier, then the insertion
point will be that rewritten copy_value instruction.
In such a case, when rather than creating a new end_borrow there and
deleting the old, just reuse the old one. The lifetime of the value
being copied will be canonicalized by CopyPropagation regardless.
Pass a BasicCalleeAnalysis instance to isDeinitBarrier. This enables
LexicalDestroyHoisting to hoist destroys over applies of functions which
are not deinit barriers.
Pass a BasicCalleeAnalysis instance to isDeinitBarrier. This will allow
ShrinkBorrowScope to hoist end_borrows over applies of functions which
are not deinit barriers.
Functions "are deinit barriers" (more pedantically, applies of functions
are deinit barriers) if any of their instructions are deinit barriers.
During side-effect analysis, when walking a function's instructions for
other global effects, also check for the deinit-barrier effect. If an
instruction is found to be a deinit barrier, mark the function's global
effects accordingly.
Add SILFunction::isDeinitBarrier to conveniently access the effects
computed during ComputeSideEffects.
Update the isBarrierApply predicate to iterate over the list of callees,
if complete, to check whether any is a deinit barrier. If none is, then
the apply is not a deinit barrier.
Added new C++-to-Swift callback for isDeinitBarrier.
And pass it CalleeAnalysis so it can depend on function effects. For
now, the argument is ignored. And, all callers just pass nullptr.
Promoted to API the mayAccessPointer component predicate of
isDeinitBarrier which needs to remain in C++. That predicate will also
depends on function effects. For that reason, it too is now passed a
BasicCalleeAnalysis and is moved into SILOptimizer.
Also, added more conservative versions of isDeinitBarrier and
maySynchronize which will never consider side-effects.