Commit Graph

1693 Commits

Author SHA1 Message Date
Arnold Schwaighofer
1b8cc91ef3 Merge pull request #37832 from aschwaighofer/change_async_task_wait_abi
Change _wait(_throwing) ABIs to reduce code size
2021-06-15 06:49:42 -07:00
Adrian Prantl
946e8ef21c Fix a debug info regression introduced with async support.
This patch removes a heuristic to promote all debug intrinsics pointing into
allocas to llvm.dbg.declare() intrinsics and instead more accurate classifies
variables in async contexts by adding the missing cases alloc_box and
alloc_stack cases.

rdar://78977132
2021-06-09 11:42:45 -07:00
Arnold Schwaighofer
10e3d2e3af Change _wait(_throwing) ABIs to reduce code size
Changes the task, taskGroup, asyncLet wait funtion call ABIs.

To reduce code size pass the context parameters and resumption function
as arguments to the wait function.

This means that the suspend point does not need to store parent context
and resumption to the suspend point's context.

```
  void swift_task_future_wait_throwing(
    OpaqueValue * result,
    SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
    AsyncTask *task,
    ThrowingTaskFutureWaitContinuationFunction *resume,
    AsyncContext *callContext);
```

The runtime passes the caller context to the resume entry point saving
the load of the parent context in the resumption function.

This patch adds a `Metadata *` field to `GroupImpl`. The await entry
pointer no longer pass the metadata pointer and there is a path through
the runtime where the task future is no longer available.
2021-06-08 10:41:26 -07:00
Arnold Schwaighofer
6696bcf5b2 IRGen: Fix the insert point after inserting the dynamic replacement prolog
The code used the last basic block in the function instead of the last
basic block created for the dynamic replacement prolog.

rdar://77073666
2021-05-03 11:47:13 -07:00
John McCall
ec5215bf4f Remove the implicit nil inhabitant of Builtin.Executor,
and traffic in Optional<Builtin.Executor> in various places.
2021-04-30 03:11:56 -04:00
Arnold Schwaighofer
1f890dc6a2 IRGen: Fix async dynamic replacements
We need to emit a full async suspend sequence when calling the
replacement.

rdar://77072724
2021-04-23 09:03:51 -07:00
Konrad `ktoso` Malawski
ba615029c7 [Concurrency] Store child record when async let child task spawned 2021-04-19 10:06:23 +09:00
Doug Gregor
e77a27e8ed [Concurrency] Introduce runtime detection of data races.
Through various means, it is possible for a synchronous actor-isolated
function to escape to another concurrency domain and be called from
outside the actor. The problem existed previously, but has become far
easier to trigger now that `@escaping` closures and local functions
can be actor-isolated.

Introduce runtime detection of such data races, where a synchronous
actor-isolated function ends up being called from the wrong executor.
Do this by emitting an executor check in actor-isolated synchronous
functions, where we query the executor in thread-local storage and
ensure that it is what we expect. If it isn't, the runtime complains.
The runtime's complaints can be controlled with the environment
variable `SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL`:

  0 - disable checking
  1 - warn when a data race is detected
  2 - error and abort when a data race is detected

At an implementation level, this introduces a new concurrency runtime
entry point `_checkExpectedExecutor` that checks the given executor
(on which the function should always have been called) against the
executor on which is called (which is in thread-local storage). There
is a special carve-out here for `@MainActor` code, where we check
against the OS's notion of "main thread" as well, so that `@MainActor`
code can be called via (e.g.) the Dispatch library's
`DispatchQueue.main.async`.

The new SIL instruction `extract_executor` performs the lowering of an
actor down to its executor, which is implicit in the `hop_to_executor`
instruction. Extend the LowerHopToExecutor pass to perform said
lowering.
2021-04-12 15:19:51 -07:00
nate-chandler
e45acc2368 Merge pull request #36856 from nate-chandler/rdar76479222
[IRGen] Emit PAF for generic methods.
2021-04-12 08:55:29 -07:00
nate-chandler
f4fc0227da Merge pull request #36810 from nate-chandler/concurrency/irgen/rdar76372871
[IRGen] Restored single refcounted object opt for async partial applies.
2021-04-12 08:21:39 -07:00
Nate Chandler
ba4aa08b04 [IRGen] Emit PAF for generic methods.
Previously, the partial application of a generic method at the receiver
would result in the emission of a "simple" partial apply where the
receiver was treated as the context and the original function was
treated as the function.  That was problematic because such partial
applications must capture the polymorphic arguments supplied at
partial_apply time.  Here, a full partial application forwarder is
emitted for this case.

