Commit Graph

4317 Commits

Author SHA1 Message Date
John McCall
07f03bd287 Use pattern substitutions to consistently abstract yields.
The design implemented in this patch is that we lower the types of accessors with pattern substitutions when lowering them against a different accessor, which happens with class overrides and protocol witnesses, and that we introduce pattern substitutions when substituting into a non-patterned coroutine type.  This seems to achieve consistent abstraction without introduce a ton of new complexity.

An earlier version of this patch tried to define witness thunks (conservatively, just for accessors) by simply applying the requirement substitutions directly to the requirement.  Conceptually that should work, but I ran into a lot of trouble with things that assumed that pattern substitutions didn't conceal significant substitution work.  for example, resolving a dependent member in a component type could find a new use of an opaque archetype when the code assumed that such types had already been substituted away.  So while I think that is definiteely a promising direction, I had to back that out in order to make the number of changes manageable for a single PR.

As part of this, I had to fix a number of little bugs here and there, some of which I just introduced.  One of these bugfixes is a place where the substitution code was trying to improperly abstract function types when substituting them in for a type parameter, and it's been in the code for a really long time, and I'm really not sure how it's never blown up before.

I'm increasingly of the opinion that invocation substitutions are not actually necessary, but that --- after we've solved the substitution issues above --- we may want the ability to build multiple levels of pattern substitution so that we can guarantee that e.g. witness thunks always have the exact component structure of the requirement before a certain level of substitution, thus allowing the witness substitutions to be easily extracted.
2020-03-10 01:26:31 -04:00
John McCall
ceff414820 Distinguish invocation and pattern substitutions on SILFunctionType.
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.
2020-03-07 16:25:59 -05:00
Brent Royal-Gordon
d590823f3c Warn about conflicts between #file strings 2020-03-05 23:30:37 -08:00
Brent Royal-Gordon
8e5ca8abdf [NFC] Generate #file -> #filePath table ahead of time 2020-03-05 17:23:44 -08:00
Brent Royal-Gordon
f34fa7ffcd Match prototype’s #file string format to upcoming SE-0274 revision 2020-03-05 16:01:13 -08:00
Robert Widmann
de72824b04 [Gardening] Canonicalize usages of ASTContext::Stats 2020-02-27 17:12:58 -08:00
Arnold Schwaighofer
869e579477 Merge pull request #30076 from aschwaighofer/silgen_fix_dynamic_replacement_before_original
SILGen: Fix dynamic replacement before original function
2020-02-27 12:03:09 -08:00
Joe Groff
0fb4ea1ec3 Merge pull request #30003 from NobodyNada/master
[SILOptimizer] Generalize optimization of static key paths, take 2
2020-02-26 12:13:43 -08:00
Arnold Schwaighofer
cae695e81b SILGen: Fix dynamic replacement before original function
Creating a @_dynamicReplacement function requires the creation of a
reference to the original function. We need to call SILGenModule's
getFunction to satisfy all the assertions in place.

rdar://59774606
2020-02-26 09:47:36 -08:00
Slava Pestov
d823be96a2 Merge pull request #30061 from slavapestov/property-wrapper-backing-init-constrained-extension
SILGen: Fix substitution map when calling property wrapper backing initializer
2020-02-25 22:11:45 -05:00
Slava Pestov
4b9c82de5b SILGen: Fix substitution map when calling property wrapper backing initializer
If we're emitting a designated constructor inside a constrained extension,
we have to use the correct substitution map for calling the property wrapper
backing initializer.

Factor out the computation of this substitution map and use it consistently.

Fixes <rdar://problem/59245068>.
2020-02-25 18:18:54 -05:00
Slava Pestov
10c37c6565 SILGen: Work around for stored property keypath components not supporting generic resilient classes
A keypath component for a stored property can take one of several forms:

- The property offset is known to be constant at compile-time.

  This is used in the simplest cases for classes and structs.

