Instead of looking for a single store to the global in a global-init function, build a GlobalInitValue tree.
This is a data structure representing the init value of the global. It can handle complex InlineArray initializations,
like `init(repeating:)`.
rdar://150859232
Treat `load`-`store` pairs as if they were `copy_addr` instructions.
This can catch more cases. For example it can eliminate unnecessary copies of InlineArray when subscripting it.
rdar://149250346
Beside cleaning up the source code, the motivation for the translation into Swift is to make it easier to improve the pass for some InlineArray specific optimizations (though I'm not sure, yet if we really need those).
Also, the new implementation doesn't contain the optimize-store-into-temp optimization anymore, because this is covered by redundant load elimination.
These APIs are quite convoluted. The checks for var_decl need to be performed in
just the right order. The is a consequence of complexity in the SIL
representation itself, not a problem with the APIs.
It is common for code to accidentally call a less-complete form of the API. It
is essential that they be defined in a central location, and the we get the same
answer whether we start with an Instruction, Argument, or Value. The primary
public interface should always check for debug_value users. The varDecl property
is actually an implementation detail.
It is questionable whether a function like findVarDecl() that returns a basic
property of SIL and does not require arguments should be a property instead. It
is a function to hint that it may scan the use-list, which is not something
we normally want SIL properties to do. Use-lists can grow linearly in function
size. But, again, this is a natural result of the SIL representation and needs
to be considered an implementation detail.
This utility is used by DependentAddressUseDefWalker which now conservatively
follows all possible uses. This could result in the same address being reached
multiple times during a def-use walk. Ensure that we don't infinitely recurse.
There is no small test case for this, but the fix is trivial and standard
practice for such walkers, and this is hit quickly in real usage, so there is no
danger of it regressing.
Fixes rdar://150403948 ([nonescapable] Infinite recursion compiler crash in
lifetime dependence checking)
Correctly generate dependency tracking for functions that return a non-Escapable
existential, such as:
func getMutableSpanWithOpaqueReturn(_ array: inout [Int]) -> any PAny & ~Copyable & ~Escapable
Previously, dependency insertion assumed that @out storage always initialized an
alloc_stack. But existentials are always boxed.
First, add a diagnostic to catch any missing dependency insertions now that
we're past the bootstrapping phase.
Then, generalize handling of dependency insertion to handle any access base as
long as it has a recognizable address source.
Fixes rdar://150388126 (Missing mark_dependence for opaque lifetime dependent
value)
Array/ArraySlice/ContiguousArray have support for mutableSpan property.
These types are "optimized COW" types, we use compiler builtins begin_cow_mutation/end_cow_mutation to
optimize uniqueness checks. Since mutableSpan is a property and not a coroutine there is
no way to schedule the end_cow_mutaton operation at the end of the access.
This can lead to miscompiles in rare cases where we can end up using a stale storage buffer after a cow.
This PR inserts end_cow_mutation_addr to avoid this issue.
Note: We can end up with unnecessary end_cow_mutation_addr. But it is just a barrier to prevent invalid optimizations
and has no impact.
When a coroutine is extended because of a dependent lifetime, extend all scopes
that enclose that coroutine even if the coroutine itself has no lifetime
dependencies.
Fixes rdar://150275147 (Invalid SIL after lifetime dependence fixup involving
coroutines)
Add a note explaining that dependence on closure captures is not
supported. Otherwise, the diagnostics are very confusing:
"it depends on a closure capture; this is not yet supported"
Ensure that we always issue a diagnostic on error, but avoid emitting any notes that don't have source locations.
With implicit accessors and thunks, report the correct line number and indicate which accessor generates the error.
Always check for debug_value users.
Consistently handle access scopes across diagnostic analysis and diagnostic messages.
* rename `ScopedInstruction.endOperands` -> `scopeEndingOperands`
* let them behave the same way. For `load_borrow` there was a difference because `endOperands` didn't consider branches to re-borrow phis.
Briefly (April 2025), RawSpan._extracting, Span._extracting, and UTF8Span.span
returned a borrowed value that depended on a copied argument. Continue to
support those interfaces. The implementations were correct but needed an
explicit _overrideLifetime.
Diagnose a scoped dependence on an argument that inherits its lifetime as an
error:
@lifetime(borrow arg)
func reborrowSpan<T>(_ arg: Span<T>) -> Span<T> { arg }
@lifetime(copy span)
public func testBorrowInheritedArg<T>(_ span: Span<T>) -> Span<T> {
reborrowSpan(span) // expected-error {{lifetime-dependent value escapes its scope}}
}
Fixes: rdar://146319009 ([nonescapable] enforce borrow constraint narrowing of inherited lifetime)
For example:
```
%0 = load %1
copy_addr %1 to %2
```
->
```
%0 = load %1
store %0 to %2
```
This is important for MandatoryRedundantLoadElimination to be able to create statically initialized globals in the mandatory pipeline.
For example:
```
public struct MyStruct {
public static let r: Range<Int> = 1 ..< 3
}
```
gets a statically initialized global, even at Onone, with this improvement.
rdar://149356742
Allow a dependency on a local [read] access scope to be transfered to the
caller's [modify] access.
Fixes rdar://149560133 (Invalid lifetime dependence error when
trying to return Span from an inout argument)
Add support for returnValue phis (e.g. to return an Optional .some or .none).
Fixes rdar://149397018 (Wrapping non escapable in an Optional
(or any copy lifetime wrapper) is an escape)
* move it from the SIL to the AST module (where it belongs)
* change the signature of `diagnose` from `diagnose(location, .some_error)` to `diagnose(.some_error, at: location)`
* add an overload to allow passing a `SIL.Location` directly to `diagnose`
* add a `Diagnostic : Error` utility struct which allows throwing a `Diagnostic`
Add support for extending owned temporary values in addition to access scopes
and borrow scopes. Required for _read accessors in which the coroutine depends
on an owned value.
SwiftCompilerSources for Windows is now fully enabled, so there is no
longer any reason to gate these passes under an OS check.
commit d482ab73bc
Author: Hiroshi Yamauchi <hjyamauchi@gmail.com>
Date: Fri Dec 13 09:24:44 2024 -0800
Update the pinned toolchain for Windows and enable SwiftCompilerSources for Win/ARM64
Fixes a false alarm in case of recursive calls with different type parameters.
For example:
```
protocol P {
associatedtype E: P
}
func noRecursionMismatchingTypeArgs1<T: P>(_ t: T.Type) {
if T.self == Int.self {
return
}
noRecursionMismatchingTypeArgs1(T.E.self)
}
```
With this approach, you cannot tell whether a parameter is addressable only
from the function type. Instead you need the SILValue that will be passed to the
call site.
* let `SIL.Type` conform to `TypeProperties` to share the implementation of common type properties between the AST types and `SIL.Type`
* call references to an `AST.Type` `rawType` (instead of just `type`)
* remove unneeded stuff
* add comments
Otherwise, DestroyHoisting attemps to compute interior liveness
and inserts destoys at the ends. CanonicalizeOSSALifetimes is
designed to do this and not DestroyHoisting.
allLifetimeEndingInstructions collects insertion points for end_borrows,
and can end up having duplicate entries in the case of enums with non payloaded cases.
Unique the entries so we don't end up with multiple end_borrows
Fixes rdar://146212574