Whenever we have a reference to a foreign function/variable in SIL, use
a mangled name at the SIL level with the C name in the asmname
attribute. The expands the use of asmname to three kinds of cases that
it hadn't been used in yet:
* Declarations imported from C headers/modules
* @_cdecl @implementation of C headers/modules
* @_cdecl functions in general
Some code within the SIL pipeline makes assumptions that the C names of
various runtime functions are reflected at the SIL level. For example,
the linking of Embedded Swift runtime functions is done by-name, and
some of those names refer to C functions (like `swift_retain`) and
others refer to Swift functions that use `@_silgen_name` (like
`swift_getDefaultExecutor`). Extend the serialized module format to
include a table that maps from the asmname of functions/variables over
to their mangled names, so we can look up functions by asmname if we
want. These tables could also be used for checking for declarations
that conflict on their asmname in the future. Right now, we leave it
up to LLVM or the linker to do the checking.
`@_silgen_name` is not affected by these changes, nor should it be:
that hidden feature is specifically meant to affect the name at the
SIL level.
The vast majority of test changes are SIL tests where we had expected
to see the C/C++/Objective-C names in the tests for references to
foreign entities, and now we see Swift mangled names (ending in To).
The SIL declarations themselves will have a corresponding asmname.
Notably, the IRGen tests have *not* changed, because we generally the
same IR as before. It's only the modeling at the SIL lever that has
changed.
Another part of rdar://137014448.
It used to be done with a library intrinsic which returns the array and an element address pointer.
A `mark_dependence` was used to "connect" the two results.
But this resulted in completely wrong OSSA after inlining.
It just didn't get caught be the verifier because the SIL was obfuscated by address-pointer conversions.
Now we don't use the second result (= the element address) of the intrinsic but generate a correct borrow scope from the first (= array) result. Within that borrow scope we project out the element address with a `ref_tail_addr` instruction.
This relies on knowledge of the internal Array data structures. However those data structures are baked into the ABI since a long time and will not change.
If the argument type is an array and it's passed to an imported declaration
that accepts a raw pointer, the solver should use an "array-to-c-pointer"
conversion instead of the one for pointers.
Resolves: rdar://158629300
Type annotations for instruction operands are omitted, e.g.
```
%3 = struct $S(%1, %2)
```
Operand types are redundant anyway and were only used for sanity checking in the SIL parser.
But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:
* if the block with the definition appears after the block where the operand's instruction is located
* if a block or instruction is printed in isolation, e.g. in a debugger
The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
This fixes use-after-free miscompilation bugs that can occur when a
lifetime-optimized standard library type, like Dictionary or String is
converted to an UnsafePointer using implicit inout-to-pointer
conversion:
func ptrToDictionary(_: UnsafePointer<Dictionary<K, V>>) {}
func testDictionary() {
var d: Dictionary = ...
ptrToDictionary(&d)
}
func ptrToString(_: UnsafePointer<String>) {}
func testString() {
var s: String = ...
ptrToString(&s)
}
Address to pointer conversion must always be guarded by either a
mark_dependence or a fix_lifetime. Use fix_lifetime for call emission
in SILGen to limit the optimization impact to the narrow scope of the
pointer conversion.
This could negatively impact performance simply because SIL does not
provide a way to scope pointer conversion. fix_lifetime is
unnecessarilly conservative and prevents the elimination of dead
allocations.
rdar://117807309 (Fix SILGen to emit fix_lifetime for
inout-to-pointer conversion)
Types that have "value semantics" should not have lexical lifetimes.
Value types are not expected to have custom deinits. Are not expected to
expose unsafe interior pointers. And cannot have weak references because
they are structs. Therefore, deinitialization barriers are irrelevant.
rdar://107076869
The problem here is that the AutoreleasingUnsafeMutablePointer's LValue
component would given the following Swift:
```
public class C {}
@inline(never)
func updateC(_ p: AutoreleasingUnsafeMutablePointer<C>) -> () {
p.pointee = C()
}
public func test() -> C {
var cVar = C()
updateC(&cVar)
return cVar
}
```
generate the following SIL as part of setting cVar after returning from updateC.
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
assign %22 to %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
Once we are in Canonical SIL, we get the following SIL:
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
store %22 to [assign] %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
which destroy hoisting then modifies by hoisting the destroy by the store assign
before the copy_value:
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
destroy_addr %7 : $*C
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
store %22 to [init] %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
Given the appropriate Swift code, one could have that %21 is actually already
stored in %7 and has a ref count of 1. In such a case, the destroy_addr would
cause %21 to be deallocated before we can retain the value.
In order to fix this edge case as a bug fix, in the setter for
AutoreleasingUnsafeMutablePointer, we introduce a mark_dependence from the
copied value onto the memory. This ensures that destroy hoisting does not hoist
the destroy_addr past the mark_dependence, yielding correctness. That is we
generate the following SIL:
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
%23 = mark_dependence %22 : $C on %7 : $*C
assign %23 to %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
For those unfamiliar, mark_dependence specifies that any destroy of the memory
in %7 can not move before any use of %23.
rdar://99402398
Previously we gave them the same SIL linkage as the method, then changed
the LLVM IR linkage to 'internal' (which is roughly equivalent to
SIL 'private') in IRGen.
This would crash in the SIL verifier if an @objc method was
'@_alwaysEmitIntoClient'. While such a combination of attributes is
silly since '@objc' methods are intrinsically part of the ABI, we
should not crash in this case.
The simplest fix is to just set the linkage to private at the SIL
level, avoiding the IRGen hack entirely.
In order to allow this, I've had to rework the syntax of substituted function types; what was previously spelled `<T> in () -> T for <X>` is now spelled `@substituted <T> () -> T for <X>`. I think this is a nice improvement for readability, but it did require me to churn a lot of test cases.
Distinguishing the substitutions has two chief advantages over the existing representation. First, the semantics seem quite a bit clearer at use points; the `implicit` bit was very subtle and not always obvious how to use. More importantly, it allows the expression of generic function types that must satisfy a particular generic abstraction pattern, which was otherwise impossible to express.
As an example of the latter, consider the following protocol conformance:
```
protocol P { func foo() }
struct A<T> : P { func foo() {} }
```
The lowered signature of `P.foo` is `<Self: P> (@in_guaranteed Self) -> ()`. Without this change, the lowered signature of `A.foo`'s witness would be `<T> (@in_guaranteed A<T>) -> ()`, which does not preserve information about the conformance substitution in any useful way. With this change, the lowered signature of this witness could be `<T> @substituted <Self: P> (@in_guaranteed Self) -> () for <A<T>>`, which nicely preserves the exact substitutions which relate the witness to the requirement.
When we adopt this, it will both obviate the need for the special witness-table conformance field in SILFunctionType and make it far simpler for the SILOptimizer to devirtualize witness methods. This patch does not actually take that step, however; it merely makes it possible to do so.
As another piece of unfinished business, while `SILFunctionType::substGenericArgs()` conceptually ought to simply set the given substitutions as the invocation substitutions, that would disturb a number of places that expect that method to produce an unsubstituted type. This patch only set invocation arguments when the generic type is a substituted type, which we currently never produce in type-lowering.
My plan is to start by producing substituted function types for accessors. Accessors are an important case because the coroutine continuation function is essentially an implicit component of the function type which the current substitution rules simply erase the intended abstraction of. They're also used in narrower ways that should exercise less of the optimizer.
In a previous commit, I banned in the verifier any SILValue from producing
ValueOwnershipKind::Any in preparation for this.
This change arises out of discussions in between John, Andy, and I around
ValueOwnershipKind::Trivial. The specific realization was that this ownership
kind was an unnecessary conflation of the a type system idea (triviality) with
an ownership idea (@any, an ownership kind that is compatible with any other
ownership kind at value merge points and can only create). This caused the
ownership model to have to contort to handle the non-payloaded or trivial cases
of non-trivial enums. This is unnecessary if we just eliminate the any case and
in the verifier separately verify that trivial => @any (notice that we do not
verify that @any => trivial).
NOTE: This is technically an NFC intended change since I am just replacing
Trivial with Any. That is why if you look at the tests you will see that I
actually did not need to update anything except removing some @trivial ownership
since @any ownership is represented without writing @any in the parsed sil.
rdar://46294760
This is the last part of SILGen conditionalized on EnableSILOwnership being
set. It also (as you can tell from the diff) eliminates a bunch of code from the
tests.
rdar://29791263
The constraint solver support for the Swift 3 function type behavior
has been removed, so it's no longer possible to pun the same value as
both a function taking multiple parameters and a function taking a
single tuple argument.
This means the entire parameter list is no longer a target for
substitution as a single value, so the most general form of a function
value passes each parameter indirectly instead of passing a single
tuple parameter indirectly.
The SILGen testsuite consists of valid Swift code covering most language
features. We use these tests to verify that no unknown nodes are in the
file's libSyntax tree. That way we will (hopefully) catch any future
changes or additions to the language which are not implemented in
libSyntax.
I am going to leave in the infrastructure around this just in case. But there is
no reason to keep this in the tests themselves. I can always just revert this
and I don't think merge conflicts are likely due to previous work I did around
the tooling for this.
Otherwise, the plus_zero_* tests will have plus_zero_* as a module name, causing
massive FileCheck problems.
The reason why I am doing it with the main tests is so that I can use it when
syncing branches/etc.
radar://34222540
The array or string has to be kept alive past the call. John fixed
this back in 733915f but I want to make sure it doesn't regress.
rdar://problem/31325077 (originally fixed as rdar://problem/31542269,
also reported as SR-3231)
conversions and extend lifetimes over the call.
Apply this logic to string-to-pointer conversions as well as
array-to-pointer conversions.
Fix the AST verifier to not blow up on optional pointer conversions,
and make sure we SILGen them correctly. There's still an AST bug
here, but I'll fix that in a follow-up patch.
Officially kick SILBoxType over to be "nominal" in its layout, with generic layouts structurally parameterized only by formal types. Change SIL to lower a capture to a nongeneric box when possible, or a box capturing the enclosing generic context when necessary.
Use a syntax that declares the layout's generic parameters and fields,
followed by the generic arguments to apply to the layout:
{ var Int, let String } // A concrete box layout with a mutable Int
// and immutable String field
<T, U> { var T, let U } <Int, String> // A generic box layout,
// applied to Int and String
// arguments