and not also drop a subst parameter.
This turned out to be more convenient for certain clients (e.g. SILGenPoly)
than requiring the full subst param list to be passed in. These clients
want to process the subst param list separately, and dropping self early
can be convenient for that. The only fundamental reason we need this
flag is for working with the orig type, so just use it for that; clients
that need to use this feature can reasonably be expected to cooperate.
This is necessary because the use patterns in SILGenPoly require
walking two orig+subst sequences in parallel, which poses problems
for a callback-centric design like the one I addded before. An
inversion of control is necessary; this is basically a manual
coroutine. But frankly it's a nicer interface than the callback
design, too; I switched the implementation of forEachFunctionParam
to use the generator just to avoid code duplication, but I might
try to remove it and switch all the clients over to the generator.
The main problems with the callback design are that (1) I wasn't
sure which values clients would want, and the result is that there
are a *lot* of parameters and (2) (relatedly) the types of those
parameters have to be written out explicitly, and some of them
are quite large. The generator code is just much nicer. Maybe
I can still give the generator a little unparameterized callback
to keep lexical loops simple.
I'll need to do this same thing for tuples. One at a time.
This still does not have the complete behavior that we want since we are not yet
inserting the debug_value undef to invalidate after performing moves.
NOTE: In printed SIL, I decided to make the flag implicit if we have a
noncopyable type. This is just to reduce the bloat in SIL. If one needs this
property for a copyable type though, it is mandatory.
This is in preparation for wiring up debug info support for noncopyable
values. Originally this flag name made sense since it was set when we performed
consume operator checking. Now I am going to use it for noncopyable types as
well. I think the new name uses_moveable_value_debuginfo actually describes what
the flag is supposed to do, tell IRGen that the value may be moved since it
needs to use moveable value debug info emission.
Moves from limited use values are redundant. When a move separates a
non-escaping lifetime from an escaping lifetime, it is still redundant
if the original lifetime couldn't be optimized because it's already as
small as possible.
As I've been iterating on this work, I've been gradually mulling these
over, and I think this is the way to go for now. These should make it
a lot less cumbersome to write these kinds of traversals correctly.
The intent is to the sunset the existing expanded-components stuff
after I do a similar pass for function parameters.
A type (mostly classes) can be attributed with `@_semantics("arc.immortal")`.
ARC operations on values of such types are eliminated.
This is useful for the bridged SIL objects in the swift compiler sources.
Instead of doing the type casts and/or conformance lookup on the swift side, do it on the C++ side.
It makes a significant performance difference because `Operand.value` is a time critical function
Previously it was testing for opened existentials specifically.
We should really teach outlining to handle local archetypes properly.
We'd have to build a generic signature for the lowered type, and that
probably means also adding requirements that are relevant to value
operations, but it would mean outlining would benefit all types, and
it would let us avoid bundling in unnecessary information from the
enclosing generic environment.
A minor side-effect of this is that we no longer bind names to
opened element type values. The names were things like \tau_1_0,
which is not very useful, especially in LLVM IR where \tau is
printed with two UTF-8 escapes.
There is a preexisting function with this name that takes a
BorrowedValue. The new function calls that preexisting function if a
BorrowedValue can be constructed from the SILValue. Otherwise, it looks
for direct uses of the value which qualify as "pointer escapes".
More missing infrastructure. In this case, it's really *existing*
missing infrastructure, though; we should have been imploding tuples
this way all along, given that we're doing it in the first place.
I don't like that we're doing all these extra tuple copies. I'm not
sure yet if they're just coming out of SILGen and eliminated immediately
after in practice; maybe so. Still, it should be obvious that they're
unnecessary.
`isSuccessorBlock` and `isPredecessorBlock` are dangerous because they can easily lead to quadratic behavior.
Fortunately they are not used anywhere (except in one place for verification, which I rewrote).
This required quite a bit of infrastructure for emitting this kind of
tuple expression, although I'm not going to claim they really work yet;
in particular, I know the RValue constructor is going to try to explode
them, which it really shouldn't.
It also doesn't include the caller side of returns, for which I'll need
to teach ResultPlan to do the new abstraction-pattern walk. But that's
next.
Add a separate 'verifyOwnership()' entry point so it's possible
to check OSSA lifetimes at various points.
Move SILGenCleanup into a SILGen pass pipeline.
After SILGen, verify incomplete OSSA.
After SILGenCleanup, verify ownership.
Add local lifetime-ending operations to any owned or borrowed value.
This puts a single value into valid OSSA form so that linear lifetime
checking will pass.
Also adds UnreachableLifetimeCompletion which fixes OSSA after
converting a code path to unreachable (e.g. DiagnoseUnreachable and MandatoryInlining).
This allows the AP to answer questions like how many
elements/parameters in the substituted type correspond to
this pack expansion.
I've threaded this through a lot of cases for foreign patterns
that probably won't ever need it.
It's essential that a non-escaping closure will be treated as having a relevant type for escape analysis.
Because if it's capturing an (inout) address it's like it's storing a pointer to the captured variable in its context.
Adds test cases for rdar://105676825
CSE relies on OSSA RAUW for lifetime extension when replacing a redundant instruction.
OSSA RAUW however does not handle lifetime extension for escaped base values.
Values escape from ownership via pointer escape, bitwise escape, forwarding unowned operations
and have none or unowned ownership. For all such values do not look through ownership instructions
while determining equality. It is possible to CSE such values with equivalent operands, because the
operand use guarantees lifetime of the base operand.