Enable KeyPath/AnyKeyPath/PartialKeyPath/WritableKeyPath in Embedded Swift, but
for compile-time use only:
- Add keypath optimizations into the mandatory optimizations pipeline
- Allow keypath optimizations to look through begin_borrow, to make them work
even in OSSA.
- If a use of a KeyPath doesn't optimize away, diagnose in PerformanceDiagnostics
- Make UnsafePointer.pointer(to:) transparent to allow the keypath optimization
to happen in the callers of UnsafePointer.pointer(to:).
Treat mark_dependence [nonescaping] as a dependent value even if the dependence base does not have a recognizable
scope (e.g. a multiply-defined alloc_stack). This happens because ClosureLifetimeFixup creates redundant mark_dependence
instructions for partial_apply captures. We constantly need to work around this broken representation of nonescaping closures.
Add PartialApplyInst.hasNoescapeCapture
Add PartialApplyInst.mayEscape
Refactor DiagnoseInvalidEscapingCaptures. This may change functionality because tuples containing a noescape closure are now correctly recognized. Although I'm not sure such tupes can ever be captured directly.
SILBoxTypes have their own generic signature and substitution
map. This means that every time we query isEscapable or mayEscape, we
need to extract the type of the box's field and perform type
substitution so that the AST query only sees types from the function's
generic environment.
Fixes rdar://124179106 (Assertion failed in SIL:
(!type->hasTypeParameter() && "caller forgot to mapTypeIntoContext!"))
We've been building up this exponential explosion of task-creation
builtins because it's not currently possible to overload builtins.
As long as all of the operands are scalar, though, it's pretty easy
to peephole optional injections in IRGen, which means we can at
least just use a single builtin in SIL and then break it apart in
IRGen to decide which options to set.
I also eliminated the metadata argument, which can easily be recreated
from the substitutions. I also added proper verification for the builtin,
which required (1) getting `@Sendable` right more consistently and (2)
updating a bunch of tests checking for things that are not actually
valid, like passing a function that returns an Int directly.
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.
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