Commit Graph

159 Commits

Author SHA1 Message Date
John McCall
3aa04db87b Track whether a task is actively running.
Tracking this as a single bit is actually largely uninteresting
to the runtime.  To handle priority escalation properly, we really
need to track this at a finer grain of detail: recording that the
task is running on a specific thread, enqueued on a specific actor,
or so on.  But starting by tracking a single bit is important for
two reasons:

- First, it's more realistic about the performance overheads of
  tasks: we're going to be doing this tracking eventually, and
  the cost of that tracking will be dominated by the atomic
  access, so doing that access now sets the baseline about right.

- Second, it ensures that we've actually got runtime involvement
  in all the right places to do this tracking.

A propos of the latter: there was no runtime involvement with
awaiting a continuation, which is a point at which the task
potentially transitions from running to suspended.  We must do
the tracking as part of this transition, rather than recognizing
in the run-loops that a task is still active and treating it as
having suspended, because the latter point potentially races with
the resumption of the task.  To do this, I've had to introduce
a runtime function, swift_continuation_await, to do this awaiting
rather than inlining the atomic operation on the continuation.

As part of doing this work, I've also fixed a bug where we failed
to load-acquire in swift_task_escalate before walking the task
status records to invoke escalation actions.

I've also fixed several places where the handling of task statuses
may have accidentally allowed the task to revert to uncancelled.
2021-07-14 20:24:01 -04:00
Mike Ash
c2df2448ec [Concurrency] Reserve two more words in Job.
Keep Task the same size by pulling two words out of OpaquePrivateStorage.

rdar://79313908
2021-06-16 16:59:25 -04:00
Fred Riss
bbda706393 [Concurrency] Add a unique Task ID to AsyncTask
This commit changes JobFlags storage to be 32bits, but leaves the runtime
API expressed in terms of size_t. This allows us to pack an Id in the
32bits we freed up.

The offset of this Id in the AsyncTask is an ABI constant. This way
introspection tools can extract the currently running task identifier
without any need for special APIs.
2021-05-11 08:28:17 -07:00
Arnold Schwaighofer
fe29da2754 IRGen: Fix signing of resumeParent in emitGetAsyncContinuation
rdar://76103735
2021-04-02 06:51:40 -07: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
Joe Groff
0f395e347d IRGen: Initialize the executor field in continuation contexts again.
Fixes rdar://75783864.
2021-03-24 13:41:50 -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
Arnold Schwaighofer
cb3703c47d Adjust to llvm change that requires suspend.async to specify the index of the async context 2021-02-23 13:28:38 -08:00
Nate Chandler
893d28c9b3 [IRGen] Signed parent async context. 2021-02-03 17:51:18 -08:00
Nate Chandler
5261c31ed0 [IRGen] Sign TaskResumeFunction. 2021-02-03 17:51:02 -08:00
Nate Chandler
c31cb54d35 [IRGen] Sign TaskResumeContext. 2021-02-03 17:50:50 -08:00
Slava Pestov
c133e13efd Merge pull request #34916 from slavapestov/with-unsafe-continuation
Concurrency: Implement withUnsafe[Throwing]Continuation
2020-12-03 11:18:49 -05:00
swift-ci
14ea0e56d4 Merge pull request #34937 from aschwaighofer/clarify_comment 2020-12-03 07:26:19 -08:00
Arnold Schwaighofer
71a993c603 Clarify comment 2020-12-03 05:05:19 -08:00
Erik Eckstein
752558ce18 IRGen: fix the LLVM struct definition of AsyncTask.
The object header was missing.
2020-12-03 11:56:44 +01:00
Slava Pestov
a2dbdecdab SIL: Refactor get_async_continuation[_addr] to return a RawUnsafeContinuation 2020-12-01 20:04:09 -05:00
Erik Eckstein
bf2be9eb5d [concurrency] IRGen: update task/executor/context on every suspend point
For this, store those 3 values on the stack at function entry and update them with the return values of coro_suspend_async intrinsic calls.

