Commit Graph

2682 Commits

Author SHA1 Message Date
Slava Pestov
91b980b94d SILGen: Dynamic, curry, foreign thunks should be serializable
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.
2017-03-29 21:35:25 -07:00
Slava Pestov
af11149550 SIL: Implement the [serialized] vs [serializable] distinction
This generalizes a hack where re-abstraction thunks become fragile on contact
with fragile functions.

The old policy was:

- [fragile] functions always serialized
- [reabstraction_thunk] transitively referenced from fragile always serialized

The new policy is:

- [serialized] functions always serialized
- [serializable] functions transitively referenced from serialized functions
  are always serialized
- Most kinds of thunks can now be [serializable], allowing them to be shared
  between serialized and non-serialized code without any issues, as long as the
  body of the thunk is sufficiently "simple" (doesn't reference private
  symbols or performs direct access to resilient types)
2017-03-29 20:09:35 -07:00
Slava Pestov
695a8d2065 Merge pull request #8407 from slavapestov/rename-everything-without-asking-permission
SIL: Terminology change: [fragile] => [serialized]
2017-03-29 20:08:15 -07:00
Slava Pestov
8fe8b89b0f SIL: Terminology change: [fragile] => [serialized]
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.

This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.
2017-03-29 16:47:28 -07:00
Michael Gottesman
79b225ffa8 [silgen] Fix up EnumElementPatternInitialization::emitEnumMatch to use ownership.
This commit does a few things:

1. It uses SwitchEnumBuilder so we are not re-inventing any wheels.
2. Instead of hacking around not putting in a destroy for .None on the fail
pass, just *do the right thing* and recognize that we have a binary case enum
and in such a case, just emit code for the other case rather than use a default
case (meaning no cleanup on .none).

rdar://31145255
2017-03-29 15:36:41 -07:00
Michael Gottesman
6de8e56cbe [silgen] Add APIs for dumping/printing ManagedValues.
Saves a few key strokes in the debugger.
2017-03-29 15:36:12 -07:00
Michael Gottesman
d1e3147652 [silgen] Improve debug dump of DestroyLocalVariable so that it dumps the value that will be destroyed. 2017-03-29 15:36:12 -07:00
Slava Pestov
53759f7126 Use ValueDecl::isDynamic() instead of getAttrs().hasAttribute<DynamicAttr>() 2017-03-29 00:46:43 -07:00
Slava Pestov
af8e7d29f3 SILGen: Remove some dead code 2017-03-28 22:23:29 -07:00
Slava Pestov
13330bb2c9 SILGen: Simplify curry thunks
Now that methods are the only case where we have a function
with multiple parameter lists, we can remove the logic for
forwarding captures (methods cannot have captures), and
simplify what remains to only deal with the case of a single
'self' argument being curried.
2017-03-28 19:40:09 -07:00
Slava Pestov
7138639056 SILGen: Move witness table emission to SILGenType.cpp
And a couple of other small cleanups.
2017-03-28 19:01:33 -07:00
Slava Pestov
97a8ce4776 SILGen: Extract some code into a new SILGenThunk.cpp file
Also replace the crazy templated preEmitFunction() with
something simpler.
2017-03-28 18:54:53 -07:00
Michael Gottesman
56adc0cdb2 [silgen] Make emitTupleDispatchWithOwnership use proper ownership.
rdar://31145255
2017-03-27 16:41:54 -07:00
Michael Gottesman
26b0b72390 [silgen] Eliminate address handling code from emitTupleDispatchWithOwnership. 2017-03-27 16:34:56 -07:00
Michael Gottesman
b69497886c [silgen] Hoist specialization code in emitTupleDispatch so that it does not cause the SIL emission code to be split. 2017-03-27 16:33:38 -07:00
Michael Gottesman
631d20f701 [gardening] Rename two instances of gen => SGF. 2017-03-27 16:31:13 -07:00
Michael Gottesman
022cb547e2 [silgen] Extract out tuple pattern emission for objects whenownership is enabled into its own method. 2017-03-27 16:28:56 -07:00
Michael Gottesman
5cbf589524 Small ease of use convenience APIs. NFC. 2017-03-27 16:00:34 -07:00
swift-ci
3652e3bb57 Merge pull request #8373 from gottesmm/fix_ownership_in_enum_element 2017-03-27 14:19:19 -07:00
swift-ci
fd2e54d9da Merge pull request #8371 from gottesmm/enum_element_refactor_1 2017-03-27 13:43:16 -07:00
Michael Gottesman
eaa229b9f8 [semantic-sil] Make emitEnumElementDispatchWithOwnership conform to ownership.
This means inserting an eager copy on the switch operand, eliminating the
unforwarding, and destroying the copy in the default case as well as the normal
cases.

