Commit Graph

446 Commits

Author SHA1 Message Date
Pavel Yaskevich
f7f2e3709b [Sema] RuntimeMetadata: Synthesize a body for runtime attribute generator
Single expression is not going to cut it in this case because attribute
and attached declaration could have different availability, so we need
to use `if #available` to guard attribute instantiation and return `nil`
in cases where types are not available.
2022-12-20 09:45:01 -08:00
Pavel Yaskevich
b83b0943b5 [SILDeclRef] RuntimeMetadata: Add a special kind for runtime attribute generator
A new `RuntimeAttributeGenerator` is used to reference runtime
attribute generator functions synthesized by SILGen.
`#function` magic literal points to the declaration that declaration
attribute is attached to.
2022-12-20 09:45:01 -08:00
Pavel Yaskevich
91042d77aa [SILGen] Make it possible to emit generator function given its body and result type
This would be used for runtime attribute generators that have to
emit `if #available(...)` block in the body which is much easier
to do during Sema.
2022-12-20 09:45:01 -08:00
Pavel Yaskevich
3fb69b3c3c [SIL] SILFunction: Add runtime accessible function attribute
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
2022-12-20 09:33:44 -08:00
Pavel Yaskevich
77fb90ee19 [Sema/SILGen] Add asserts to getParameterAt call sites that expect non-null parameter 2022-11-17 11:52:00 -08:00
Robert Widmann
fc52e7adc6 Look for the C-Language Copy of UIApplicationMain
A long while back we added a copy of UIApplicaitonMain to the UIKit
overlay. This was intended to fix the signature of UIApplicationMain by
forcing clients to choose a non-deprecated copy with revised nullability
annotations that were compatible with the (then) interface of the (then)
CommandLine stdlib type. Since then, we've gone in a completely different
direction with type-based entrypoints and @main, but the compatibility
shims remain. This code was assuming that it would always find one
declaration of UIApplicationMain in the clang module, but that's not
a sound assumption to make. In certain scenarios, we can wind up finding
the overlay's copy of UIApplicationMain too. When that's the Swift
function, we reference a native-to-foreign thunk that we don't actually
wind up generating in the open-coding and this results in a nasty linker
error. Filter the available candidates here looking for the C copy of
UIApplicationMain.

rdar://101932338
2022-11-04 10:22:41 -07:00
Hamish Knight
809cfb7bf2 [Profiler] Introduce ProfileCounterRef
For now this just wraps an ASTNode, but in the
future it will allow us to model counters
that cannot simply hang off ASTNodes, e.g
error branch counters.
2022-10-13 19:42:37 +01:00
Hamish Knight
5a8c14d583 [Profiler] Fix up a couple uses of emitProfilerIncrement
Remove a case where we know we don't have a
profiler, and avoid incrementing for a distributed
factory method. Otherwise such cases could pass
a null ASTNode, which will become an assertion
failure in a future commit.

While we're here, let's standardize on emitting
the profiler increment for function entry after
the prolog, as if there's e.g an unreachable
parameter, the increment can be safely elided
anyway.
2022-10-13 19:42:36 +01:00
Hamish Knight
b12015c343 [SIL] Introduce the increment_profiler_counter instruction
This is a dedicated instruction for incrementing a
profiler counter, which lowers to the
`llvm.instrprof.increment` intrinsic. This
replaces the builtin instruction that was
previously used, and ensures that its arguments
are statically known. This ensures that SIL
optimization passes do not invalidate the
instruction, fixing some code coverage cases in
`-O`.

rdar://39146527
2022-09-07 17:55:13 +01:00
Hamish Knight
27b27a400e [Profiler] Fix autoclosure property wrapper crash
We need to query the top-level expression, not
the sub-expression of a potential function
conversion.