This fixes a correctness issue, because the executor may be different after a resume.
It also is more efficient, because this means that the 3 values don't have to preserved in the context over a suspension point.
2020-12-01 15:19:39 +01:00
Arnold Schwaighofer
b0be562ded Merge pull request #34829 from aschwaighofer/irgen_get_await_async_continuation
IRGen: get/await_async_continuation support
2020-11-30 11:22:55 -08:00
Arnold Schwaighofer
505a6ee1d3 Also store the current executor in the async_continuation_context at the time of 2020-11-20 14:46:41 -08:00
Doug Gregor
307959e733 [IRGen] Don't mark calls to swift_task_alloc as 'readnone'.
Doing so causes later passes to coalesce swift_task_alloc calls.
2020-11-19 23:26:30 -08:00
Arnold Schwaighofer
beb3951c3f Get rid of getOrCreateAwaitAsyncSupendFn 2020-11-19 13:05:06 -08:00
Arnold Schwaighofer
5dbb1a467c Fix memory orderings 2020-11-19 12:20:32 -08:00
Arnold Schwaighofer
d75e4c2bd2 IRGen: get/await_async_continuation support.
rdar://71124933
2020-11-19 08:43:26 -08:00
Arnold Schwaighofer
e7e6490145 IRGen: swift_taskAlloc wants its size input to be multiple of MaximumAlignment 2020-11-14 10:12:33 -08:00
Arnold Schwaighofer
2271d4df55 Use taskAlloc for dynamic allocas
Async coroutines don't support dynamic allocas.
2020-11-13 10:41:42 -08:00
Nate Chandler
2d21932672 [Async CC] Add constant "pointer" for async func.
An AsyncFunctionPointer, defined in Task.h, is a struct consisting of
two i32s: (1) the relative address of the async function and (2) the
size of the async context to be allocated when calling that function.

Here, such structs are emitted for every async SILFunction that is
emitted.
2020-11-12 18:20:10 -08:00
Robert Widmann
40d9cd8d3f [NFC] Give IRGenModule Exclusive Ownership of an LLVMContext Object 2020-04-16 11:57:44 -07:00
Dan Zheng
1779632a6f [IRGen] NFC: silence llvm::MaybeAlign warnings.
Use `llvm::MaybeAlign` instead of `unsigned` to silence slew of warnings.
2020-02-20 08:49:28 +00:00
Erik Eckstein
56ecb8fc9b Enable better runtime failure messages
The implementation was done quite a while ago.
Now, that we have support in lldb (https://github.com/apple/llvm-project/pull/773), we can enable it by default in the compiler.

LLDB now shows the runtime failure reason, for example:

* thread #1, queue = 'com.apple.main-thread', stop reason = Swift runtime failure: arithmetic overflow
    frame #1: 0x0000000100000f0d a.out`testit(a=127) at trap_message.swift:4
   1
   2   	@inline(never)
   3   	func testit(_ a: Int8) -> Int8 {
-> 4   	  return a + 1
   5   	}
   6

For details, see https://github.com/apple/swift/pull/25978

rdar://problem/51278690
2020-02-18 12:03:57 +01:00
Jonas Devlieghere
4db7f40686 Update for upstream intrinsics change (NFC)
The Intrinsic ID is now an opaque typedef to facilitate splitting up
the enum into target-specific enums.
2020-01-03 10:53:22 -08:00
Jonas Devlieghere
027b8659f2 Add missing include for llvm::cl::opt
Include  "llvm/Support/CommandLine.h" for cl::opt.
2019-11-18 09:57:03 -08:00
Erik Eckstein
ffd7f75de3 IRGen: debug info generation for cond_fail messages.
To display a failure message in the debugger, create a function in the debug info which has the name of the failure message.
The debug location of the trap/cond_fail is then wrapped into this function and the function is declared as "inlined".
In case the debugger stops at the trap instruction, it displays the inline function, which looks like the failure message.
For example:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x0000000100000cbf a.out`testit3(_:) [inlined] Unexpectedly found nil while unwrapping an Optional value at test.swift:14:11 [opt]
   11
   12   @inline(never)
   13   func testit(_ a: Int?) -> Int {
-> 14     return a!
   15   }
   16

This change is currently not enabled by default, but can be enabled with the option "-Xllvm -enable-trap-debug-info".
Enabling this feature needs some changes in lldb. When the lldb part is done, this option can be removed and the feature enabled by default.
2019-07-16 14:51:18 +02:00
Brent Royal-Gordon
d5a2912a26 Revert "Better runtime failure messages (not yet enabled by default)" 2019-07-15 13:42:40 -07:00
Erik Eckstein
e915300e96 IRGen: debug info generation for cond_fail messages.
To display a failure message in the debugger, create a function in the debug info which has the name of the failure message.
The debug location of the trap/cond_fail is then wrapped into this function and the function is declared as "inlined".
In case the debugger stops at the trap instruction, it displays the inline function, which looks like the failure message.
For example:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x0000000100000cbf a.out`testit3(_:) [inlined] Unexpectedly found nil while unwrapping an Optional value at test.swift:14:11 [opt]
   11
   12   @inline(never)
   13   func testit(_ a: Int?) -> Int {
-> 14     return a!
   15   }
   16

This change is currently not enabled by default, but can be enabled with the option "-Xllvm -enable-trap-debug-info".
Enabling this feature needs some changes in lldb. When the lldb part is done, this option can be removed and the feature enabled by default.
2019-07-12 14:03:13 +02:00
Bob Wilson
27efdcb8ee master-next: use separate memcpy/memmove src/dest alignment arguments
LLVM r323617 changed the IRBuilder's CreateMemCpy and CreateMemMove
functions to take separate arguments for the destination and source
alignments.
2018-03-28 22:19:16 -07:00
Vedant Kumar
f64d88591e [IRGen] Prevent mergeable traps from being created
PR #14729 made more calls to llvm.trap() non-mergeable. This follow-up
adds asserts to IRBuilder which make it harder to accidentally introduce
mergeable calls to llvm.trap() in the future.

The newly-added assertions exposed an issue in GenBuiltin while
compiling parts of the stdlib. This PR fixes the issue.

Suggested by Adrian Prantl!

rdar://32772768
2018-02-26 13:44:52 -08:00
Vedant Kumar
132bb19274 [IRGen] Avoid generating mergeable traps
Factor out and reuse logic in the lowering of CondFailInst to emit
non-mergeable traps, everywhere we emit traps. This should address a
debugging quality issue with ambiguous ud2 instructions.

rdar://32772768
2018-02-20 13:40:40 -08:00
Slava Pestov
c19478ab3f IRGen: Offset::offsetBy() should take an Offset and a Size 2017-12-07 14:21:58 -08:00
Joe Shajrawi
62d823c56d Code size: Do not use a global state for isOutlined 2017-11-15 15:28:27 -08:00
Joe Shajrawi
5aff0891b7 Code size: copy_addr outline part 2 - Support Archetypes 2017-11-15 15:26:44 -08:00
Erik Eckstein
90c21be191 Unify the implementation of optimization mode in various option classes.
This commit is mostly refactoring.

*) Introduce a new OptimizationMode enum and use that in SILOptions and IRGenOptions
*) Allow the optimization mode also be specified for specific SILFunctions. This is not used in this commit yet and thus still a NFC.