I did not refactor this code to use the switch enum builder, but at some point
it should be refactored as such.
2017-03-27 13:33:11 -07:00
Michael Gottesman
ba1e9f76d8 [silgen] Copy the body of emitEnumElementDispatch to emitEnumElementDispatchWithOwnership.
The reason I am doing this is that I am going to in the next couple of commits
change enum element dispatch to with or without semantic SIL use proper
ownership.

In this commit, I just did the copy and eliminated any parts of the code that
were predicated on having an address.
2017-03-27 10:28:08 -07:00
Slava Pestov
2dc819d1d1 AST: Introduce new form of TypeBase::getCanonicalType()
I've fixed a few bugs recently where I had to switch
a getCanonicalType() call to instead use the stronger
GenericSignature::getCanonicalTypeInContext().

Avoid the 'if (genericSig = ...)' dance by adding a new
form of TypeBase::getCanonicalType() which takes a
signature, and if it's null, just falls back to the
standard getCanonicalType().
2017-03-27 00:18:26 -07:00
Slava Pestov
efff6a6922 SILGen: Fix a couple of problems with materializeForSet in constrained extensions
- Property defined in constrained extension of a class

- Subscript defined in a constrained extension with non-canonical index type

Fixes <rdar://problem/31222187>.
2017-03-27 00:18:26 -07:00
Slava Pestov
35a5594035 SILGen: Fixes for *static* 'Self'-returning methods
Take a seat and pour yourself a beer because this is
going to get pretty intense.

Recall that class methods that return 'Self', have a
'self' type of @dynamic_self X or @dynamic_self X.Type,
for some class X, based on if the method is an instance
method or a static method.

The instance type of a metatype is not lowered, and we
preserve DynamicSelfType there. This is required for
correct behavior with the SIL optimizer.

For example if you specialize a function that contains a
'metatype $((T) -> Int, T).Type' SIL instruction or
some other metatype of a structural type containing a
generic parameter, we might end up with something like
'metatype $((@dynamic_self X) -> Int, X).Type'
after substitution, for some class 'X'. Note that the
second occurrence of 'X', is in "lowered position" so
the @dynamic_self did, indeed, get stripped away.

So while *values* of @dynamic_self type don't need to
carry the fact that they're @dynamic_self at the SIL
level, because Sema has inserted all the right casts.

Metatypes do though, because when lowering the 'metatype'
instruction, IRGen has to know to emit the type metadata
from the method's 'self' parameter, and not the static
metadata for the exact class type.

Essentially, 'metatype @dynamic_self X.Type' is
the same as 'value_metatype %self : X.Type', except that
the @dynamic_self type can appear inside other structural
types also, which is something we cannot write in the
AST.

This is all well and good, but when lowering a
SILFunctionType we erase @dynamic_self from the 'self'
parameter type because when you *call* such a function
from another function, you are not necessarily calling
it on your own 'self' value. And if you are, Sema
already emitted the right unchecked downcast there to
turn the result into the right type.

The problem is that the type of an argument (the value
"inside" the function) used to always be identical to
the type of the parameter (the type from "outside" the
function, in the SILFunctionType). Of course this
assumption is no longer correct for static methods,
where the 'self' argument should really have type
@dynamic_self X.Type, not X.Type.

A further complication is closure captures, whose types
can also contain @dynamic_self inside metatypes in other
structural types. We used to erase @dynamic_self from
these.

Both of these are wrong, because if you call a generic
function <T> (T.Type) -> () with a T := @dynamic_self X
substitution (recall that substitutions are written in
terms of AST types and not lowered types) and pass in
the 'self' argument, we would pass in a value of type
X.Type and not @dynamic_self X.Type.