rdar://99449154
2022-09-01 19:29:19 +01:00
Hamish Knight
6a6ba8300c [Profiler] Re-enable an assertion
This was disabled as it was hit when attempting to
profile lazy variables. Now that we handle them
correctly, re-enable it.
2022-08-19 14:03:41 +01:00
Michael Gottesman
f1182a73da [no-implicit-copy] Remove auto +1 param signature change called by noimplicit copy in favor of following normal convention.
I also added a bunch of tests for both the trivial/non-trivial case as well as
some docs to SIL.rst.
2022-07-19 16:39:03 -07:00
Joe Groff
6b6a557611 SILGen: Carry WMO of type lowering context to closure captures.
TypeConverter doesn't know by itself what SILModule it's currently lowering on
behalf of, so the existing code forming the TypeExpansionContext for opaque types
incorrectly set the isWholeModule flag to always false. This created a miscompile
when a public API contained a closure that captured a value involving private types
from another file in the same module because of mismatched type expansion contexts
inside and outside the closure. Fixes rdar://93821679
2022-06-06 19:51:40 -07:00
Nate Chandler
6acfad653f [SIL-opaque] Handled forward captures.
A let that isn't defined yet can be captured by a local function to
which a closure is formed.  Don't use an address type unless we're using
lowered addresses.
2022-03-23 12:34:08 -07:00
Andrew Trick
caaad424d8 [SIL-opaque] Various SILGen fixes 2022-03-22 17:04:13 -07:00
Andrew Trick
2907c61203 SILModule::hasLoweredAddress 2022-03-09 17:18:15 -08:00
John McCall
716f4b9e2f Hop to the generic executor in non-actor-isolated async functions.
Async functions are now expected to set ExpectedExecutor in their
prologue (and, generally, immediately hop to it).  I updated the
prologue code for a bunch of function emission, most of which was
uninteresting.  Top-level code was not returning to the main
executor, which is now fixed; fortunately, we weren't assuming
that we were on the main executor yet.

We had some code that only kicked in when an ExpectedExecutor
wasn't set which made us capture the current executor before
a hop and then return to it later.  This code has been removed;
there's no situation in which save-and-return is the semantically
correct thing to do given the possibility of hop optimization.
I suspect it could also have led to crashes if the current
executor is being kept alive only because it's currently running
code.  If we ever add async functions that are supposed to inherit
their caller's executor, we should have the caller pass the right
executor down to it.

This is the first half of SE-0338; the second, sendability
enforcement, is much more complicated, and Doug has volunteered
to do it.

Fixes rdar://79284465, as well as some tests that were XFAILed
on Windows.
2022-01-27 01:53:19 -05:00
Evan Wilde
431b6661e4 Generate async main entrypoint for top-level
This patch adds the SILGen side of generating the asynchronous main
entrypoint for top-level code. The behavior is the same as with the
asynchronous MainType entrypoint.
2022-01-12 15:40:39 -08:00
Pavel Yaskevich
4860f90fd7 [SIL] Add new flag to SILFunction - IsDistributed
Determines whether given SILFunction represents a distributed
method or its thunk.
2021-12-17 10:52:52 -08:00
Evan Wilde
1cc4dd414d Conjure up asyncMainDrainQueue
The asyncMainDrainQueue is also declared `internal`, so it won't show up
in the swiftinterface file.

The expected declaration is:

```
@available(SwiftStdlib 5.5, *)
@_silgen_name("swift_task_asyncMainDrainQueue")
internal func _asyncMainDrainQueue() -> Never
```
2021-11-16 21:36:51 -08:00
Karoy Lorentey
47956908b7 [Concurrency] SwiftStdlib 5.5 ⟹ SwiftStdlib 5.1 (usages)
The concurrency runtime now deploys back to macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, which corresponds to the 5.1 release of the stdlib.

Adjust macro usages accordingly.
2021-10-28 14:36:36 -07:00
Evan Wilde
e10bb9f56a Workaround to cope with older SDKs
getMainExecutor swift decl doesn't exist on older concurrency-supporting
SDKs, but the `swift_task_getMainExecutor` function does exist. This
causes the compiler to crash while compiling async-main functions with
older SDKs.
2021-10-27 12:37:06 -07:00
Evan Wilde
bb80f9f329 Replace reinterpret cast with struct
A single-element struct is structurally the same as the member type
itself.
2021-10-04 09:53:11 -07:00
Evan Wilde
493eca3272 Inherit main thread priority/context
This patch changes the main task to inherit the context of the main
thread. This should assign the appropriate priority based on how the
program was invoked. I've also updated the tests to reflect these
changes.
2021-10-02 16:53:06 -07:00
Evan Wilde
d376ee9989 Run first thunk of Async main synchronously
This patch updates the asynchronous main function to run the first thunk
of the function synchronously through a call to `swift_job_run`.

The runloop is killed by exiting or aborting the task that it is running
on. As such, we need to ensure that the task contains an async function
that either calls exit explicitly or aborts. The AsyncEntryPoint, that
contains this code, was added in the previous patch. This patch adds the
pieces for the actual implementation of this behaviour as well as adding
the necessary code to start the runloop.

