A live range representing the ownership of addressible memory.
This live range represents the minimal guaranteed lifetime of the object being addressed. Uses of derived addresses
may be extended up to the ends of this scope without violating ownership.
.liveOut objects (@in_guaranteed, @out and globals) have no instruction range.
.local objects (alloc_stack, yield, @in, @inout) report the single live range of the full assignment that reaches
this address.
.owned values (boxes and references) simply report OSSA liveness.
.borrow values report each borrow scope's range. The effective live range is their intersection. A valid use must
lie within
Compute the live range for the borrow scopes of a guaranteed value. This returns a separate instruction range for
each of the value's borrow introducers. Unioning those ranges would be incorrect. We typically want their
intersection.
Only rewrite the mark_dependence to depend on the function argument when the
dependent value is actually returned.
Also, find all uses even if an escaping use is seen.
This avoids a lot of confusion because the callers expect this type. Fixing it just required some redundancy and
bridging in the EnclosigValues implementation.
To make the ScopedInstruction abstraction useful and formalize to use-points of scoped operations.
This is specifically for scoped operations that use their operands up to the end of their scope.
This is not for the many instructions that introduce scoped lifetimes. Allocations are not considered scoped
operations. Every owned value has a scoped lifetime just like an allocation, but the scope-ending instructions are not
considered use points.
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
This fixes all analyses that use AccessUtils in the presence of new
forwarding instructions. This is also needed for consistency with the
C++ source base. And for general sanity.
Utilities that walk the use-def chain should never hard-code a list of
opcodes that happened to work with some specific pass. Passes should
never assume that a basic SIL utility handles specific SIL operations
a certain way. Instead, the utility needs to be defined in terms of
SIL semantics. In this case, the utility is supposed to handle all
instructions that semantically forward ownership of a reference.
Mirror isIdentityPreservingRefCase.
I don't know why this does not apply to boxes and existentials, but am convervatively staying consistent with the
current behavior.
These instructions carry lifetime dependence from a single operand to a single result. They are not forwarding
instructions because we use them to indicate the boundaries of a forwarded lifetime.
* add ForwardingInstruction conformances to missing forwarding instruction classes
* move all the forwarding instruction conformance definitions into ForwardingInstructions.swift
* remove the default implementations of the requirements, so that every instruction needs to specify them