rdar://76479222
2021-04-11 18:50:22 -07:00
Erik Eckstein
0456d95cb0 SIL: Use StackList in BasicBlockWorklist and BasicBlockSetVector
plus: I moved both data structures into a separate header file.
2021-04-11 14:07:26 +02:00
Nate Chandler
08f5aae366 [IRGen] Restored single refcounted object opt for async partial applies.
As part of bringup, specifically in order to support storing the size of
the async context as the first entry in the thick context, the
optimization that allows the partial application of a single refcounted
object to avoid the allocation of a thick context was disabled.

Now that we have async function pointers for partial application
forwarders, that rationale is moot, so, here, the optimization is
restored.

rdar://76372871
2021-04-09 12:40:48 -07:00
John McCall
82c190af21 Merge pull request #36751 from rjmccall/two-word-executor
Change ExecutorRef and fix the actor runtime
2021-04-08 16:49:37 -04:00
John McCall
156264f8e8 Make ExecutorRef two words. 2021-04-08 12:57:12 -04:00
Arnold Schwaighofer
d4246b904d hop_to_executor should have no affect if we inline a [noasync] apply into a non async function.
rdar://76230423
2021-04-08 07:41:13 -07:00
Nate Chandler
6bbc96b8c8 [IRGen] Added fn ptr to async FunctionPointer.
The address of the function to be called when generating code to invoke
the function associated with FunctionPointer which is produced via
direct reference is by definition statically known; it is neither necessary
nor desireable to load this address out of the AsyncFunctionPointer
corresponding to the function.

Here, that spurious additional work is skipped.  The approach is to add
a second value to the FunctionPointer struct.  For FunctionPointers
whose kind is AsyncFunctionPointer, this value is either null or else
the address of the corresponding function.

rdar://71376092
2021-04-07 16:11:09 -07:00
Nate Chandler
d3e0e7af07 [ptrauth] Signed AsyncFunctionPointers as data.
Previously, AsyncFunctionPointer constants were signed as code.  That
was incorrect considering that these constants are in fact data.  Here,
that is fixed.

rdar://76118522
2021-04-05 18:24:41 -07:00
John McCall
4f6f8b3377 Rewrite hop_to_executor so that it takes a Builtin.Executor in IRGen
The comment in LowerHopToActor explains the design here.
We want SILGen to emit hops to actors, ignoring executors,
because it's easier to fully optimize in a world where deriving
an executor is a non-trivial operation.  But we also want something
prior to IRGen to lower the executor derivation because there are
useful static optimizations we can do, such as doing the derivation
exactly once on a dominance path and strength-reducing the derivation
(e.g. exploiting static knowledge that an actor is a default actor).

There are probably phase-ordering problems with doing this so late,
but hopefully they're restricted to situations like actors that
share an executor.  We'll want to optimize that eventually, but
in the meantime, this unblocks the executor work.
2021-03-30 20:08:41 -04:00
John McCall
98711fd628 Revise the continuation ABI.
The immediate desire is to minimize the set of ABI dependencies
on the layout of an ExecutorRef.  In addition to that, however,
I wanted to generally reduce the code size impact of an unsafe
continuation since it now requires accessing thread-local state,
and I wanted resumption to not have to create unnecessary type
metadata for the value type just to do the initialization.

Therefore, I've introduced a swift_continuation_init function
which handles the default initialization of a continuation
and returns a reference to the current task.  I've also moved
the initialization of the normal continuation result into the
caller (out of the runtime), and I've moved the resumption-side
cmpxchg into the runtime (and prior to the task being enqueued).
2021-03-28 12:58:16 -04:00
Arnold Schwaighofer
414e6c7dfd IRGen: Fix debug_value emission for constants in async functions
rdar://75534499
2021-03-22 10:22:54 -07:00
Arnold Schwaighofer
3bdd5cb99a IRGen: async error ABI
Throwing functions pass the error result in `swiftself` to the resume
partial function.
Therefore, `() async -> ()` to `() async throws -> ()` is not ABI compatible.

