Commit Graph

446 Commits

Author SHA1 Message Date
Arnold Schwaighofer
33f4f57cc4 SILGen: Add TypeExpansionContext to SILGen 2019-11-11 14:21:52 -08:00
Joe Groff
03c7919b4a SIL: Add fields to SILFunctionType for substituted function types.
https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711

This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:

- A substitution map, accessed by `getSubstitutions()`, which maps the generic signature
  of the function to its concrete implementation. This will allow, for instance, a protocol
  witness for a requirement of type `<Self: P> (Self, ...) -> ...` for a concrete conforming
  type `Foo` to express its type as `<Self: P> (Self, ...) -> ... for <Foo>`, preserving the relation
  to the protocol interface without relying on the pile of hacks that is the `witness_method`
  protocol.

- A bool for whether the generic signature of the function is "implied" by the substitutions.
  If true, the generic signature isn't really part of the calling convention of the function.
  This will allow closure types to distinguish a closure being passed to a generic function, like
  `<T, U> in (*T, *U) -> T for <Int, String>`, from the concrete type `(*Int, *String) -> Int`,
  which will make it easier for us to differentiate the representation of those as types, for
  instance by giving them different pointer authentication discriminators to harden arm64e
  code.

This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.

This does bifurcate some existing APIs:

- SILFunctionType now has two accessors to get its generic signature.
  `getSubstGenericSignature` gets the generic signature that is used to apply its
  substitution map, if any. `getInvocationGenericSignature` gets the generic signature
  used to invoke the function at apply sites. These differ if the generic signature is
  implied.
- SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
  and results of the function. They now have two APIs to get that type. `getInterfaceType`
  returns the unsubstituted type of the generic interface, and
  `getArgumentType`/`getReturnValueType` produce the substituted type that is used at
  apply sites.
2019-10-25 13:38:51 -07:00
Robert Widmann
56b6e53dae Remove raw references to PatternBindingEntry APIs
Switch most callers to explicit indices.  The exceptions lie in things that needs to manipulate the parsed output directly including the Parser and components of the ASTScope.  These are included as friend class exceptions.
2019-10-17 13:31:14 -07:00
Brent Royal-Gordon
f93c0ee1b7 [NFC] Base emitGeneratorFunction() on canCaptureFromParent() 2019-10-14 13:29:33 -07:00
Brent Royal-Gordon
ca25640cc3 Merge branch 'master' into everything-evil 2019-10-14 13:24:03 -07:00
Brent Royal-Gordon
ab96afacb5 [SILGen] Assert that captures have been computed
Before using the capture info, SILGen now asserts that it has computed, except for declarations which are not in a local context and therefore can’t have captures.

This causes failures in REPL tests, but they are actual failures—there’s a bug in TypeCheckREPL.
2019-10-11 19:16:58 -07:00
Slava Pestov
d8b61ff24b Sema: Peel off typeCheckParameterList()'s specifier computation into a request
Since getSpecifier() now kicks off a request instead of always
returning what was previously set, we can't pass a ParamSpecifier
to the ParamDecl constructor anymore. Instead, callers either
call setSpecifier() if the ParamDecl is synthesized, or they
rely on the request, which can compute the specifier in three
specific cases:

- Ordinary parsed parameters get their specifier from the TypeRepr.

- The 'self' parameter's specifier is based on the self access kind.

- Accessor parameters are either the 'newValue' parameter of a
  setter, or a cloned subscript parameter.

For closure parameters with inferred types, we still end up
calling setSpecifier() twice, once to set the initial defalut
value and a second time when applying the solution in the
case that we inferred an 'inout' specifier. In practice this
should not be a big problem because expression type checking
walks the AST in a pre-determined order anyway.
2019-10-10 15:00:07 -04:00
Doug Gregor
ab5d161c05 [SILGen] Separate the initialization of a wrapped property from a wrapped value
Teach SILGen to emit a separate SIL function to capture the
initialization of the backing storage type for a wrapped property
based on the wrapped value. This eliminates manual code expansion at
every use site.
2019-09-24 09:11:53 -07:00
Slava Pestov
533d41d0db SIL: Compute lowered local captures of SILDeclRefs and not AnyFunctionRefs
Unfortuantely this commit is bigger than I would like but I couldn't think
of any reasonable ways to split it up.

