The body of a function has to be re-analyzed for every call
site of the function, which is very expensive and if the
body is not changed would produce the same result.
This takes about ~10% from swift-syntax overall build time
in release configuration.
Run the swift-frontend in a mode that will generate LLVM IR adding the
option `-print-cond-fail-messages` will dump all cond_fail message strings
encountered in the SIL.
```
% swift-frontend -Xllvm -print-cond-fail-messages -emit-ir/-c ...
cond_fail message encountered: Can't take a prefix of negative length from a collection
cond_fail message encountered: Range out of bounds
cond_fail message encountered: Array index is out of range
```
We need to consider that archetypes (generic types) can be existentials if they conform to self-conforming protocols.
Fixes a miscompile
rdar://147269904
The standard library uses `_precondition` calls which have a message argument.
Allow disabling the generated cond_fail by these message arguments.
For example:
_precondition(source >= (0 as T), "Negative value is not representable")
Results in a `cond_fail "Negative value is not representable"`.
This commit allows for specifying a file that contains these messages on
each line.
/path/to/disable_cond_fails:
```
Negative value is not representable
Array index is out of range
```
The optimizer will remove these cond_fails if the swift frontend is invoked with
`-Xllvm -cond-fail-config-file=/path/to/disable_cond_fails`.
* move the "SILCombine passes" into a separate file `Simplifications.def` which lives in the SILCombiner directory
* group passes by kind
* rename PASS -> LEGACY_PASS and add a comment to make clear that new passes should be implemented in Swift
NFC
Casts always work with formal rather than lowered types.
This fixes a potential bug when lowered types are different than formal types, like function types.
OSLogOptimization pass
The OSLogOptimization pass constant evaluates and folds SIL instructions
that are inlined from the construction of the string interpolations passed
to the log calls, which enables replacing the dynamic format string construction
with a static format string. In addition to folding constant strings, it also folds
constant integers and arrays whose elements are constants. This change makes it
skip folding static strings, since they are already efficiently represented.
rdar://146028438
When checking for false positives, we want to make sure that if a
debug_value is dropped, we also find a real instruction that shares
the same scope as the debug_value or has a scope that is a child
of the scope of the debug_value, and has an inlinedAt equal to the
inlinedAt of the debug_value or it's inlinedAt chain contains the
inlinedAt of the debug_value. However, this instruction shouldn't be
another debug_value.
The check was supossed to check if(!I.isDebugInstruction())
but it checked if(I.isDebugInstruction())
This patch fixes that bug.
It appears that we can end up breaking this assertion when inlining
SIL from modules with strict concurrency enabled into modules that
don't. That's not a assertion-worth condition.
Instructions in a block, which is moved, must not use any (non-trivial) value because we don't do liveness analysis.
When moving a block, there is no guarantee that the operand value is still alive at the new location.
Fixes an ownership violation error
rdar://146630743
Copy propagation does these optimizations more generally. It should be
able to replace this optimization. Fixing it and not just deleting CopyValueOpts
because it happens to be called in the mandatory pipeline.
* Reimplement most of the logic in Swift as an Instruction simplification and remove the old code from SILCombine
* support more cases of existential archetype replacements:
For example:
```
%0 = alloc_stack $any P
%1 = init_existential_addr %0, $T
use %1
```
is transformed to
```
%0 = alloc_stack $T
use %0
```
Also, if the alloc_stack is already an opened existential and the concrete type is known,
replace it as well:
```
%0 = metatype $@thick T.Type
%1 = init_existential_metatype %0, $@thick any P.Type
%2 = open_existential_metatype %1 : $@thick any P.Type to $@thick (@opened("X", P) Self).Type
...
%3 = alloc_stack $@opened("X", any P) Self
use %3
```
is transformed to
```
...
%3 = alloc_stack $T
use %3
```
If an apply uses an existential archetype (`@opened("...")`) and the concrete type is known, replace the existential archetype with the concrete type
1. in the apply's substitution map
2. in the arguments, e.g. by inserting address casts
For example:
```
%5 = apply %1<@opend("...")>(%2) : <τ_0_0> (τ_0_0) -> ()
```
->
```
%4 = unchecked_addr_cast %2 to $*ConcreteType
%5 = apply %1<ConcreteType>(%4) : <τ_0_0> (τ_0_0) -> ()
```
Replace `unconditional_checked_cast` to an existential metatype with an `init_existential_metatype`, it the source is a conforming type.
Note that init_existential_metatype is better than unconditional_checked_cast because it does not need to do any runtime casting.
So far a `SILCombineSimplifiable` could only replace a SILCombine visit implementation.
With the `SWIFT_SILCOMBINE_PASS_WITH_LEGACY` (to be used in Passes.def) it's possible to keep an existing C++ implementation and on top of that add a Swift Simplification pass.
Handle open_existential_ref instructions which cast keypath instructions before they are passed to a partial_apply.
In Swift language mode 6 keypaths are existentials (e.g. `any WritableKeyPath<Str, Int> & Sendable`) and we need to deal with that in CapturePropagation.
rdar://141370412
TempLValueOpt eliminates copies from a temporary to destination and
supports hoisting projections of the destination.
An enum is fully initialized with the pair init_enum_data_addr and
inject_enum_addr. Calling destroy_addr only before inject_enum_addr
can cause a runtime crash.
This optimization can eliminate copy_addr and hoist init_enum_data_addr
such that enum is not fully initialized before it's use.
Disable this case for now.
Fixes rdar://145941433
To correctly do this optimization we have to find the corresponding inject_enum_addr
and hoist it as well or ensure the source is not used until fully initialized by inject_enum_addr.