There are now four layers of main functions before hitting the "real"
code.

@main: This is the actual main entrypoint of the program. This
constructs the task containing @async_main, grabs the main executor,
runs swift_job_run to run the first part synchronously, and finally
kicks off the runloop with a call to _asyncMainDrainQueue. This is
generated in the call to `emitAsyncMainThreadStart`.

@async_main: This thunk exists to ensure that the main function calls
`exit` at some point so that the runloop stops. It also handles emitting
an error if the user-written main function throws.

e.g:

```
func async_main() async -> () {
  do {
    try await Main.$main()
    exit(0)
  } catch {
    _errorInMain(error)
  }
}
```

Main.$main(): This still has the same behaviour as with the
synchronous case. It just calls `try await Main.main()` and exists to
simplify typechecking.

Main.main(): This is the actual user-specified main. It serves the same
purpose as in the synchronous, allowing the programmer to write code,
but it's async!

The control flow in `emitFunctionDefinition` is a little confusing (to
me anyway), so here it is spelled out:

If the main function is synchronous, the `constant.kind` will be a
`SILDeclRef::Kind::EntryPoint`, but the `decl` won't be async, so it
drops down to `emitArtificalTopLevel` anyway.

If the main function is async and we're generating `@main`, the
`constant.kind` will be `SILDeclRef::Kind::AsyncEntryPoint`, so we also
call `emitArtificalTopLevel`. `emitArtificalTopLevel` is responsible for
detecting whether the decl is async and deciding whether to emit code to
extract the argc/argv variables that get passed into the actual main
entrypoint to the program. If we're generating the `@async_main` body,
the kind will be `SILDeclRef::Kind::EntryPoint` and the `decl` will be
async, so we grab the mainEntryPoint decl and call
`emitAsyncMainThreadStart` to generate the wrapping code.

Note; there is a curious change in `SILLocation::getSourceLoc()`
where instead of simply checking `isFilenameAndLocation()`, I change it
to `getStorageKind() == FilenameAndLocationKind`. This is because the
SILLocation returned is to a FilenameAndLocationKind, but the actual
storage returns true for the call to `isNull()` inside of the
`isFilenameAndLocation()` call. This results in us incorrectly falling
through to the `getASTNode()` call below that, which asserts when asked
to get the AST node of a location.

I also did a little bit of refactoring in the SILGenModule for grabbing
intrinsics. Previously, there was only a `getConcurrencyIntrinsic`
function, which would only load FuncDecls out of the concurrency
module. The `exit` function is in the concurrency shims module, so I
refactored the load code to take a ModuleDecl to search from.

