When branching to the exit block, flatten an @out tuple return value
into its components, as is done for all other return values.
In the exit block, when constructing the @out tuple to return, visit the
tuple-type-tree of the return value to reconstruct the nested tuple
structure: @out tuple returns are not flattened, unlike regular tuple
returns.
The changes for https://github.com/apple/swift/pull/59787 introduced a circular depenendcy between the SIL library and the SILGen library. I have undone this in the cheapest way possible as I don't have bandwidth to look into a more correct fix at the moment.
Previously, to workaround an issue with ShrinkBorrowScope (where it
assumed a reasonable definition of isDeinitBarrier), a placeholder
version of the function was added. It is now removed by moving the
implementation of a version of that predicate back to C++.
This invalidation kind is used when a compute-effects pass changes function effects.
Also, let optimization passes which don't change effects only invalidate the `FunctionBody` and not `Everything`.
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.
Instead of creating and destroying a SILProfiler
per TopLevelCodeDecl, setup a single profiler
for the top-level entry point function, and visit
all the TopLevelCodeDecls when mapping regions.
For now this just wraps an ASTNode, but in the
future it will allow us to model counters
that cannot simply hang off ASTNodes, e.g
error branch counters.
So far, function effects only included escape effects.
This change adds side-effects (but they are not computed, yet).
It also involves refactoring of the existing escape effects.
Also the SIL effect syntax changed a bit. Details are in docs/SIL.rst
* In `ApplySite`: `argumentOperands` and `isCalleeOperand`
* In `ArgumentConvention`: `isIndirect`, `isIndirectIn` and `isGuaranteed`
* In `Function`: `isDefinition`, `numParameterArguments`, `numArguments`, `getArgumentConvention`, `effectAttribute`
* In `Type`: `isFunction` and `isCalleeConsumedFunction`
* In `Instruction`: `hasUnspecifiedSideEffects`
* New bridged instructions: `EndApplyInst` and `AbortApplyInst`
* `LoadInst.ownership`
* `BeginAccessInst.isStatic`
* make the `Allocation` protocol a `SingleValueInstruction` (instead of `AnyObject`)
We can remove a ton of complexity by assuming that SSA uses never
occur before a def in the same block. This will hold true as long as
useless phis are only removed after all unreachable code is first
removed. Then we don't have the self-loop problem.
The SILVerifier already checks this invariant and I added an in-depth
comment in SimplifyCFG.
Computing simple liveness is distinct from computing transitive
liveness. But for safety and consistency, always handle the first
level of liveness transitively. This way, computeSimple can be used on
guaranteed values that need OSSA lifetime fixup.
Simple liveness just means that *inner* borrow and address scopes are
assumed to be complete.
This utility is still only used conservatively because OSSA lifetime
completion is not yet enabled. But, in the future, computeSimple can
be used in the common case.
Start using consistent terminolfy in ownership utils.
A transitive use set follows transitive uses within an ownership
lifetime. It does not rely on complete inner scopes. An extended use
set is not necessarilly transitive but does look across
lifetime-ending uses: copies of owned values and/or reborrows of
guaranteed values. Whether lifetime extension refers to copies or
reborrow is context dependent.