The general idea here is that capture computation is now done for a
SILDeclRef and not an AnyFunctionRef. This allows SIL to represent the
captures of a default argument generator.
2019-09-18 14:26:01 -04:00
Jordan Rose
853caa66d4 [AST] Split FileUnit and its subclasses out of Module.h
Most of AST, Parse, and Sema deal with FileUnits regularly, but SIL
and IRGen certainly don't. Split FileUnit out into its own header to
cut down on recompilation times when something changes.

No functionality change.
2019-09-17 17:54:41 -07:00
Slava Pestov
75f4625bee AST: Peel off ClangModuleLoader.h from ASTContext.h 2019-09-03 22:39:35 -04:00
Slava Pestov
83c90b6b2a AST: Turn NominalTypeDecl::getStoredProperties() into a request
This improves on the previous situation:

- The request ensures that the backing storage for lazy properties
  and property wrappers gets synthesized first; previously it was
  only somewhat guaranteed by callers.

- Instead of returning a range this just returns an ArrayRef,
  which simplifies clients.

- Indexing into the ArrayRef is O(1), which addresses some FIXMEs
  in the SIL optimizer.
2019-07-16 16:38:38 -04:00
Slava Pestov
44142cdb62 SILGen: Diagnose captures before definitions
The new analysis simply checks if the captured value has been defined
yet; instead of asserting if it hasn't, we can now emit a diagnostic
using the source location tracked in the capture list.