The emitBuiltinCreateAsyncTask function symbol is exposed from
SILGenBuiltin so that it is available from SILGenFunction. There is a
fair bit of work involved going from what is available at the SGF to
what is needed for actually calling the CreateAsyncTask builtin, so in
order to avoid additional maintenance, it's good to re-use that.
2021-10-02 16:53:06 -07:00
Evan Wilde
552ae0635a Add AsyncEntryPoint SILDeclRef type
The AsyncEntryPoint represents the thunk that is wrapped in a task. This
thunk is used to ensure that the main function explicitly calls "exit",
and to properly unwrap and report any unhandled errors returned from the
user-written main. The function takes on the name `@async_main` in the
emitted SIL.
2021-10-02 16:53:06 -07:00
Joe Groff
fdc0e08d60 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-09 13:42:02 -07:00
Joe Groff
3abe16f40f Revert "SILGen: Emit literal closures at the abstraction level of their context. [take 2]" (#39228) 2021-09-09 11:53:43 -05:00
Joe Groff
43506a29a2 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-07 11:55:29 -07:00
Dario Rexin
d43ea45b6a Revert "Revert "Merge pull request #38938 from drexin/wip-dist-resolve" (#38994)" (#39011)
This reverts commit f6ae9f3387.
2021-08-24 13:33:37 +09:00
Konrad `ktoso` Malawski
f6ae9f3387 Revert "Merge pull request #38938 from drexin/wip-dist-resolve" (#38994)
This reverts commit a4f3f2fb48, reversing
changes made to 8cf6c2e71b.
2021-08-23 20:30:41 +09:00
Dario Rexin
3161d8f66c [Distributed] Generate SIL for DistributedActor.resolve
rdar://78484431
2021-08-19 17:32:00 -07:00
Holly Borla
86e1014399 Revert " SILGen: Emit literal closures at the abstraction level of their context." 2021-08-18 09:03:23 -07:00
Joe Groff
309500d4bf SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-08-16 09:39:19 -07:00
Holly Borla
bd80342a4b [SILGen] Record local auxiliary decls when a parameter is emitted, and
emit those auxiliary decls inside the function body brace statement.

This generalizes the old code to work for parameters to any kind of
function (e.g. initializers).
2021-08-12 13:56:05 -07:00
Konrad `ktoso` Malawski
829a5d6895 [Distributed] Review followup and cleanups 2021-08-12 14:09:03 +09:00
Konrad `ktoso` Malawski
7e0a3eba13 [Distributed] Implementing calling transport in resolve and assigning id/transp 2021-08-12 14:08:58 +09:00
Kavon Farvardin
c49f7d0a50 [distributed] synthesize factory resolve func 2021-08-12 14:05:31 +09:00
Hamish Knight
ed104a8134 Merge pull request #37014 from hamishknight/entry-sign 2021-05-19 08:32:40 +01:00
Doug Gregor
2b9ca315fe [Concurrency] Remove asyncHandler attribute.
The `asyncHandler` attribute turned out to be the wrong solution
to the problem of creating a sync->async bridge. Remove it.
2021-05-13 17:01:39 -07:00
Hamish Knight
de7e5efed6 [SILGen] Add SILDeclRef for main entry-point
Allow SILDeclRef to refer to the main program
entry-point, which will either be for a main
SourceFile, or a synthetic main such as an `@main`
decl. Adjust the various SILDeclRef related
functions to handle this new case, and change the
emission to go through `emitFunctionDefinition`.

This change will allow the entry-point for an `@main`
decl (and eventually a main SourceFile) to be
emitted on-demand from its symbol name.
2021-04-26 11:42:32 +01:00
Kavon Farvardin
7089bf603d [nfc] rename one of the two emitPrologs in SILGen
There's a basic prolog emission function, used by value and class constructors, etc, and then there's the full-blown one for functions and closures, which uses the basic version.
2021-04-15 10:06:42 -07:00
Erik Eckstein
6ec788ff09 SIL: remove the SILOpenedArchetypesTracker
Instead, put the archetype->instrution map into SIlModule.

SILOpenedArchetypesTracker tried to maintain and reconstruct the mapping locally, e.g. during a use of SILBuilder.
Having a "global" map in SILModule makes the whole logic _much_ simpler.

I'm wondering why we didn't do this in the first place.

This requires that opened archetypes must be unique in a module - which makes sense. This was the case anyway, except for keypath accessors (which I fixed in the previous commit) and in some sil test files.
2021-04-14 08:36:10 +02:00
Holly Borla
a15f4233a2 [Property Wrappers] Implement implementation-detail property wrappers for
parameters.
2021-03-31 09:29:46 -07:00
Holly Borla
21a86b5d2f [NFC][Property Wrappers] Split PropertyWrapperBackingPropertyInfoRequest into
two separate requests - one to synthesize the auxiliary declarations, and
another to compute how the backing storage is initialized.
2021-03-19 13:03:13 -07:00
Slava Pestov
b6381d4549 Sema: Ban forward references of captured values from 'defer' body
While 'defer' is implemented as a local function, it doesn't
behave as one. In particular, since SILGen runs it after
destroying all local bindings that appear after the 'defer'
definition, the body of a 'defer' cannot forward reference
captured bindings the way that local functions can.

Note that I had to remove a SILGen test case for an older,
related issue. The new diagnostic in Sema catches these cases
earlier.

Fixes rdar://problem/75088379.
2021-03-15 17:17:30 -04:00
Holly Borla
648c5753df [SILGen] Teach SILGen to emit property wrapper generator functions that
take in a projected value.
2021-02-25 18:35:14 -08:00
Holly Borla
13692fefde [Property Wrappers] Store property wrapper "init from projection" expressions
in PropertyWrapperBackingPropertyInfo.
2021-02-25 18:35:14 -08:00
Holly Borla
c5bed94843 [SILGen] Teach SILGen to emit property wrapper parameters. 2021-02-25 18:35:13 -08:00
Joe Groff
fb199df1c7 SILGen: Support overriding/conforming to ObjC APIs with async error flag arguments. 2021-02-23 08:56:44 -08:00