Skip to content

Commit c7edfa3

Browse files
committed
Centralize non-group task creation on swift_task_create[_f].
Introduce a builtin `createAsyncTask` that maps to `swift_task_create`, and use that for the non-group task creation operations based on the task-creation flags. `swift_task_create` and the thin function version `swift_task_create_f` go through the dynamically-replaceable `swift_task_create_common`, where all of the task creation logic is present. While here, move copying of task locals and the initial scheduling of the task into `swift_task_create_common`, enabling by separate flags.
1 parent 3727db2 commit c7edfa3

File tree

19 files changed

+253
-163
lines changed

19 files changed

+253
-163
lines changed

include/swift/AST/Builtins.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,17 @@ BUILTIN_MISC_OPERATION(StartAsyncLet, "startAsyncLet", "", Special)
805805
/// until the endAsyncLet.
806806
BUILTIN_MISC_OPERATION_WITH_SILGEN(EndAsyncLet, "endAsyncLet", "", Special)
807807

808+
/// createAsyncTask(): (
809+
/// Int, // task-creation flags
810+
/// Builtin.RawPointer?, // options (TaskOptionRecord*)
811+
/// @escaping () async throws -> T // function
812+
/// ) -> Builtin.NativeObject
813+
///
814+
/// Create a new asynchronous task, given flags, options, and a function to
815+
/// execute.
816+
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTask,
817+
"createAsyncTask", "", Special)
818+
808819
/// createAsyncTaskFuture(): (
809820
/// Int, // flags
810821
/// Builtin.RawPointer?, // options (TaskOptionRecord*)

include/swift/Runtime/Concurrency.h

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,33 +36,44 @@ struct AsyncTaskAndContext {
3636
AsyncContext *InitialContext;
3737
};
3838

39-
/// Create a task object with no future which will run the given function.
39+
/// Create a task object.
40+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
41+
AsyncTaskAndContext swift_task_create(
42+
size_t taskCreateFlags,
43+
TaskOptionRecord *options,
44+
const Metadata *futureResultType,
45+
void *closureEntry, HeapObject *closureContext);
46+
47+
/// Create a task object that will run the given function.
4048
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
4149
AsyncTaskAndContext swift_task_create_f(
4250
size_t flags,
4351
TaskOptionRecord *options,
44-
ThinNullaryAsyncSignature::FunctionType *function, size_t initialContextSize);
52+
const Metadata *futureResultType,
53+
ThinNullaryAsyncSignature::FunctionType *function,
54+
size_t initialContextSize);
4555

4656
/// Caution: not all future-initializing functions actually throw, so
4757
/// this signature may be incorrect.
4858
using FutureAsyncSignature =
4959
AsyncSignature<void(void*), /*throws*/ true>;
5060

51-
/// Create a task object with a future which will run the given closure.
61+
/// Create a task object.
5262
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
53-
AsyncTaskAndContext swift_task_create_future(
54-
size_t flags,
63+
AsyncTaskAndContext swift_task_create_common(
64+
size_t taskCreateFlags,
5565
TaskOptionRecord *options,
5666
const Metadata *futureResultType,
57-
void *closureEntryPoint, HeapObject * /* +1 */ closureContext);
67+
FutureAsyncSignature::FunctionType *function, void *closureContext,
68+
size_t initialContextSize);
5869

59-
/// Create a task object with a future which will run the given function.
70+
/// Create a task object with a future which will run the given closure.
6071
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
61-
AsyncTaskAndContext swift_task_create_future_f(
72+
AsyncTaskAndContext swift_task_create_future(
6273
size_t flags,
6374
TaskOptionRecord *options,
6475
const Metadata *futureResultType,
65-
FutureAsyncSignature::FunctionType *function, size_t initialContextSize);
76+
void *closureEntryPoint, HeapObject * /* +1 */ closureContext);
6677

6778
/// Create a task object with a future which will run the given
6879
/// closure, and offer its result to the task group
@@ -74,25 +85,6 @@ AsyncTaskAndContext swift_task_create_group_future(
7485
const Metadata *futureResultType,
7586
void *closureEntryPoint, HeapObject * /* +1 */ closureContext);
7687

