This allows to run the NamedReturnValueOptimization only late in the pipeline.
The optimization shouldn't be done before serialization, because it might prevent predictable memory optimizations in the caller after inlining.
It converts a lazily initialized global to a statically initialized global variable.
When this pass runs on a global initializer `[global_init_once_fn]` it tries to create a static initializer for the initialized global.
```
sil [global_init_once_fn] @globalinit {
alloc_global @the_global
%a = global_addr @the_global
%i = some_const_initializer_insts
store %i to %a
}
```
The pass creates a static initializer for the global:
```
sil_global @the_global = {
%initval = some_const_initializer_insts
}
```
and removes the allocation and store instructions from the initializer function:
```
sil [global_init_once_fn] @globalinit {
%a = global_addr @the_global
%i = some_const_initializer_insts
}
```
The initializer then becomes a side-effect free function which let's the builtin-simplification remove the `builtin "once"` which calls the initializer.
* Disallow stores in the return -> argument path. When walking up in the EscapeUtils, it's allowed to follow stores. Therefore stores wouldn't be handled correctly.
* Also make sure that there is a return -> argument path at all
Fixes a wrong address-escaping effect in case the called function copies an indirect argument to a newly created object.
rdar://105133434
If a `debug_step` has the same debug location as a previous or succeeding instruction it is removed.
It's just important that there is at least one instruction for a certain debug location so that single stepping on that location will work.
* split the `PassContext` into multiple protocols and structs: `Context`, `MutatingContext`, `FunctionPassContext` and `SimplifyContext`
* change how instruction passes work: implement the `simplify` function in conformance to `SILCombineSimplifyable`
* add a mechanism to add a callback for inserted instructions
A destroy_addr also involves a read from the address. It's equivalent to a `%x = load [take]` and `destroy_value %x`.
It's also a write, because the stored value is not available anymore after the destroy.
Fixes a compiler crash in SILMem2Reg.
rdar://103879105
This is consistent with `Type.isTrivial`.
Also, introduce corresponding properties in `Value`: `hasTrivialType` and `hasTrivialNonPointerType`, because
1. It's less to type than `Type.isTrivial(in: function)` because `Value` knows in which function it is.
2. It fixes the corner case where value is an `Undef`, which has not parent function.
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.
Computes the side effects for a function, which consists of argument- and global effects.
This is similar to the ComputeEscapeEffects pass, just for side-effects.
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
Replace the `struct EscapeInfo` with a simpler API, just consisting of methods of `ProjectedValue` and `Value`:
* `isEscaping()`
* `isAddressEscaping()`
* `visit()`
* `visitAddress()`
For two reasons:
* We also like to check for assert failures in release builds. Although this could be achieved with `precondition`, it's easy to forget about it and use `assert` instead.
* We need to see the error message in crashlogs of release builds. This is even not the case for `precondition`.
Also, re-export the "Basic" module in "SIL" so that the new assert implementation is also available in the Optimizer module (where all files import SIL).
While I was using the new AccessUtils for a new optimization pass I discovered some areas for improvements. Also I found some bugs.
Changes:
* AccessBase: remove the unhealthy redundancy between `kind` and `baseAddress` types. Now AccessBase is single enum with the relevant base objects/addresses as payloads.
* AccessBase: for `global`, store the `GlobalValue` and not a `global_address` instruction, which is more accurate (because there can be multiple `global_addr`s for a single global variable)
* AccessBase: drop the support for function argument "pointers". The `pointer` is now always a `pointer_to_address` instruction. This also simplifies `PointerIdentification`: either it finds a matching `address_to_pointer` or it bails.
* AccessBase: improve `func isDistinct(from:)`. There are more possibilities to prove that two access bases do not alias.
* AccessBase: replace `var isUniquelyIdentified` with `var hasKnownStorageKind` which is more useful for aliasing checking.
* AccessPath: fix `func isDistinct(from:)`. `SmallProjectionPath.matches` is the wrong way to check if two expression paths may overlap. Instead use the new `SmallProjectionPath.mayOverlap`.
* AccessStoragePathWalker: rename `getAccessStorage` -> `visitAccessStorageRoots` and let it return false if it's not a class/reference AccessBase.
* add tests for `AccessPath.isDistinct(from:)`
* "merge" the `Path` and `State` in WalkUtils into a single `WalkingPath`. This makes it simpler for clients to configure a path and additional state variables. EscapeInfo now defines `EscapePath` which includes the projection path and EscapeInfo's specific state variables.
* Make the `WalkerCache` part of the WalkUtils, so that not all clients have to re-implement it.
* Rename `walkDownResults` -> `walkDownAllResults` and `walkUpOperands` -> `walkUpAllOperands` and make these functions client configurable.
`EscapeInfo` now conforms to the generic protocols defined in `WalkUtils`.
This simplifies the implementation a bit, since trivial instructions are handled
by `WalkUtils` and `EscapeInfo` only has to handle a subset of instructions
inherent to escape information.
Passes using `EscapeInfo` are updated accordingly to become visitors that
customize the `EscapeInfo` walk.
Removes redundant ObjectiveC <-> Swift bridging calls.
Basically, if a value is bridged from ObjectiveC to Swift an then back to ObjectiveC again, then just re-use the original ObjectiveC value.
Also in this commit: add an additional DCE pass before ownership elimination. It can cleanup dead code which is left behind by the ObjCBridgingOptimization.
rdar://89987440
* split the PassUtils.swift file into PassContext.swift and Passes.swift
* rework `Builder` bridging allowing more insertion point variations, e.g. inserting at the end of a block.
* add Builder.create functions for more instructions
* add `PassContext.splitBlock`
* move SIL modification functions from PassContext to extensions of the relevant types (e.g. instructions).
* rename `Location.bridgedLocation` -> `Location.bridged`