Commit Graph

59 Commits

Author SHA1 Message Date
Michael Gottesman
97b0e2ebae [concurrency] Create builtins for invoking specific concurrency runtime functions.
Specifically:

1. swift_task_addCancellationHandler
2. swift_task_removeCancellationHandler
3. swift_task_addPriorityEscalationHandler
4. swift_task_removePriorityEscalationHandler
5. swift_task_localValuePush
6. swift_task_localValuePop

rdar://109850951
2025-11-05 11:03:44 -08:00
John McCall
a7d7970e29 Turn finishAsyncLet into a builtin.
This is necessary because we need to model its stack-allocation
behavior, although I'm not yet doing that in this patch because
StackNesting first needs to be taught to not try to move the
deallocation.

I'm not convinced that `async let` *should* be doing a stack allocation,
but it undoubtedly *is* doing a stack allocation, and until we have an
alternative to that, we will need to model it properly.
2025-11-03 16:33:40 -08:00
John McCall
3cfda35b7c Remove the unused swift_asyncLet_{start,end,wait,wait_throwing} runtime
functions.

These were introduced in an early draft implementation of async let, but
never used by a released compiler. They are not used as symbols by any
app binaries. There's no reason to keep carrying them.

While I'm at it, dramatically improve the documentation of the remaining
async let API functions.
2025-11-03 13:45:18 -08:00
John McCall
cd67912a50 Remove the deprecated and unused endAsyncLet builtin. 2025-11-03 13:45:18 -08:00
Michael Gottesman
fe9c21fd87 [sil] Add a new instruction cast_implicit_actor_to_optional_actor.
This instruction converts Builtin.ImplicitActor to Optional<any Actor>. In the
process of doing so, it masks out the bits we may have stolen from the witness
table pointer of Builtin.ImplicitActor. The bits that we mask out are the bottom
two bits of the top nibble of the TBI space on platforms that support TBI (that
is bit 60,61 on arm64). On platforms that do not support TBI, we just use the
bottom two tagged pointer bits (0,1).

By using an instruction, we avoid having to represent the bitmasking that we are
performing at the SIL level and can instead just make the emission of the
bitmasking an IRGen detail. It also allows us to move detection if we are
compiling for AArch64 to be an IRGen flag instead of a LangOpts flag.

The instruction is a guaranteed forwarding instruction since we want to treat
its result as a borrowed projection from the Builtin.ImplicitActor.
2025-10-16 10:52:04 -07:00
Michael Gottesman
2fa3908e94 [concurrency] Add a new type Builtin.ImplicitActor.
This is currently not wired up to anything. I am going to wire it up in
subsequent commits.