TODO: go through remaining failing IRGen async tests and replace the
illegal convert_functions.
2021-03-17 17:17:12 -07:00
Arnold Schwaighofer
5b4e0566b9 [IRGen] Fix debug info for direct arguments/return values
Emit shadow copies in async functions and emit a load to get the value.
2021-03-17 07:41:10 -07:00
Arnold Schwaighofer
f75fbb7594 IRGen: Async ABI passing parameter and results directly
The error is still passed in the async context. I will fix this in a
follow-up.
2021-03-17 07:41:01 -07:00
John McCall
6c879d6fd3 Change the async ABI to not pass the active task and executor.
Most of the async runtime functions have been changed to not
expect the task and executor to be passed in.  When knowing the
task and executor is necessary, there are runtime functions
available to recover them.

The biggest change I had to make to a runtime function signature
was to swift_task_switch, which has been altered to expect to be
passed the context and resumption function instead of requiring
the caller to park the task.  This has the pleasant consequence
of allowing the implementation to very quickly turn around when
it recognizes that the current executor is satisfactory.  It does
mean that on arm64e we have to sign the continuation function
pointer as an argument and then potentially resign it when
assigning into the task's resume slot.

rdar://70546948
2021-03-16 22:52:54 -04:00
eeckstein
898cdc0fc1 Merge pull request #36439 from eeckstein/lookup-table-opt
Remove unnecessary retain/release/initialization overhead from lookup table Arrays.
2021-03-16 15:11:13 +01:00
Nate Chandler
ee63777332 [IRGen] Fix ABI for thick async functions.
Previously, thick async functions were represented sometimes as a pair
of (AsyncFunctionPointer, nullptr)--when the thick function was produced
via a thin_to_thick_function, e.g.--and sometimes as a pair of
(FunctionPointer, ThickContext)--when the thick function was produced by
a partial_apply--with the size stored in the slot of the ThickContext.

That optimized for the wrong case: partial applies of dynamic async
functions; in that case, there is no appropriate AsyncFunctionPointer to
form when lowering the partial_apply instruction.  The far more common
case is to know exactly which function is being partially applied.  In
that case, we can form the appropriate AsyncFunctionPointer.

Furthermore, the previous representation made calling a thick function
more complex: it was always necessary to check whether the context was
in fact null and then proceed along two different paths depending.

Here, that behavior is corrected by creating a thunk in a mandatory
IRGen SIL pass in the case that the function that is being partially
applied is dynamic.  That new thunk is then partially applied in place
of the original partial_apply of the dynamic function.
2021-03-15 13:37:40 -07:00
Erik Eckstein
c62b452ee0 IRGen: don't initialized a global_object static object if not needed.
We don't need to initialize the global object if it's never used for something which can access the object header.

This let's e.g. lookup-tables to be compiled with zero Array-overhead.

rdar://59874359
2021-03-15 11:54:23 +01:00
Andrew Trick
97ec127d25 Lower and emit debug_value [poison].
OwnershipEliminator lowers destroy_value [poison] to debug_value
[poison].

IRGen overwrites all references in shadow copies with a sentinel value
in place of debug_value [poison].

Part 2/2: rdar://75012368 (-Onone compiler support for early object
deinitialization with sentinel dead references)
2021-03-12 19:33:23 -08:00
adrian-prantl
2aae121f62 Merge pull request #36301 from adrian-prantl/75012612
Support local variables in virtual async backtraces.
2021-03-12 16:45:38 -08:00
Adrian Prantl
3401f8ab93 Support local variables in virtual async backtraces.
rdar://75012612
2021-03-10 17:52:20 -08:00
Arnold Schwaighofer
8c5fc073fd [IRGen] Use coro.end.async to return from an async function
The `coro.end.async` intrinsic allow specifying a function that is to be
tail-called as the last thing before returning.

LLVM lowering will inline the `must-tail-call` function argument to
`coro.end.async`. This `must-tail-call` function can contain a
`musttail` call.

