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.
Now that
- owned arguments don't get lexical borrow scopes from SILGen
- owned arguments get lexical moves during inlining unless the value
passed for that argument is already lexical
- guaranteed arguments don't get lexical borrow scopes during inlining
when the value passed for that argument is already lexical
tests involving owned argument emission from SILGen and inlining need to
be updated.
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
There was a special case here to type-check `T.init` as a single closure
`{ args.. in T.init(args..) }`, but really, we can do that for any static
member applied to a static metatype base, including operators.
Also fix SILGen's function conversion peephole so it looks through
`as (T...) -> U` coercions that don't involve bridging.
The old syntax was
@opened("UUID") constraintType
Where constraintType was the right hand side of a conformance requirement.
This would always create an archetype where the interface type was `Self`,
so it couldn't cope with member types of opened existential types.
Member types of opened existential types is now a thing with SE-0309, so
this lack of support prevented writing SIL test cases using this feature.
The new syntax is
@opened("UUID", constraintType) interfaceType
The interfaceType is a type parameter rooted in an implicit `Self`
generic parameter, which is understood to be the underlying type of the
existential.
Fixes rdar://problem/93771238.
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.
This is kind of complicated, because an enum can be trivial for one case and not trivial for another case. We need to check at which parts of the function we can prove that the enum does (or could) have a trivial case. In such a branch, it's not required in SIL to destroy the enum location.
Also, document the rules and requirements for enum memory locations in SIL.rst.
rdar://73770085
When a method is called with fewer than two parameter lists,
transform it into a fully-applied call by wrapping it in a
closure.
Eg,
Foo.bar => { self in { args... self.bar(args...) } }
foo.bar => { self in { args... self.bar(args...) } }(self)
super.bar => { args... in super.bar(args...) }
With this change, SILGen only ever sees fully-applied calls,
which will allow ripping out some code.
This new way of doing curry thunks fixes a long-standing bug
where unbound references to protocol methods did not work.
This is because such a reference must open the existential
*inside* the closure, after 'self' has been applied, whereas
the old SILGen implementation of curry thunks really wanted
the type of the method reference to match the opened type of
the method.
A follow-up cleanup will remove the SILGen curry thunk
implementation.
Fixes rdar://21289579 and https://bugs.swift.org/browse/SR-75.
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
To make that work, enter appropriate scopes (ArgumentScopes and
FormalEvaluationScopes) at a bunch of places. But note that l-value
emission generally can't enter such a scope, so in generic routines
like emitOpenExistentialExpr we have to just assert that we're
already in a scope.
This does not eliminate the entrypoints on SILBuilder yet. I want to do this in
two parts so that it is functionally easier to disentangle changing the APIs
above SILBuilder and changing the underlying instruction itself.
rdar://33440767
This is how we originally controlled whether or not we printed out ownership
annotations when we printed SIL. Since then, I have changed (a few months ago I
believe) the ownership model eliminator to know how to eliminate these
annotations from the SIL itself. So this hack can be removed.
As an additional benefit, this will let me rename -enable-sil-ownership to
-enable-sil-ownership-verifier. This will I hope eliminate confusion around this
option in the short term while I am preparing to work on semantic sil again.
rdar://42509812
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
Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it
from the type system.
Enable the code that generates disjunctions for Optional<T> and
rewrites expressions based on the original declared type being 'T!'.
Most of the changes supporting this were previously merged to master,
but some things were difficult to merge to master without actually
removing IUOs from the type system:
- Dynamic member lookup and dynamic subscripting
- Changes to ensure the bridging peephole still works
Past commits have attempted to retain as much fidelity with how we
were printing things as possible. There are some cases where we still
are not printing things the same way:
- In diagnostics we will print '?' rather than '!'
- Some SourceKit and Code Completion output where we print a Type
rather than Decl.
Things like module printing via swift-ide-test attempt to print '!'
any place that we now have Optional types that were declared as IUOs.
There are some diagnostics regressions related to the fact that we can
no longer "look through" IUOs. For the same reason some output and
functionality changes in Code Completion. I have an idea of how we can
restore these, and have opened a bug to investigate doing so.
There are some small source compatibility breaks that result from
this change:
- Results of dynamic lookup that are themselves declared IUO can in
rare circumstances be inferred differently. This shows up in
test/ClangImporter/objc_parse.swift, where we have
var optStr = obj.nsstringProperty
Rather than inferring optStr to be 'String!?', we now infer this to
be 'String??', which is in line with the expectations of SE-0054.
The fact that we were only inferring the outermost IUO to be an
Optional in Swift 4 was a result of the incomplete implementation of
SE-0054 as opposed to a particular design. This should rarely cause
problems since in the common-case of actually using the property rather
than just assigning it to a value with inferred type, we will behave
the same way.
- Overloading functions with inout parameters strictly by a difference
in optionality (i.e. Optional<T> vs. ImplicitlyUnwrappedOptional<T>)
will result in an error rather than the diagnostic that was added
in Swift 4.1.
- Any place where '!' was being used where it wasn't supposed to be
allowed by SE-0054 will now treat the '!' as if it were '?'.
Swift 4.1 generates warnings for these saying that putting '!'
in that location is deprecated. These locations include for example
typealiases or any place where '!' is nested in another type like
`Int!?` or `[Int!]`.
This commit effectively means ImplicitlyUnwrappedOptional<T> is no
longer part of the type system, although I haven't actually removed
all of the code dealing with it yet.
ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly
unwrapped Optional<T>!
Resolves rdar://problem/33272674.
* [runtime] Clean up symbols in error machinery.
* [runtime] Clean up symbols in Foundation overlay.
* [runtime] Clean up symbols in collections and hashing.
* [runtime] Remove symbol controls from the Linux definition of swift_allocError.
* [tests] Add more stub functions for tests that link directly to the runtime.
Support for @noescape SILFunctionTypes.
These are the underlying SIL changes necessary to implement the new
closure capture ABI.
Note: This includes a change to function name mangling that
primarily affects reabstraction thunks.
The new ABI will allow stack allocation of non-escaping closures as a
simple optimization.
The new ABI, and the stack allocation optimization, also require
closure context to be @guaranteed. That will be implemented as the
next step.
Many SIL passes pattern match partial_apply sequences. These all
needed to be fixed to handle the convert_function that SILGen now
emits. The conversion is now needed whenever a function declaration,
which has an escaping type, is passed into a @NoEscape argument.
In addition to supporting new SIL patterns, some optimizations like
inlining and SIL combine are now stronger which could perturb some
benchmark results.
These underlying SIL changes should be merged now to avoid conflicting
with other work. Minor benchmark discrepancies can be investigated as part of
the stack-allocation work.
* Add a noescape attribute to SILFunctionType.
And set this attribute correctly when lowering formal function types to SILFunctionTypes based on @escaping.
This will allow stack allocation of closures, and unblock a related ABI change.
* Flip the polarity on @noescape on SILFunctionType and clarify that
we don't default it.
* Emit withoutActuallyEscaping using a convert_function instruction.
It might be better to use a specialized instruction here, but I'll leave that up to Andy.
Andy: And I'll leave that to Arnold who is implementing SIL support for guaranteed ownership of thick function types.
* Fix SILGen and SIL Parsing.
* Fix the LoadableByAddress pass.
* Fix ClosureSpecializer.
* Fix performance inliner constant propagation.
* Fix the PartialApplyCombiner.
* Adjust SILFunctionType for thunks.
* Add mangling for @noescape/@escaping.
* Fix test cases for @noescape attribute, mangling, convert_function, etc.
* Fix exclusivity test cases.
* Fix AccessEnforcement.
* Fix SILCombine of convert_function -> apply.
* Fix ObjC bridging thunks.
* Various MandatoryInlining fixes.
* Fix SILCombine optimizeApplyOfConvertFunction.
* Fix more test cases after merging (again).
* Fix ClosureSpecializer. Hande convert_function cloning.
Be conservative when combining convert_function. Most of our code doesn't know
how to deal with function type mismatches yet.
* Fix MandatoryInlining.
Be conservative with function conversion. The inliner does not yet know how to
cast arguments or convert between throwing forms.
* Fix PartialApplyCombiner.
This replaces the '[volatile]' flag. Now, class_method and
super_method are only used for vtable dispatch.
The witness_method instruction is still overloaded for use
with both ObjC protocol requirements and Swift protocol
requirements; the next step is to make it only mean the
latter, also using objc_method for ObjC protocol calls.
I tried to do a more complex fix, but it will take more time than I have now.
This change at least ensures that we maintain correctness both in terms of the
super types and in terms of the semantic sil verifier.
rdar://31880847
I put in a simple fixup pass (MarkUninitializedFixup) for staging purposes. I
don't expect it to be in tree long. I just did not feel comfortable fixing up in
1 commit all of the passes up to DI.
rdar://31521023
This writeback scope's writeback is handled by the ArgumentScope for argument
emission. Since the scope will be destroyed after argument scope, we get
mismatched scope depths.
rdar://31313534
This fixes a crash when referencing partially-applied methods
from @_inlineable functions.
Also, curry thunks for private methods do not need shared
linkage; private is sufficient.