There were similar issues with captures, with
additional complications from nested closures.

Fix all this by having SILGenProlog emit a downcast
to turn the X.Type argument into a value of type
@dynamic_self X.Type, and tweak capture lowering to
not erase @dynamic_self from capture types.

This fixes several cases that used to fail with
asserts in SILGenApply or the SIL verifier, in particular
the example outlined in <rdar://problem/31226650>,
where we would crash when calling a protocol extension
method from a static class method (oops!).

If you got this far and still follow along,
congratulations, you now know more about DynamicSelfType
than I do.
2017-03-26 22:44:35 -07:00
Michael Gottesman
43a851736c [silgen] When compiling with sil-ownership use borrows+CopyOnSuccess instead of TakeOnSuccess.
This is NFC since all changes are behind a flag. I took a look at the codegen
when this is enabled. It looks pretty optimizable for a -Onone ARC pass. Until I
have that pass though I need this behind a flag.

Basically you see a lot of this pattern:

%0 = begin_borrow %foo
%1 = copy_value %0
...
bb1:
  %2 = begin_borrow %1
  %3 = copy_value %2
  ...
  destroy_value %3
  end_borrow %2 from %1
  destroy_value %1
  end_borrow %0 from %foo
  ...

bb2:
  destroy_value %1
  end_borrow %0 from %foo
  ...

This is really easy to optimize since one can easily see that all of %1's users
are borrows or a final destroy.

rdar://31145255
2017-03-26 15:30:15 -07:00
Michael Gottesman
80342face2 Merge pull request #8357 from gottesmm/reapply_c3c9ba3a82290cc470c71831f2688b341b0017f1
Revert "Revert "[semantic-sil] Fix ownership forwarding in emitCastTo…
2017-03-26 14:54:50 -07:00
swift-ci
c56709ffeb Merge pull request #8356 from gottesmm/partial_reapply_41f425a5033a30fdd545752b8bb10374bbf1de12 2017-03-26 14:16:43 -07:00
Michael Gottesman
af9f588a79 Merge pull request #8355 from gottesmm/select_enum_fix
Select enum fix
2017-03-26 13:18:19 -07:00
Michael Gottesman
f9e3b1d6d9 Reapply "[silgen] If we have a direct guaranteed convention and have an owned value, perform a borrow.""
This partially reverts commit 41f425a503.

The key thing is that now it is behind the semantic sil flag. I have an
additional patch that turns this back on in front of the flag, but it requires a
little bit of mandatory pass work that Erik is going to hit this week.

rdar://31145255
2017-03-26 12:56:42 -07:00
Michael Gottesman
8f2011b4fa Revert "Revert "[semantic-sil] Fix ownership forwarding in emitCastToReferenceType.""
This reverts commit c3c9ba3a82.
2017-03-26 12:51:19 -07:00
Michael Gottesman
4dacf68848 [silgen] Make sure that we do not disable ownership along failure paths when performing select enum checks.
What is happening here is that we are performing a select_enum check and then
not emitting the cleanup on the path where we know that our optional value is
null. To express such an operation in semantic sil, one should use a switch_enum
instead. Thus we must insert the destroy_value so that we know that the optional
value is balanced along all paths.

rdar://31145255
2017-03-26 10:47:12 -07:00
Michael Gottesman
fdfa53bacc Small mistakes in SILGenBuilder.
Noticed on inspection. We shouldn't be forwarding the input value if we are
going to be performing a copy.