Also, fixes a minor bug: we didn’t run mandatory IRGen passes for functions with @_semantics("optimize.sil.never")
2017-11-14 11:25:02 -08:00
Joe Shajrawi
f4db36426c Code Size: Outline copy addr instruction 2017-10-31 17:03:48 -07:00
Erik Eckstein
9c6fe76927 SIL, IRGen: add instructions "object" and "global_value” to support statically initialized objects.
This commit contains:
-) adding the new instructions + infrastructure, like parsing, printing, etc.
-) support in IRGen to generate global object-variables (i.e. "heap" objects) which are statically initialized in the data section.
-) IRGen for global_value which lazily initializes the object header and returns a reference to the object.

For details see the documentation of the new instructions in SIL.rst.
2017-08-23 09:15:49 -07:00
swift-ci
5a26e4366e Merge remote-tracking branch 'origin/master' into master-next 2017-08-03 10:30:11 -07:00
John McCall
4e48bc0ff7 Cache type-metadata layouts instead of using scanners everywhere. NFC.
Also counts as incremental work towards metadata resilience.
2017-08-03 04:13:53 -04:00
swift-ci
d549147e43 Merge remote-tracking branch 'origin/master' into master-next 2017-07-31 18:48:50 -07:00
John McCall
4dd0e039d7 Sundry minor code improvements, NFC. 2017-07-31 20:42:47 -04:00
John McCall
d4d2145ad8 Merge branch 'master' into master-next 2017-07-29 15:48:00 -04:00
John McCall
a0f20f673d Switch all of the indirect-call code in IRGen to FunctionPointer.
To make this stick, I've disallowed direct use of that overload of
CreateCall.  I've left the Constant overloads available, but eventually
we might want to consider fixing those, too, just to get all of this
code out of the business of manually remembering to pass around
attributes and calling conventions.

The test changes reflect the fact that we weren't really setting
attributes consistently at all, in this case on value witnesses.
2017-07-28 23:26:35 -04:00