- The property offset is not constant, but can be loaded from a global.

  This is used for classes that require runtime resilient layout, but where
  the offsets do not depend on the generic context.

- The property offset is not constant, and must be loaded from metadata.

  This is the case where the offset depends on the generic context. Here,
  we were only set up to load it from a fixed offset in the metadata.
  This works for generic structs, or generic classes where the superclass
  chain does not cross a resilience boundary.

  However, if a resilience boundary is crossed, the offset of the field
  offset in the metadata must itself be obtained at runtime by adding a
  constant to a value loaded from a global. This case is not supported by
  the current keypath ABI due to an oversight.

I filed <rdar://problem/59777983> to track extending the ABI to handle
this more elegantly in the future.

Fixes <rdar://problem/59617119>.
2020-02-25 16:39:50 -05:00
Joe Groff
b5c150287a SILGen: +1 function when converting for a reabstraction 2020-02-24 12:14:21 -08:00
Joe Groff
2b86330c2b SILGenPoly: Apply trivial argument conversions to return values too 2020-02-24 12:14:21 -08:00
Joe Groff
107686ecb7 SILGen: Handle function conversions in reabstraction thunks 2020-02-24 12:14:21 -08:00
Joe Groff
45e941c23a SILGen: Apply substitutions before bridging or thunking.
Even if differently-substituted function types have different value representations,
we can still share reabstraction and bridging thunks among types that are equivalent after
substitution, so handle these by generating thunks in terms of the unsubstituted type and
converting to the needed substitution form at the use site.
2020-02-24 12:14:21 -08:00
Jonathan Keller
4e77005204 [SILGen] fix key path setter access for @testable
emitKeyPathComponentForDecl was only checking if the setter was
accessible from the current module, not the current function.
This failed when accessing an internal setter from a module
imported for testing.
2020-02-21 15:34:17 -08:00
Joe Groff
f353c40ce9 Revert "[SILOptimizer] Generalize optimization of static keypaths" 2020-02-19 19:58:15 -08:00
Slava Pestov
1a9eb7960b Merge pull request #29913 from slavapestov/opaque-result-type-versus-keypath
Fix a couple of problems with opaque result types
2020-02-19 20:00:00 -05:00
Slava Pestov
9fa6d8947b SILGen: Fix keypath getter/setter emission with opaque result types
Opaque result types are substituted away inside the SILFunction, so
make sure we're looking at the correct SILFunctionType.
2020-02-19 15:42:01 -05:00
Robert Widmann
6965c3323e Merge pull request #29894 from CodaFi/im-beginning-to-feel-like-a-wrap-god
[SILGen] Reabstract and Materialize Arguments To Property Wrapper Setters If Needed
2020-02-18 21:23:01 -08:00
Robert Widmann
3e4a820fb4 [SILGen] Handle Reabstraction and Substitution in assign_by_wrapper
Use the substitution map for the LValue component to properly handle the
case where we need to re-abstract the argument to the assign_by_wrapper
setter.

Resolves rdar://59553318
2020-02-18 14:59:03 -08:00
Slava Pestov
3547122997 SILGen: Simplify prepareEpilog() utility method 2020-02-18 17:43:54 -05:00
Joe Groff
14cda1a472 Merge pull request #28799 from NobodyNada/master
[SILOptimizer] Generalize optimization of static keypaths
2020-02-18 13:28:05 -08:00
Robert Widmann
3b11c2b170 [SILGen] Materialize Arguments To Property Wrapper Setters If Needed
Codegen for the assign_by_wrapper instruction emits prepared arguments
directly into the initializer or accessor functions. This means it
misses out on the CC matching code that the general apply path uses.

In this particular case, an enum value was constructed within the
resilience boundary, but passed to the setter for a wrapper property
that expected it to be in memory.

Check the calling convention before we emit the assign_by_wrapper
instruction, and materialize an address for indirect CCs as required.

