ClosureLifetimeFixup now emits mark_dependence [nonescaping]. Those should be
ignored by diagnostics. In the capture case, the dependence has already been
resolved, and may not match the SIL patterns that we expect for source-level
lifetime dependencies.
Fixes rdar://125375685 ([nonescapable] Fix lifetime-dependence diagnostics in the stdlib)
Don't treat StoreBorrow addresses as unknown bases. While they are never the base of a formal access, they are returned
as the AccessBase when querying the enclosing scope of an address.
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!"))
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.
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
These were always redundant. And there is no way to emit them
correctly for valid OSA when the original dependence scope is in the
caller.
NFC without:
-enable-experimental-feature NonescapableTypes
-enable-lifetime-dependence-diagnostics
An object with tail allocated elements is in risk of being passed to malloc_size, which does not work for non-heap allocated objects.
Conservatively, disable objects with tail allocations.
rdar://121886093
Usually resilient classes cannot be promoted anyway, because their initializers are not visible and let the object appear to escape.
But in some rare situations this check is needed.
rdar://121558570
Add a new mandatory BooleanLiteralFolding pass which constant folds conditional branches with boolean literals as operands.
```
%1 = integer_literal -1
%2 = apply %bool_init(%1) // Bool.init(_builtinBooleanLiteral:)
%3 = struct_extract %2, #Bool._value
cond_br %3, bb1, bb2
```
->
```
...
br bb1
```
This pass is intended to run before DefiniteInitialization, where mandatory inlining and constant folding didn't run, yet (which would perform this kind of optimization).
This optimization is required to let DefiniteInitialization handle boolean literals correctly.
For example in infinite loops:
```
init() {
while true { // DI need to know that there is no loop exit from this while-statement
if some_condition {
member_field = init_value
break
}
}
}
```
```
let c = SomeClass()
```
is turned into
```
private let outlinedVariable = SomeClass() // statically initialized and allocated in the data section
let c = outlinedVariable
```
rdar://111021230
rdar://115502043
Also, make the ObjectOutliner work for OSSA. Though, it currently doesn't run in the OSSA pipeline.
Optionally, the dependency to the initialization of the global can be specified with a dependency token `depends_on <token>`.
This is usually a `builtin "once"` which calls the initializer for the global variable.
Layers:
- FunctionConvention: AST FunctionType: results, parameters
- ArgumentConventions: SIL function arguments
- ApplyOperandConventions: applied operands
The meaning of an integer index is determined by the collection
type. All the mapping between the various indices (results,
parameters, SIL argument, applied arguments) is restricted to the
collection type that owns that mapping. Remove the concept of a
"caller argument index".
By default it lowers the builtin to an `alloc_vector` with a paired `dealloc_stack`.
If the builtin appears in the initializer of a global variable and the vector elements are initialized,
a statically initialized global is created where the initializer is a `vector` instruction.
In regular swift this is a nice optimization. In embedded swift it's a requirement, because the compiler needs to be able to specialize generic deinits of non-copyable types.
The new de-virtualization utilities are called from two places:
* from the new DeinitDevirtualizer pass. It replaces the old MoveOnlyDeinitDevirtualization, which is very basic and does not fulfill the needs for embedded swift.
* from MandatoryPerformanceOptimizations for embedded swift