We were missing adding witness methods of not-specialized witness tables.
This resulted in functions not being processed which led to crashes in IRGen.
rdar://158224693
Look through `@_rawLayout` projections, which "type casts" a raw-layout struct to it's content, which must match the like-type of the raw-layout, e.g.
```
@_rawLayout(like: T)
struct S {}
%2 = builtin "addressOfRawLayout"<S>(%1 : $*S) : $Builtin.RawPointer
%3 = pointer_to_address %2 to $*T
```
If the conformance is abstract the witness table is specialized elsewhere - at the place where the concrete conformance is referenced.
Fixes a compiler crash.
add `Test`, which is the SIL-equivalent of `FunctionTest`.
It's invocation closure gets a `TestContext` instead of a `FunctionContext`.
^ The commit message #2 will be skipped:
^ - test
This allows to move many SIL APIs and utilities, which require a context, to the SIL module.
The SIL-part of SwiftPassInvocation is extracted into a base class SILContext which now lives in SIL.
Also: simplify the begin/end-pass functions of the SwiftPassInvocation.
We insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses.
end_cow_mutation_addr can be simplified to end_cow_mutation after other optimizations like inlining, specialization etc
This PR adds an instruction simplification to transform end_cow_mutation_addr to end_cow_mutation.
This can enable array optimizations which look for end_cow_mutation.
Previously, AutoDiff closure specialization pass was triggered only on
VJPs containing single basic block. However, the pass logic allows
running on arbitrary VJPs. This PR enables the pass for all VJPs
unconditionally. So, if the pullback corresponding to multiple-BB VJP
accepts some closures directly as arguments, these closures might become
specialized by the pass. Closures passed via payload of branch tracing
enum are not specialized - this is subject for future changes.
The PR contains several commits.
1. The thing named "call site" in the code is partial_apply of pullback
corresponding to the VJP. This might appear only once, so we drop
support for multiple "call sites".
2. Enhance existing SILOptimizer tests for the pass.
3. Add validation-tests for single basic block case.
4. The change itself - delete check against single basic block.
5. Add validation-tests for multiple basic block case.
6. Add SILOptimizer tests for multiple basic block case.
Bypess lifetime dependence diagnostics completely for immortal values. We did
not do this initially because we wanted to potentially consider a value with a missing
dependency to mean that it could not escape the current function. But now we use
`Void` as a stand-in for immortal values.
This is needed for reassigning a Span/MutableSpan to an empty, immortal
Span:
func inoutToImmortal(_ s: inout RawSpan) {
let tmp = RawSpan(_unsafeBytes: UnsafeRawBufferPointer(start: nil, count: 0))
s = _overrideLifetime(tmp, borrowing: ())
}
Fixes rdar://152572002 ([GH:#81976] Cannot reinitialize inout parameter of type
`MutableSpan<T>?`)
This is needed after running the SSAUpdater, because the updater can insert unnecessary phis in the middle of the original liverange of a value.
Fixes an ownership error.
rdar://153229472
Add a fake use for dead-end blocks. This allows gatherKnownLifetimeUses to be
used for local liveness by considering an "unreachable" instruction to generate
liveness. This is important when liveness is used as a boundary within which
access scopes may be extended. Otherwise, we are unable to extend access scopes
into dead-end blocks.
Fixes rdar://154406790 (Lifetime-dependent variable 'X' escapes its
scope but only if actor/class is final)
This overload is disfavored to make sure that it's only used for cases
that don't involve literals, for that `==(StringRef, StaticString) -> Bool`
is preferred. Otherwise these overloads are going to be ambiguous
because both `StringRef`, `StaticString` conform to `ExpressibleByStringLiteral`.
Consider the following example:
```swift
func test(lhs: StringRef) {
lhs == "<<test>>"
}
```
The type-checker used to pick `==(StringRef, StringRef)` overload in this
case because it has homogenous parameter types but this is no longer the
case because this behavior was too aggressive and led to sub-optimal choices
by completely skipping other viable overloads.
Since `StaticString` already represents literals it's better to use
a standard library type and reserve the `(StringRef, StringRef)`
overload to when the literals are not involved.
Resolves: rdar://154719565
Unlike addresses of indirect arguments, a pointer argument (e.g. `UnsafePointer`) can escape a function call.
For example, it can be returned.
Fixes a miscompile
rdar://154124497
switch_enum_addr was being treated like a store instruction, which killed
the local enum's liveness. This could result local variable analysis reporting a
shorter lifetime for the local.
This showed up as a missing exclusivity diagnostic because an access scope was
not fully extended across a dependent local variable of Optional type.
This prevents the following pattern from miscompiling. It should report an exclusivity violation:
var mutableView = getOpaqueOptionalView(holder: &holder)!
mutate(&holder)
mutableView.modify()
Fixes rdar://151231236 ([~Escapable] Missing 'overlapping acceses' error when
called from client code, but exact same code produces error in same module)
This peephole optimization also combined the instructions if the `destroy_addr` appears before the `copy_addr` in the same basic block.
https://github.com/swiftlang/swift/issues/82466
rdar://154236276
This fix enables exclusive access to a MutableSpan created from an UnsafeMutablePointer.
The compiler has a special case that allows MutableSpan to depend on a mutable
pointer *without* extending that pointer's access scope. That lets us implement
standard library code like this:
mutating public func extracting(droppingLast k: Int) -> Self {
//...
let newSpan = unsafe Self(_unchecked: _pointer, byteCount: newCount)
return unsafe _overrideLifetime(newSpan, mutating: &self)
Refine this special case so that is does not apply to inout parameters where the
programmer has an expectation that the unsafe pointer is not copied when being
passed as an argument. Now, we safely get an exclusivity violation when creating
two mutable spans from the same pointer field:
@lifetime(&self)
mutating func getSpan() -> MutableSpan<T> {
let span1 = makeMutableSpan(&self.pointer)
let span2 = makeMutableSpan(&self.pointer) // ERROR: overlapping access
return span1
}
If we don't fix this now, it will likely be source breaking in the future.
Fixes rdar://153745332 (Swift allows constructing two MutableSpans to the same underlying pointer)
Consider an empty tuple to be a value introducer rather than a forwarding
instruction.
Fixes rdar://153978086 ([nonescapable] compiler crash with dependency on an
expression)
Do not eliminate a mark_dependence on a begin_apply scope even though the token
has a trivial type.
Ideally, token would have a non-trivial Builtin type to avoid special cases.
This pass replaces `alloc_box` with `alloc_stack` if the box is not escaping.
The original implementation had some limitations. It could not handle cases of local functions which are called multiple times or even recursively, e.g.
```
public func foo() -> Int {
var i = 1
func localFunction() { i += 1 }
localFunction()
localFunction()
return i
}
```
The new implementation (done in Swift) fixes this problem with a new algorithm.
It's not only more powerful, but also simpler: the new pass has less than half lines of code than the old pass.
The pass is invoked in the mandatory pipeline and later in the optimizer pipeline.
The new implementation provides a module-pass for the mandatory pipeline (whereas the "regular" pass is a function pass).
This is required because the mandatory pass needs to remove originals of specialized closures, which cannot be done from a function-pass.
In the old implementation this was done with a hack by adding a semantic attribute and deleting the function later in the pipeline.
I still kept the sources of the old pass for being able to bootstrap the compiler without a host compiler.
rdar://142756547