resolves rdar://59071930
2020-02-18 09:10:07 -08:00
Jonathan Keller
a06fe96fd9 [SILGen] fix key path setter access for @testable
emitKeyPathComponentForDecl was only checking if the setter was
accessible from the current module, not the current function.
This failed when accessing an internal setter from a module
imported for testing.
2020-02-15 15:10:25 -08:00
Hamish Knight
2e40295640 NFC: Extract simple_display for FileUnit 2020-02-13 20:44:38 -08:00
Slava Pestov
38815ecf8d SILGen: Fix crash on assignment to static property wrapper through 'self'
Fixes <rdar://problem/59117087>.
2020-02-13 18:18:23 -05:00
Slava Pestov
55dd1c7a94 SILGen: Small cleanup for SILGenVTable 2020-02-12 18:29:26 -05:00
Michael Gottesman
60a09dd63c [builtin] Change ConvertStrongToUnownedUnsafe and ConvertUnownedUnsafeToGuaranteed to take non-optional arguments. 2020-02-12 13:30:06 -08:00
Slava Pestov
fc810e1205 SILGen: Relax assertion about missing vtable entries in a class
Since resilient class metadata is built at runtime, we don't actually
care if there are missing vtable entries. The restriction was relaxed
in Sema in 9117c5728a, but SILGen still
had an assertion here.

Add a test and relax the assertion.

Fixes <rdar://problem/58644615>.
2020-02-10 19:28:11 -05:00
Michael Gottesman
94cd804eed Merge pull request #29680 from gottesmm/pr-5cabc7ee4a3e006145b5d4716d59ba51ba0c547b
[builtin] Add a new SIL builtin convertStrongToUnsafeUnowned()
2020-02-07 14:52:55 -08:00
Michael Gottesman
f7f98887d4 [builtin] Add a new SIL builtin convertUnownedUnsafeToGuaranteed()
(BaseT, @inout @unowned(unsafe) T) -> @guaranteed T

The reason for the weird signature is that currently the Builtin infrastructure
does not handle results well. Also, note that we are not actually performing a
call here. We are SILGening directly so we can create a guaranteed result.

The intended semantics is that one passes in a base value that guarantees the
lifetime of the unowned(unsafe) value. The builtin then:

1. Borrows the base.
2. Loads the trivial unowned (unsafe), converts that value to a guaranteed ref
   after unsafely unwrapping the optional.
3. Uses mark dependence to tie the lifetimes of the guaranteed base to the
   guaranteed ref.

I also updated my small UnsafeValue.swift test to make sure we get the codegen
we expect.
2020-02-07 13:08:34 -08:00
Michael Gottesman
1137c00196 [builtin] Add a new SIL builtin convertStrongToUnownedUnsafe()
The signature is:

(T, @inout @unowned(unsafe) Optional<T>) -> ()

The reason for the weird signature is that currently the Builtin infrastructure
does not handle results well.

The semantics of this builtin is that it enables one to store the first argument
into an unowned unsafe address without any reference counting operations. It
does this just by SILGening the relevant code. The optimizer chews through this
code well, so we get the expected behavior.

I also included a small proof of concept to validate that this builtin works as
expected.
2020-02-07 13:07:05 -08:00
Slava Pestov
c5718d5b18 SILGen: Fix crash with function conversions involving class-constrained protocols
If a protocol has a superclass constraint, the existential type can be
upcast to the class type given by the constraint. This wasn't implemented
in the function conversion code path, leading to a crash.