77-
/// Create a task object with a future which will run the given
78-
/// function, and offer its result to the task group
79-
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
80-
AsyncTaskAndContext swift_task_create_group_future_f(
81-
size_t flags,
82-
TaskGroup *group,
83-
TaskOptionRecord *options,
84-
const Metadata *futureResultType,
85-
FutureAsyncSignature::FunctionType *function, size_t initialContextSize);
86-
87-
/// Create a task object.
88-
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
89-
AsyncTaskAndContext swift_task_create(
90-
size_t taskCreateFlags,
91-
TaskOptionRecord *options,
92-
const Metadata *futureResultType,
93-
FutureAsyncSignature::FunctionType *function, void *closureContext,
94-
size_t initialContextSize);
95-
9688
/// Allocate memory in a task.
9789
///
9890
/// This must be called synchronously with the task.

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,8 +1585,7 @@ FUNCTION(TaskCreateGroupFuture,
15851585
// size_t taskCreateFlags,
15861586
// TaskOptionRecord *options,
15871587
// const Metadata *futureResultType,
1588-
// void *closureEntry, HeapObject *closureContext,
1589-
// size_t initialContextSize);
1588+
// void *closureEntry, HeapObject *closureContext);
15901589
FUNCTION(TaskCreate,
15911590
swift_task_create, SwiftCC,
15921591
ConcurrencyAvailability,
@@ -1595,8 +1594,7 @@ FUNCTION(TaskCreate,
15951594
SwiftTaskOptionRecordPtrTy,
15961595
TypeMetadataPtrTy,
15971596
Int8PtrTy,
1598-
RefCountedPtrTy,
1599-
SizeTy),
1597+
RefCountedPtrTy),
16001598
ATTRS(NoUnwind, ArgMemOnly))
16011599

16021600
// void swift_task_switch(AsyncContext *resumeContext,

lib/AST/Builtins.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,7 +1424,7 @@ Type swift::getAsyncTaskAndContextType(ASTContext &ctx) {
14241424
return TupleType::get(resultTupleElements, ctx);
14251425
}
14261426