```
define @my_must_tail_call_func(void (*)(i64) %fnptr, i64 %args) {
  musttail call void %fnptr(i64 %args)
  ret void
}

define @async_func() {
  ...
  coro.end.async(..., @my_must_tail_call_func, %return_continuation, i64 %args)
  unreachable
}
```
2021-03-10 10:15:27 -08:00
Adrian Prantl
e51bcdb3e9 Enable lifetime extension for local variables and function arguments in async
functions at -Onone to force them to get promoted into the async context.

This patch includes a partial revert of a83bfabc8b.
2021-03-03 15:00:07 -08:00
Konrad `ktoso` Malawski
5427986255 Merge pull request #36228 from ktoso/wip-groups-towards-clean-abi
[TaskGroup] Towards ABI stability of groups
2021-03-03 11:46:22 +09:00
Konrad `ktoso` Malawski
aedbbe615d [TaskGroup] Towards ABI stability of groups 2021-03-02 20:25:22 +09:00
Arnold Schwaighofer
b11b0a4600 IRGen: Remove hack
Since llvm-project PR#2557 llvm will no longer use r11 for swiftasync
2021-03-01 15:03:44 -08:00
Konrad `ktoso` Malawski
2ab160e7da Merge branch 'main' into wip-no-escape-group 2021-02-26 07:56:00 +09:00
Adrian Prantl
c2dc87cd6b Debug info support for let await result variables. 2021-02-24 12:55:24 -08:00
Konrad `ktoso` Malawski
655d8f13e7 cleanup after rebase; this is likely incorrect in some way 2021-02-24 12:10:49 +09:00
John McCall
fd96f4139d Work around a bug in the x86_64 swiftasync argument treatment.
r11 is the linker scratch register, so we need to make sure that
we don't end up in the linker when making cross-library direct
async calls.  Since there are currently only a few special
symbols that we do that for, we can achieve this by disabling
lazy binding for those symbols specifically.
2021-02-22 02:39:53 -05:00
John McCall
2012195cd5 Alter the runtime interface for awaiting futures and task groups.
First, just call an async -> T function instead of forcing the caller
to piece together which case we're in and perform its own copy.  This
ensures that the task is actually kept alive properly.

Second, now that we no longer implicitly depend on the waiting tasks
being run synchronously, go ahead and schedule them to run on the
global executor.

This solves some problems which were blocking the work on TLS-ifying
the task/executor state.
2021-02-21 23:48:13 -05:00
Adrian Prantl
582bbbdbd9 Add debug info support for direct async arguments.
rdar://74460135
2021-02-19 15:48:59 -08:00
Arnold Schwaighofer
29db4015e8 IRGen: We can only reuse methods for partial apply thunks if their abi uses swiftself for self
rdar://73777202
2021-02-16 18:37:24 -08:00
nate-chandler
de63a23e77 Merge pull request #35603 from nate-chandler/concurrency/irgen/rdar71378532
[Async CC] Make error indirect.
2021-02-16 07:39:14 -08:00
Michael Gottesman
133901d6f6 [irgen] Emit shadow copies for ConstantDataVector.
LLVM seems to not support this today. With ownership SSA, we now produce these
for accelerate for some reason, causing lldb/TestAccelerateSIMD.py to fail. I
debugged this with Adrian and we got this fix. I filed the radar below against
Adrian to fix.

rdar://74287800
2021-02-12 23:20:17 -08:00
eeckstein
d6a7e9b532 Merge pull request #35935 from eeckstein/basicblock-worklist
SIL: A utility for processing basic blocks in a worklist.
2021-02-13 07:35:44 +01:00
Slava Pestov
72e1f02ae2 IRGen: Fix async dispatch thunk emission with loadable return value
Fixes <rdar://problem/74246091>.
2021-02-12 14:06:07 -05:00
Erik Eckstein
214b7a9929 Use the new BasicBlockWorklist utility in various places in the compiler.
It's a refactoring which simplifies the code.
NFC.
2021-02-12 11:15:55 +01:00
Erik Eckstein
fe10f98cf0 SIL: rename the SILBitfield.h header file to BasicBlockBits.h
NFC
2021-02-12 11:15:55 +01:00
Nate Chandler
e2a8abc9e5 [Async CC] Make error indirect.
Previously, the error stored in the async context was of type SwiftError
*.  In order to enable the context to be callee released, make it
indirect and change its type to SwiftError **.

rdar://71378532
2021-02-11 11:34:47 -08:00