rdar://31145255
2017-03-26 10:47:12 -07:00
Slava Pestov
f3db730424 SILGen: Another fix for covariant method overrides
This fixes the "AST type changed, override is ABI compatible" case,
which enables the test cases previously marked with 'FIXME' in
vtable_thunks_reabstraction to pass.
2017-03-25 22:08:29 -07:00
Hugh Bellamy
b6e720ab96 Fix undefined behaviour caused by accessing uninitialized field in CallEmission 2017-03-25 12:54:21 +07:00
Joe Shajrawi
69bd3ca9f8 Fix opaque value corner-cases for classes and vtables 2017-03-24 12:28:52 -07:00
Slava Pestov
7aabd80898 SIL: Stub out TypeConverter::getOverriddenVTableEntry()
This replaces SILDeclRef::getBaseOverriddenVTableEntry(). It lives
in the TypeConverter because it needs to use type lowering information
to determine if the method requires a new vtable entry or not.
2017-03-24 01:53:39 -07:00
Slava Pestov
ef7f6bf0ea SIL: Stub out TypeConverter::requiresNewVTableEntry() 2017-03-24 01:52:42 -07:00
Slava Pestov
a9532fa1cb SILGen: Fix O(n^2) algorithm in vtable emission
Not only was it quadratic, but we were also potentially emitting
redundant vtable thunks if a method had multiple overrides in
the inheritance hierarchy.

I doubt this makes much of a difference in practice, but the new
logic seems a bit simpler also.
2017-03-24 01:51:59 -07:00
Slava Pestov
e912f27944 AST/SILGen: New mangling for vtable thunks
Simply mangling the derived method is no longer sufficient. Now also
mangle the base method, so that eventually we handle this sort of
scenario:

class Base {
  // introduces: Base.method
  func method(_: Int, _: Int) {}
}

class First : Base {
  // overrides: Base.method
  // introduces: First.method
  override func method(_: Int?, _: Int) {}
}

class Second : First {
  // overrides: Base.method, First.method
  // introduces: Second.method
  override func method(_: Int?, _: Int?) {}
}

Here, the override of Base.method by Second.method and the
override of First.method by Second.method require distinct
manglings even though the derived method (Second.method) is
the same in both cases.

Note that while the new mangling is longer, vtable thunks are
always emitted with private linkage, so with the exception of
the standard library which is built with -sil-serialize-all
they will not affect the size of dylibs.

The standard library itself has very few classes so it doesn't
matter there either.

This patch doesn't actually add any support to introduce new
vtable entries for methods that override; this is coming up
next.
2017-03-23 23:40:52 -07:00
Slava Pestov
82f50b8b42 SILGen: Refactor emitVTableMethod() to return a SILVTable::Entry
This change simplifies some code and incidentally fixes a curious
corner case. We allow dynamic overrides of non-dynamic methods,
but we did not account for the fact that the override could have
a different calling convention.
2017-03-23 22:20:08 -07:00
Joe Shajrawi
4c29a63a4b Merge pull request #8308 from shajrawi/conditional_checked_cast_opaque_result
Further support for conditional checked cast under opaque value mode
2017-03-23 20:15:20 -07:00
Slava Pestov
990e66dda7 Merge pull request #8304 from slavapestov/vtable-visitor-refactoring
VTable visitor refactoring
2017-03-23 20:08:18 -07:00
Joe Shajrawi
2e82d6ff07 Further support for conditional checked cast under opaque value mode - make sure we don't create a buffer for results 2017-03-23 19:20:11 -07:00
Joe Shajrawi
a442cd9cf2 Merge pull request #8305 from shajrawi/tuple_corner_case_reabstract
Support a corner case of tuple transformation with opaque value types
2017-03-23 19:05:14 -07:00
Slava Pestov
1a9fe1fb74 SILGen: Use SILVTableVisitor instead of bespoke member traversal
This changes the order in which declarations are emitted.
It also means we no longer emit a vtable entry for the
materializeForSet of dynamic storage. Neither of these are
intended to have any functional effect.
2017-03-23 18:45:40 -07:00
Joe Shajrawi
e7773ba167 Support a corner case of tuple transformation with opaque value types 2017-03-23 18:28:23 -07:00
Michael Gottesman
73bc62c537 Merge pull request #8297 from gottesmm/add_getsubst_methods_to_argumentsource
[silgen] Add helper methods to compute ArgumentSource::getSubst{RValue,}Type() as SILTypes.
2017-03-23 17:46:10 -07:00
Joe Shajrawi
2c94420ba0 Add support for global opaque values / subscript lvalues under opaque values mode 2017-03-23 17:27:07 -07:00
Joe Shajrawi
1c490c1c5c Add support for global opaque values / subscript rvalues under opaque values mode 2017-03-23 16:54:10 -07:00