Fixes <https://bugs.swift.org/browse/SR-12018> / <rdar://problem/58861162>.
2020-02-06 19:48:03 -05:00
Robert Widmann
4570ba8426 Refactor GenerateSILRequest into WMO and per-SF SILGen Requests 2020-02-04 15:20:52 -08:00
Robert Widmann
676436640c Add SILGenSourceFileRequest
Replace SILGenModule::emitSourceFile with SILGenSourceFileRequest so we
have an explicit source file to associate any lookups with.
2020-02-03 18:26:19 -08:00
Michael Gottesman
6c5c853339 [ownership] Change guaranteed args from transformation terminators to not require end_borrows.
For those who are unaware, a transformation terminator is a terminator like
switch_enum/checked_cast_br that always dominate their successor blocks. Since
they dominate their successor blocks by design and transform their input into
the args form, we can validate that they obey guaranteed ownership semantics
just like a forwarding instruction.

Beyond removing unnecessary code bloat, this also makes it significantly more
easier to optimize/work with transformation terminators when converting @owned
-> @guaranteed since we do not need to find end_borrow points when the owned
value is consumed.

<rdar://problem/59097063>
2020-02-02 16:59:57 -08:00
swift-ci
a33690456c Merge pull request #29599 from gottesmm/pr-762e321418ba69083a3400aa47cb65b0d34f5e37 2020-02-02 14:36:35 -08:00
Michael Gottesman
8f91b9e89a [ownership] Get rid of old entrypoint for creatingEndBorrow that takes the original value.
The original design was to make it so that end_borrow tied at the use level its
original/borrowed value. So we would have:

```
%borrowedVal = begin_borrow %original
...
end_borrow %borrowedVal from %original
```

In the end we decided not to use that design and instead just use:

```
%borrowedVal = begin_borrow %original
...
end_borrow %borrowedVal
```

In order to enable that transition, I left the old API for end_borrow that took
both original and borrowedVal and reimplemented it on top of the new API that
just took the borrowedVal (i.e. the original was just a dead arg).

Now given where we are in the development, it makes sense to get rid of that
transition API and move to just use the new API.
2020-02-02 12:57:58 -08:00
Arnold Schwaighofer
fce335bf36 SILGen: Fix withoutActuallyEscaping of 'c' closures
They don't have a context and therefore are not consumed.

Fixes a failing assert.

rdar://59046275
2020-01-31 08:57:45 -08:00
Arnold Schwaighofer
18babf7574 SILGen: Lower the type of the return value merge phi in the context of the current function
rdar://58929484
2020-01-28 08:06:02 -08:00
Robert Widmann
423bcdfcdd Merge pull request #29242 from CodaFi/smooth-as-sil-k
[NFC] Define SILGen Request Zone and GenerateSIL Request
2020-01-27 16:30:20 -08:00
Vedant Kumar
dfdb2e57b9 [SILProfiler] Do not set up a profiler for a function twice
rdar://58861159
2020-01-27 12:32:49 -08:00
Robert Widmann
b6fb6ed7ff Add type info for unique_ptr 2020-01-26 14:23:45 -08:00
Robert Widmann
6ec3ab94d2 [NFC] Define SILGen Request Zone and GenerateSIL Request
Define a high-level request for SILGen and switch the high-level
entrypoint to vector through it.
2020-01-26 13:43:52 -08:00
Saleem Abdulrasool
684d13e2c1 SILGen: remove stray file (NFC)
This file has no content is unreferenced in the build system.
2020-01-22 17:45:45 -08:00
Varun Gandhi
29cc1b6195 Revert "[AST] Store Clang type in SILFunctionType for @convention(c) functions."
This reverts commit 5f45820755.
2020-01-22 09:04:52 -08:00
Varun Gandhi
5f45820755 [AST] Store Clang type in SILFunctionType for @convention(c) functions. 2020-01-17 16:22:39 -08:00
Arnold Schwaighofer
8ed908f923 Revert "[silgen] When SILGenLValue accesses ref_elt_addr, emit unsafe access for immutable or non accessing uses instead of not emitting any begin_access."
This reverts commit a3b68e6df5.

Speculative revert because I believe it is the cause of the failures on
the swift-master-source-compat-suite-enable-verify-exclusivity bot.

rdar://58529726
2020-01-15 10:12:23 -08:00