The reason why we are introducing this new Builtin type is to represent that we
are going to start stealing bits from the protocol witness table pointer of the
Optional<any Actor> that this type is bitwise compatible with. The type will
ensure that this value is only used in places where we know that it will be
properly masked out giving us certainty that this value will not be used in any
manner without it first being bit cleared and transformed back to Optional<any
Actor>.
2025-10-16 10:51:13 -07:00
John McCall
fb9a1e301b Fix IRGen to pass complete metadata to various concurrency builtins
Fixes rdar://146155888
2025-09-11 18:27:39 -04:00
Konrad `ktoso` Malawski
fda7f539fb Reapply "Task names" (#79562) (#79600) 2025-03-08 10:58:49 +09:00
Konrad `ktoso` Malawski
09003d6f11 Revert "Merge pull request #77609 from ktoso/wip-task-names" (#79562)
This reverts commit 4ab5d2604f.
2025-02-23 22:59:21 -08:00
Konrad `ktoso` Malawski
4ab5d2604f Merge pull request #77609 from ktoso/wip-task-names
[Concurrency] Task names
2025-02-21 22:28:33 +09:00
Kuba Mracek
cf7ea301e1 [Concurrency] Fix arm64e ptrauth violations in Embedded Swift Concurrency 2024-10-28 21:16:48 -07:00
swift-ci
433a6d8469 Merge remote-tracking branch 'origin/main' into rebranch 2024-10-03 19:47:13 -07:00
Kuba Mracek
a2dcb6045c [embedded] Introduce a new swift_taskGroup_initializeWithOptions runtime entrypoint 2024-10-01 14:56:38 -07:00
Kuba Mracek
f1c2334c9a [Concurrency] Enable TaskGroup/DiscardingTaskGroup in Embedded Swift 2024-09-28 17:52:05 -07:00
Ben Barham
a7b50f357f Merge remote-tracking branch 'origin/main' into manual-main-merge
Conflicts:
  - `lib/Driver/ToolChains.cpp` conflicting with the `addAllArgs` rename
    for multiple options
2024-09-16 13:53:18 -07:00
Allan Shortlidge
02dbb96b94 AST: Rename AvailabilityContext to AvailabilityRange.
The generality of the `AvailabilityContext` name made it seem like it
encapsulates more than it does. Really it just augments `VersionRange` with
additional set algebra operations that are useful for availability
computations. The `AvailabilityContext` name should be reserved for something
pulls together more than just a single version.
2024-09-13 16:25:18 -07:00
swift-ci
6e7b0a9f52 Merge remote-tracking branch 'origin/main' into rebranch 2024-08-26 11:34:27 -07:00
Arnold Schwaighofer
ad6f6dec6e IRGen: We cannot call destroy through metadata of private types of non-copyable fields
So call the destroy on the closing type instead.

Amends the concepts areFieldsABIAccessible/isABIAccessible to take metadata
accessibility of non-copyable types into account.

rdar://133990500
2024-08-21 11:22:30 -07:00
Ben Barham
5b4cd16647 [rebranch] Add missing llvm/IR/Module.h include
`llvm/IR/Module.h` was presumably being transitively included
previously.
2024-07-31 08:54:35 -07:00
Tim Kientzle
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Konrad `ktoso` Malawski
2ec717b115 [Concurrency] TaskExecutor ownership fixes (#74000) 2024-06-14 22:56:33 +09:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
John McCall
d8767b7724 Pass the task option record pointer to swift_task_create as a pointer.
We add the `memory(argmem: readwrite)` attribute to swift_task_create,
which means that the call is only allowed to read or write "pointer
operands".  LLVM is smart enough to look through obvious ptrtoint
casts, but not to look through integer selects and so on, which is what
we produce when there's an opaque optional operand that feeds into the
builtin.  This was causing miscompiles under optimization when using
`@isolated(any)` function types for task creation, since we're not yet
clever enough to fold the function_extract_isolation for a known function
(and of course it's not necessarily a known function anyway).
2024-03-15 00:40:54 -04:00
John McCall
0901b2b0b3 Add builtin support for starting a task on a specific executor.
This should be close enough to the creation of this builtin that we don't
need a new feature for it specifically.
2024-03-11 19:44:50 -04:00
John McCall
0a282c044f Unify all of the task-creation builtins coming out of SILGen.
We've been building up this exponential explosion of task-creation
builtins because it's not currently possible to overload builtins.
As long as all of the operands are scalar, though, it's pretty easy
to peephole optional injections in IRGen, which means we can at
least just use a single builtin in SIL and then break it apart in
IRGen to decide which options to set.

I also eliminated the metadata argument, which can easily be recreated
from the substitutions.  I also added proper verification for the builtin,
which required (1) getting `@Sendable` right more consistently and (2)
updating a bunch of tests checking for things that are not actually
valid, like passing a function that returns an Int directly.
2024-03-06 22:21:12 -05:00
Konrad `ktoso` Malawski
828f589be4 Initial Task Executor implementation Task(on:), addTask(on:) etc. (#68793)
Co-authored-by: John McCall <rjmccall@gmail.com>
2023-12-12 17:14:24 +09:00
Konrad `ktoso` Malawski
c29bffd2be remove buildOrdinaryTaskExecutorRef until we need it 2023-11-02 15:50:43 +09:00
Konrad `ktoso` Malawski
5546f4da7b Rename ExecutorRef to SerialExecutorRef 2023-11-01 18:39:44 +09:00
Konrad `ktoso` Malawski
9e75142911 Task Executors: Prepare for new TaskExecutor protocol & builtins 2023-11-01 16:02:39 +09:00
Kuba Mracek
90e1d2006f [embedded] Add support for actors and async let into the embedded Concurrency runtime 2023-10-09 22:43:50 -07:00
Konrad `ktoso` Malawski
0586c14b60 [Concurrency] SerialExecutor.isSameExclusiveExecutionContext (#64604) 2023-03-28 15:56:28 +09:00
Joe Groff
03a2393a6c IRGen: Track IsCopyable through type infos.
And use the new bit to ensure we don't try to lower move-only types
with common layout value witness surrogates. Take a bit in the runtime
value witness flags to represent types that are not copyable.
2023-02-27 18:52:50 -08:00
Joe Groff
a572c3f491 IRGen: Rename internal 'POD' references to 'TriviallyDestroyable'.
Noncopyable types aren't really "POD", but the bit is still useful to track
whether a noncopyable type has a no-op destroy operation, so rename the
existing bit to be more specific within IRGen's implementation.

Don't rename it in the runtime or Builtin names yet, since doing so will
require a naming transition for compatibility.
2023-02-27 18:52:10 -08:00
Dario Rexin
a8d4d57f11 [IRGen] Generate compressed representation of value witnesses (#63813)
rdar://105837040

* WIP: Store layout string in type metadata

* WIP: More cases working

* WIP: Layout strings almost working

* Add layout string pointer to struct metadata

* Fetch bytecode layout strings from metadata in runtime

* More efficient bytecode layout

* Add support for interpreted generics in layout strings

* Layout string instantiation, take and more

* Remove duplicate information from layout strings

* Include size of previous object in next objects offset to reduce number of increments at runtime

* Add support for existentials

* Build type layout strings with StructBuilder to support target sizes and metadata pointers

* Add support for resilient types

* Properly cache layout strings in compiler

* Generic resilient types working

* Non-generic resilient types working

* Instantiate resilient type in layout when possible

* Fix a few issues around alignment and signing

* Disable generics, fix static alignment

* Fix MultiPayloadEnum size when no extra tag is necessary

* Fixes after rebase

* Cleanup

* Fix most tests

* Fix objcImplementattion and non-Darwin builds

* Fix BytecodeLayouts on non-Darwin

* Fix Linux build

* Fix sizes in linux tests

* Sign layout string pointers

* Use nullptr instead of debug value
2023-02-24 15:40:28 -08:00
Saleem Abdulrasool
b34db5d19e IRGen: order properties on SwiftAsyncCC to be uniform
Adjust the IRGen to always set the calling convention and then the
noexcept bit.  This makes it easier to quickly scan through the
attributes for the async calls which was useful for some Concurrency
related work on Windows.
2023-02-14 08:22:02 -08:00
Konrad `ktoso` Malawski
f8b85015c1 prepare flags
wip on options

implement discardResults as a flag passed to grout init
2023-01-05 16:19:05 +09:00
Dario Rexin
3cf40ea504 [IRGen] Re-introduce TypeLayout strings (#62059)
* Introduce TypeLayout Strings

Layout strings encode the structure of a type into a byte string that can be
interpreted by a runtime function to achieve a destroy or copy. Rather than
generating ir for a destroy/assignWithCopy/etc, we instead generate a layout
string which encodes enough information for a called runtime function to
perform the operation for us. Value witness functions tend to be quite large,
so this allows us to replace them with a single call instead. This gives us the
option of making a codesize/runtime cost trade off.

* Added Attribute @_GenerateLayoutBytecode

This marks a type definition that should use generic bytecode based
value witnesses rather than generating the standard suite of
value witness functions. This should reduce the codesize of the binary
for a runtime interpretation of the bytecode cost.

* Statically link in implementation

Summary:
This creates a library to store the runtime functions in to deploy to
runtimes that do not implement bytecode layouts. Right now, that is
everything. Once these are added to the runtime itself, it can be used
to deploy to old runtimes.

* Implement Destroy at Runtime Using LayoutStrings

If GenerateLayoutBytecode is enabled, Create a layout string and use it
to call swift_generic_destroy

* Add Resilient type and Archetype Support for BytecodeLayouts

Add Resilient type and Archetype Support to Bytecode Layouts

* Implement Bytecode assign/init with copy/take

Implements swift_generic_initialize and swift_generic_assign to allow copying
types using bytecode based witnesses.

* Add EnumTag Support

* Add IRGen Bytecode Layouts Test

Added a test to ensure layouts are correct and getting generated

* Implement BytecodeLayouts ObjC retain/release

* Fix for Non static alignments in aligned groups

* Disable MultiEnums

MultiEnums currently have some correctness issues with non fixed multienum
types. Disabling them for now then going to attempt a correct implementation in
a follow up patch

* Fixes after merge

* More fixes

* Possible fix for native unowned

* Use TypeInfoeBasedTypeLayoutEntry for all scalars when ForceStructTypeLayouts is disabled

* Remove @_GenerateBytecodeLayout attribute

* Fix typelayout_based_value_witness.swift

Co-authored-by: Gwen Mittertreiner <gwenm@fb.com>
Co-authored-by: Gwen Mittertreiner <gwen.mittertreiner@gmail.com>
2022-11-29 21:05:22 -08:00
Arnold Schwaighofer
d810b0f7e4 IRGen: Pass the elementType of pointers through to operations
In preparation for moving to llvm's opaque pointer representation
replace getPointerElementType and CreateCall/CreateLoad/Store uses that
dependent on the address operand's pointer element type.

This means an `Address` carries the element type and we use
`FunctionPointer` in more places or read the function type off the
`llvm::Function`.
2022-10-03 15:27:12 -07:00
Nate Chandler
34c08b8344 [TaskToThread] Add Task.runInline.
The new intrinsic, exposed via static functions on Task<T, Never> and
Task<T, Error> (rethrowing), begins an asynchronous context within a
synchronous caller's context.  This is only available for use under the
task-to-thread concurrency model, and even then only under SPI.
2022-07-08 08:44:18 -07:00
Joe Groff
d451203b7f SILGen: Emit async let entry points at correct abstraction level.
Avoid a reabstraction thunk every time an async let entry point is emitted,
by setting the context abstraction level while we emit the implicit closure.
Adjust some surrounding logic that breaks when we do this:

- When lowering a non-throwing function type against a throwing abstraction
  pattern, include the error type in the lowered substituted type. Async
  throwing and nonthrowing functions would require another thunk to convert
  away the throwingness of the async context, which would defeat the purpose.
- Adjust the code in IRGen that pads the initial context size for `async let`
  entry points so that it works when the entry point has not yet emitted, by
  marking the async function pointer to be padded later if it isn't defined
  yet.
2022-03-30 14:51:46 -07:00
Joe Groff
6f68eae7ba IRGen: Artificially pad async let entry point contexts.
We fixed a bug in the concurrency runtime (rdar://problem/90357994) that would
lead to memory corruption when a new `async let` child task tried to use the
last 16 bytes of the preallocated slab from its parent to seed its own task
allocator. To work around this bug in older OSes that shipped with the bug,
artificially pad the async coroutine context size for any async functions
used as an `async let` entry point, which will prevent the runtime from
going down the path of trying to use the preallocated storage at all.
rdar://90506708
2022-03-25 16:06:00 -07:00
Arnold Schwaighofer
5c9de9e656 Revert "Merge pull request #40356 from gmittert/TypeLayoutFixes"
This reverts commit d27e6e1e46, reversing
changes made to f2e85a2b1f.

It causes an execution time failure in
`Interpreter/struct_extra_inhabitants.swift` with

```
ninja -C swift-macosx-x86_64 check-swift-optimize
```

rdar://86054209
2021-12-06 07:49:57 -08:00
Gwen Mittertreiner
13bb43b72e Revert "Revert "Merge pull request #37116 from gmittert/Descaling""
This reverts commit 7c7dd666c6.
2021-11-30 16:19:34 -08:00
Arnold Schwaighofer
7c7dd666c6 Revert "Merge pull request #37116 from gmittert/Descaling"
This reverts commit 5ebb1b2fc6, reversing
changes made to 76260c2235.

This commit causes compiler crashes when using protocol composition
types involving objc.

Repo:

```
import Foundation

public class SomeObject : NSObject {}

public protocol ProtoA{}

public protocol SomeProtoType { }
public typealias Composition = SomeObject & SomeProtoType

public struct Thing<T: ProtoA> {
    let a: Composition
    let b: T

    init(a: Composition,
         b: T
    ) {
        self.a = a
        self.b = b
    }
}

$ swiftc -c Repo.swift -O
```

While looking at this issue I noticed that it is not correct to use a
ScalarEntry of ObjCReference (or other ScalarKind::XXXReference) for
`AddressOnly##Name##ClassExistentialTypeInfo` types. These should be
calling the IGF.emit##Name##Destroy(addr, Refcounting); functions not
objc_release.
It is probably best to use the macro facilities in a similar fashion like
lib/IRGen/GenExistential.cpp does.

rdar://85269025
2021-11-11 11:44:09 -08:00
Gwen Mittertreiner
a3ceda653f Teach TypeLayout the Different Types of References
Summary:
As part of SR-14273, the type layout infrastructure needs to be able to be able
to differentiate between types of scalars so it knows how to release/retain
appropriately. Right now, for example, to destroy a scalar, it blindly calls
into typeInfo's irgen functions which means it's not able to generate any of
the needed information for itself.

This patch adds a field to ScalarTypeLayout to allow them to know what kind of
reference they are and strings through the machinery to provide the information
to set it.

This also moves ScalarTypeLayout::destroy to use the new information.

Test Plan: ninja check-swift

Reviewers: mren, #pika_compiler

Reviewed By: mren

Subscribers: apl, phabricatorlinter

Differential Revision: https://phabricator.intern.facebook.com/D30983093

Tasks: T100580959

Tags: swift-adoption

Signature: 30983093:1632340205:3bdd3218ae86ad6b3d199cc1b504a625e3650ec0
2021-09-29 10:40:55 -07:00
Joe Groff
fc67ba57f2 Merge pull request #37938 from jckarter/async-let-multi-suspend
Handle multiple awaits and suspend-on-exit for async let tasks.
2021-07-23 07:36:54 -07:00
Joe Groff
439edbce1f Handle multiple awaits and suspend-on-exit for async let tasks.
Change the code generation patterns for `async let` bindings to use an ABI based on the following
functions:

- `swift_asyncLet_begin`, which starts an `async let` child task, but which additionally
  now associates the `async let` with a caller-owned buffer to receive the result of the task.
  This is intended to allow the task to emplace its result in caller-owned memory, allowing the
  child task to be deallocated after completion without invalidating the result buffer.
- `swift_asyncLet_get[_throwing]`, which replaces `swift_asyncLet_wait[_throwing]`. Instead of
  returning a copy of the value, this entry point concerns itself with populating the local buffer.
  If the buffer hasn't been populated, then it awaits completion of the task and emplaces the
  result in the buffer; otherwise, it simply returns. The caller can then read the result out of
  its owned memory. These entry points are intended to be used before every read from the
  `async let` binding, after which point the local buffer is guaranteed to contain an initialized
  value.
- `swift_asyncLet_finish`, which replaces `swift_asyncLet_end`. Unlike `_end`, this variant
  is async and will suspend the parent task after cancelling the child to ensure it finishes
  before cleaning up. The local buffer will also be deinitialized if necessary. This is intended
  to be used on exit from an `async let` scope, to handle cleaning up the local buffer if necessary
  as well as cancelling, awaiting, and deallocating the child task.
- `swift_asyncLet_consume[_throwing]`, which combines `get` and `finish`. This will await completion
  of the task, leaving the result value in the result buffer (or propagating the error, if it
  throws), while destroying and deallocating the child task. This is intended as an optimization
  for reading `async let` variables that are read exactly once by their parent task.

To avoid an epoch break with existing swiftinterfaces and ABI clients, the old builtins and entry
points are kept intact for now, but SILGen now only generates code using the new interface.

This new interface fixes several issues with the old async let codegen, including use-after-free
crashes if the `async let` was never awaited, and the inability to read from an `async let` variable
more than once.

rdar://77855176
2021-07-22 10:19:31 -07:00
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
Alejandro Alonso
e73af2b6b3 Remove a dump statement from IRGen 2021-06-22 15:54:08 -04:00
Konrad `ktoso` Malawski
8536100354 [Concurrency] introduce task options, and change ABI to accept them
introduce new options parameter to all task spawning

[Concurrency] ABI for asynclet start to accept options

[Concurrency] fix unittest usages of changed task creation ABI

[Concurrency] introduce constants for parameter indexes in ownership

[Concurrency] fix test/SILOptimizer/closure_lifetime_fixup_concurrency.swift
2021-06-21 13:03:50 +09:00