1427-
static ValueDecl *getCreateAsyncTaskFuture(ASTContext &ctx, Identifier id) {
1427+
static ValueDecl *getCreateAsyncTask(ASTContext &ctx, Identifier id) {
14281428
BuiltinFunctionBuilder builder(ctx);
14291429
auto genericParam = makeGenericParam().build(builder);
14301430
builder.addParameter(makeConcrete(ctx.getIntType())); // 0 flags
@@ -2761,8 +2761,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
27612761
case BuiltinValueKind::CancelAsyncTask:
27622762
return getCancelAsyncTask(Context, Id);
27632763

2764+
case BuiltinValueKind::CreateAsyncTask:
27642765
case BuiltinValueKind::CreateAsyncTaskFuture:
2765-
return getCreateAsyncTaskFuture(Context, Id);
2766+
return getCreateAsyncTask(Context, Id);
27662767

27672768
case BuiltinValueKind::CreateAsyncTaskGroupFuture:
27682769
return getCreateAsyncTaskGroupFuture(Context, Id);

lib/IRGen/GenBuiltin.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
270270
return;
271271
}
272272

273-
if (Builtin.ID == BuiltinValueKind::CreateAsyncTaskFuture ||
273+
if (Builtin.ID == BuiltinValueKind::CreateAsyncTask ||
274+
Builtin.ID == BuiltinValueKind::CreateAsyncTaskFuture ||
274275
Builtin.ID == BuiltinValueKind::CreateAsyncTaskGroupFuture) {
275276

276277
auto flags = args.claimNext();
@@ -285,6 +286,7 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
285286

286287
auto newTaskAndContext = emitTaskCreate(
287288
IGF,
289+
Builtin.ID == BuiltinValueKind::CreateAsyncTask,
288290
flags,
289291
taskGroup,
290292
taskOptions,

lib/IRGen/GenCall.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3859,6 +3859,7 @@ void irgen::emitTaskCancel(IRGenFunction &IGF, llvm::Value *task) {
38593859

38603860
llvm::Value *irgen::emitTaskCreate(
38613861
IRGenFunction &IGF,
3862+
bool isCreateAsyncTask,
38623863
llvm::Value *flags,
38633864
llvm::Value *taskGroup,
38643865
llvm::Value *taskOptions,
@@ -3881,7 +3882,8 @@ llvm::Value *irgen::emitTaskCreate(
38813882
taskFunction, localContextInfo});
38823883
} else if (futureResultType) {
38833884
result = IGF.Builder.CreateCall(
3884-
IGF.IGM.getTaskCreateFutureFn(),
3885+
isCreateAsyncTask ? IGF.IGM.getTaskCreateFn()
3886+
: IGF.IGM.getTaskCreateFutureFn(),
38853887
{flags,
38863888
taskOptions,
38873889
futureResultType,

lib/IRGen/GenCall.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ namespace irgen {
230230
/// When \c futureResultType is non-null, calls the future variant to create
231231
/// a future.
232232
llvm::Value *emitTaskCreate(
233-
IRGenFunction &IGF, llvm::Value *flags,
233+
IRGenFunction &IGF,
234+
bool isCreateAsyncTask,
235+
llvm::Value *flags,
234236
llvm::Value *taskGroup,
235237
llvm::Value *taskOptions,
236238
llvm::Value *futureResultType,

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,13 +768,27 @@ BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, UnsafeGuaranteed)
768768
const int PARAMETER_INDEX_CREATE_ASYNC_TASK_FUTURE_FUNCTION = 3;
769769
const int PARAMETER_INDEX_CREATE_ASYNC_TASK_GROUP_FUTURE_FUNCTION = 4;
770770

771+
OperandOwnership
772+
OperandOwnershipBuiltinClassifier::visitCreateAsyncTask(BuiltinInst *bi,
773+
StringRef attr) {
774+
// The function operand is consumed by the new task.
775+
if (&op == &bi->getOperandRef(PARAMETER_INDEX_CREATE_ASYNC_TASK_FUTURE_FUNCTION))
776+
return OperandOwnership::DestroyingConsume;
777+
778+
// FIXME: These are considered InteriorPointer because they may propagate a
779+
// pointer into a borrowed values. If they do not propagate an interior pointer,
780+
// then they should be InstantaneousUse instead and should not require a
781+
// guaranteed value.
782+
return OperandOwnership::InteriorPointer;
783+
}
784+
771785
OperandOwnership
772786
OperandOwnershipBuiltinClassifier::visitCreateAsyncTaskFuture(BuiltinInst *bi,
773787
StringRef attr) {
774788
// The function operand is consumed by the new task.
775789
if (&op == &bi->getOperandRef(PARAMETER_INDEX_CREATE_ASYNC_TASK_FUTURE_FUNCTION))
776790
return OperandOwnership::DestroyingConsume;
777-
791+
778792
// FIXME: These are considered InteriorPointer because they may propagate a
779793
// pointer into a borrowed values. If they do not propagate an interior pointer,
780794
// then they should be InstantaneousUse instead and should not require a

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, IntInstrprofIncrement)
532532
CONSTANT_OWNERSHIP_BUILTIN(None, GlobalStringTablePointer)
533533
CONSTANT_OWNERSHIP_BUILTIN(None, GetCurrentAsyncTask)
534534
CONSTANT_OWNERSHIP_BUILTIN(None, CancelAsyncTask)
535+
CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTask)
535536
CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTaskFuture)
536537
CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTaskGroupFuture)
537538
CONSTANT_OWNERSHIP_BUILTIN(None, ConvertTaskToJob)

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,6 +1854,7 @@ static void visitBuiltinAddress(BuiltinInst *builtin,
18541854
case BuiltinValueKind::IntInstrprofIncrement:
18551855
case BuiltinValueKind::TSanInoutAccess:
18561856
case BuiltinValueKind::CancelAsyncTask:
1857+
case BuiltinValueKind::CreateAsyncTask:
18571858
case BuiltinValueKind::CreateAsyncTaskFuture:
18581859
case BuiltinValueKind::CreateAsyncTaskGroupFuture:
18591860
case BuiltinValueKind::AutoDiffCreateLinearMapContext:

0 commit comments

Comments
 (0)