Fixes <https://bugs.swift.org/browse/SR-4812>, <rdar://problem/40600800>.
2019-06-27 20:59:22 -04:00
Slava Pestov
06ecb8d5c7 SIL: Remove CaptureKind::None and clean up some other capture-related logic 2019-06-27 20:59:22 -04:00
Vedant Kumar
569c8afc54 [Profiler] Separate profiler instances for property inits and constructors (#25247)
Assign separate SILProfiler instances to stored property initializers
and constructors.

Starting with rdar://39460313, coverage reporting for these constructs
was bundled up into a single SILProfiler uniqued by the NominalTypeDecl.
There are two problems with doing this.

First, the shared SILProfiler is given a fake name that can't be
demangled. That breaks Xcode's reports.  Second, the relationship
between SILProfiler and SILFunction is supposed to be 1:1. Having a
shared SILProfiler muddies things a bit and requires extra bookkeeping.

rdar://47467864
2019-06-05 10:38:10 -07:00
Doug Gregor
c02ecf9859 [SE-0258] Rename to Property Wrappers 2019-05-29 22:17:50 -07:00
Slava Pestov
16d5716e71 SIL: Use the best resilience expansion when lowering types
This is a large patch; I couldn't split it up further while still
keeping things working. There are four things being changed at
once here:

- Places that call SILType::isAddressOnly()/isLoadable() now call
  the SILFunction overload and not the SILModule one.

- SILFunction's overloads of getTypeLowering() and getLoweredType()
  now pass the function's resilience expansion down, instead of
  hardcoding ResilienceExpansion::Minimal.

- Various other places with '// FIXME: Expansion' now use a better
  resilience expansion.

- A few tests were updated to reflect SILGen's improved code
  generation, and some new tests are added to cover more code paths
  that previously were uncovered and only manifested themselves as
  standard library build failures while I was working on this change.
2019-04-26 22:47:59 -04:00
Slava Pestov
472787bab7 SIL: isNonThrowing parameter of SILBuilder::create{Begin,}Apply() defaults to false
Also remove the overload of createApply() that does not take a SubstitutionMap.
It accomplishes nothing except creating ambiguity.
2019-04-25 22:27:38 -04:00
Saleem Abdulrasool
382ec0c288 SILGen: disambiguate apply overload
The anonymous universal initialiser would result in ambiguous selection
of the constructor.  Name the type being constructed.
2019-04-25 12:26:54 -07:00
Slava Pestov
9a1abf705a SILGen: Remove SILGenSILBuilder
This reverts commit 59cc3c1216fbb1719e5357dcef3f8b249528fc74.
2019-04-25 02:06:14 -04:00
Doug Gregor
2e9f8cf981 Capture a placeholder opaque value expression when needed. 2019-04-23 11:32:28 -07:00
Doug Gregor
cc68b12d1a [SILGen] Initialization of instance properties with property delegates
The initialization of an instance property that has an attached
property delegate involves the initial value written on the property
declaration, the implicit memberwise initializer, and the default
arguments to the implicit memberwise initializer. Implement SILGen
support for each of these cases.

There is a small semantic change to the creation of the implicit
memberwise initializer due to SE-0242 (default arguments for the
memberwise initializer). Specifically, the memberwise initializer will
use the original property type for the parameter to memberwise
initializer when either of the following is true:

  - The corresponding property has an initial value specified with the
    `=` syntax, e.g., `@Lazy var i = 17`, or
  - The corresponding property has no initial value, but the property
    delegate type has an `init(initialValue:)`.

The specific case that changed is when a property has an initial value
specified as a direct initialization of the delegate *and* the
property delegate type has an `init(initialValue:)`, e.g.,

```swift
struct X {
  @Lazy(closure: { ... })
  var i: Int
}
```

Previously, this would have synthesized an initializer:

```swift
init(i: Int = ???) { ... }
```

However, there is no way for the initialization specified within the
declaration of i to be expressed via the default argument. Now, it
synthesizes an initializer:

```swift
init(i: Lazy<Int> = Lazy(closure: { ... }))
```
2019-04-23 11:31:59 -07:00
Joe Groff
60aa49d69c merge fixup 2019-04-17 14:46:22 -07:00
Joe Groff
c771a7e71b SILGen: Substitute away opaque types. 2019-04-17 14:43:32 -07:00
Slava Pestov
6bb36b5c01 Sema: Subscript default arguments
Fixes <https://bugs.swift.org/browse/SR-6118>.
2019-04-02 20:37:01 -04:00
Azoy
bbf680df64 forward direct return to direct results 2019-04-01 18:12:34 -05:00
Azoy
340d4d2569 don't forget to strip reference storage types off 2019-03-31 11:55:15 -05:00
Azoy
4d2b5d4b2f emit apply 2019-03-31 11:54:03 -05:00
Slava Pestov
c93ec45e62 SIL: Plumb resilience expansion through when lowering capture types
For now this is NFC.
2019-03-13 02:08:32 -04:00
Robert Widmann
944d8d06d7 [SE-0155] Default Arguments in Enum Cases
The bulk of the changes are to SILGenApply.  As we must now evaluate the
payload ArgumentSource to an RValue, we follow the example of subscripts
and lie to the argument emitter.  This evaluates arguments at +1 which
can lead to slightly worse codegen at -Onone.
2019-02-12 10:06:48 -05:00
Robert Widmann
426fe886dc [SR-8272] Drop the last remnants of LogicValue
Removes the _getBuiltinLogicValue intrinsic in favor of an open-coded
struct_extract in SIL.  This removes Sema's last non-literal use of builtin
integer types and unblocks a bunch of cleanup.

This patch would be NFC, but it improves line information for conditional expression codegen.
2018-12-19 23:14:59 -05:00
Arnold Schwaighofer
5f4e183302 Add [dynamically_replacable] to SILFunctions
'dynamic' functions are marked as [dynamically_replaceable].
2018-11-06 09:53:21 -08:00
Arnold Schwaighofer
c158106329 Allow dynamic without @objc in -swift-version 5
Dynamic functions will allow replacement of their implementation at
runtime.
2018-11-06 09:53:21 -08:00
Michael Gottesman
e96dcdf243 [silgen] Add a missing destroy_value in our code that emits UIApplicationMain.
This error slipped through... the ownership verifier catches this when the test
test/SILGen/UIApplicationMain is compiled.
2018-10-29 22:03:23 -07:00
Andrew Trick
2ccc089b27 SILGenFunction::mergeCleanupBlocks.
Avoid emitting unnecessary basic block for cleanup chains. This is a
general approach that handles all cases while simplifying SILGen
emission and keeping the CFG in a valid state during SILGen.
2018-10-19 22:22:23 -07:00
Graydon Hoare
9ce3dc4543 [Stats] Add some tracers to SILGen. 2018-09-01 00:05:58 -07:00
John McCall
af1fbee3de Thread ForUnwind_t into emitCleanupsForReturn.
Some "return" edges are for unwinding due to errors and some aren't.
They'll need to be distinguished if we ever want to support throwing
cleanups.
2018-08-16 02:27:54 -04:00
Vedant Kumar
6d467fd31f [SILProfiler] Don't crash when coverage info for lazy getters is incomplete (#18744)
ASTWalker visits a lazy_initializer_expr once within its associated
var_decl (by way of the parent nominal type). However, SILGen visits the
lazy_initializer_expr while inside of the var_decl's getter. The result
is that there is no coverage mapping information for the contents of the
lazy init within the getter's SILProfiler.

Fixing this will require reworking how profile counters are assigned to
be more in line with what SILGen needs.

As a stop-gap, this patch prevents SILGen from asserting that coverage
mappings are complete with a defensive check which prevents a crash seen
in SR-8429.

rdar://42792053
2018-08-15 17:48:21 -07:00
Michael Gottesman
f6c77f55d0 Merge pull request #18516 from gottesmm/pr-1f01768b88d904e16c4d1fd22cdbfca3fcc2cfa4
[silgen] Replace all uses of SILFunctionBuilder with SILGenFunctionBu…
2018-08-06 08:32:29 -07:00
Michael Gottesman
6511b75de0 [silgen] Replace all uses of SILFunctionBuilder with SILGenFunctionBuilder.
This initial implementation just delegates from SILGenFunctionBuilder to
SILFunctionBuilder. I was going to start transforming verbose uses of
SILFunctionBuilder into higher level APIs on SILGenFunctionBuilder, but I have
run out of time.

This is a good incremental step forward that will let me hide the constructor of
SILFunctionBuilder after I update the optimizer and thus ensure that
SILFunctionBuilder is only used through appropriate composition APIs.

rdar://42301529
2018-08-05 17:12:36 -07:00
Doug Gregor
bd5f5d80e4 [AST] Add ExtensionDecl::getExtendedNominal().
Introduce ExtensionDecl::getExtendedNominal() to provide the nominal
type declaration that the extension declaration extends. Move most
of the existing callers of the callers to getExtendedType() over to
getExtendedNominal(), because they don’t need the full type information.

ExtensionDecl::getExtendedNominal() is itself not very interesting yet,
because it depends on getExtendedType().
2018-08-03 11:26:48 -07:00
Doug Gregor
9eb9898321 Merge pull request #18364 from DougGregor/name-lookup-requests
[Name lookup] Introduce requests for several name lookup operations.
2018-07-31 13:23:38 -07:00
Doug Gregor
2860557a77 [Name lookup] Use the declaration-based lookupQualified() where it’s easy.
Switch a number of callers of the Type-based lookupQualified() over to
the newer (and preferred) declaration-based lookupQualified(). These are
the easy ones; NFC.
2018-07-31 10:14:44 -07:00
Michael Gottesman
11b24415c1 [sil-module] Create SILFunctionBuilder and hide creation/erasing functions on SILModule.
This commit does not modify those APIs or their usage. It just:

1. Moves the APIs onto SILFunctionBuilder and makes SILFunctionBuilder a friend
   of SILModule.
2. Hides the APIs on SILModule so all users need to use SILFunctionBuilder to
   create/destroy functions.

I am doing this in order to allow for adding/removing function notifications to
be enforced via the type system in the SILOptimizer. In the process of finishing
off CallerAnalysis for FSO, I discovered that we were not doing this everywhere
we need to. After considering various other options such as:

1. Verifying after all passes that the notifications were sent correctly and
   asserting. Turned out to be expensive.
2. Putting a callback in SILModule. This would add an unnecessary virtual call.

I realized that by using a builder we can:

1. Enforce that users of SILFunctionBuilder can only construct composed function
   builders by making the composed function builder's friends of
   SILFunctionBuilder (notice I did not use the word subclass, I am talking
   about a pure composition).
2. Refactor a huge amount of code in SILOpt/SILGen that involve function
   creation onto a SILGenFunctionBuilder/SILOptFunctionBuilder struct. Many of
   the SILFunction creation code in question are straight up copies of each
   other with small variations. A builder would be a great way to simplify that
   code.
3. Reduce the size of SILModule.cpp by 25% from ~30k -> ~23k making the whole
   file easier to read.

NOTE: In this commit, I do not hide the constructor of SILFunctionBuilder since
I have not created the derived builder structs yet. Once I have created those in
a subsequent commit, I will hide that constructor.

rdar://42301529
2018-07-31 10:04:03 -07:00
Joe Groff
a6fb91a5b7 SILGen: Pick UIApplicationMain by looking directly in the Clang module.
This saves us from having to do overload resolution on the overlay module, which fails if an overlay declaration exactly matches the imported signature of the original ObjC declaration. Fixes rdar://problem/42352695 harder.
2018-07-23 12:37:24 -07:00
Slava Pestov
e606aad80f SILGen: Remove uses of AbstractFunctionDecl::getParameterLists() 2018-07-19 22:09:13 -07:00
Joe Groff
cba32f79a5 SILGen: Cope with overloads when emitting artificial main for @UIApplicationMain.
The overlay may add overloads for UIApplicationMain for various reasons. When we generate the special `main` implementation for a `@UIApplicationMain` class, we want to call the original function from Objective-C, so pick that one where there are multiple overloads to choose from. Fixes rdar://problem/42352695.
2018-07-18 15:58:11 -07:00
Ben Cohen
2b04e9f105 Suppress a number of warnings in no-assert builds (#17721)
* Supress a number of warnings about things used only in asserts

* Re-use a couple of variables instead of supressing the warning
2018-07-04 07:15:14 -07:00
John McCall
9bee3cac5a Generalize storage implementations to support generalized accessors.
The storage kind has been replaced with three separate "impl kinds",
one for each of the basic access kinds (read, write, and read/write).
This makes it far easier to mix-and-match implementations of different
accessors, as well as subtleties like implementing both a setter
and an independent read/write operation.

AccessStrategy has become a bit more explicit about how exactly the
access should be implemented.  For example, the accessor-based kinds
now carry the exact accessor intended to be used.  Also, I've shifted
responsibilities slightly between AccessStrategy and AccessSemantics
so that AccessSemantics::Ordinary can be used except in the sorts of
semantic-bypasses that accessor synthesis wants.  This requires
knowing the correct DC of the access when computing the access strategy;
the upshot is that SILGenFunction now needs a DC.

Accessor synthesis has been reworked so that only the declarations are
built immediately; body synthesis can be safely delayed out of the main
decl-checking path.  This caused a large number of ramifications,
especially for lazy properties, and greatly inflated the size of this
patch.  That is... really regrettable.  The impetus for changing this
was necessity: I needed to rework accessor synthesis to end its reliance
on distinctions like Stored vs. StoredWithTrivialAccessors, and those
fixes were exposing serious re-entrancy problems, and fixing that... well.
Breaking the fixes apart at this point would be a serious endeavor.
2018-06-30 05:19:03 -04:00
Slava Pestov
ebb1198d57 AST: There's no longer any reason to pass SubstitutionMap by const reference
SubstitutionMaps are now just a trivial pointer-sized value, so
pass them by value instead.

I did have to move a couple of functors from Type.h to SubstitutionMap.h
to resolve some issues with forward declarations.
2018-05-19 00:45:36 -07:00