Skip to content

Commit 721f30d

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 81ce2dc commit 721f30d

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
@@ -794,6 +794,17 @@ BUILTIN_MISC_OPERATION(StartAsyncLet, "startAsyncLet", "", Special)
794794
/// until the endAsyncLet.
795795
BUILTIN_MISC_OPERATION_WITH_SILGEN(EndAsyncLet, "endAsyncLet", "", Special)
796796

797+
/// createAsyncTask(): (
798+
/// Int, // task-creation flags
799+
/// Builtin.RawPointer?, // options (TaskOptionRecord*)
800+
/// @escaping () async throws -> T // function
801+
/// ) -> Builtin.NativeObject
802+
///
803+
/// Create a new asynchronous task, given flags, options, and a function to
804+
/// execute.
805+
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTask,
806+
"createAsyncTask", "", Special)
807+
797808
/// createAsyncTaskFuture(): (
798809
/// Int, // flags
799810
/// 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
@@ -2743,8 +2743,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
27432743
case BuiltinValueKind::CancelAsyncTask:
27442744
return getCancelAsyncTask(Context, Id);
27452745

2746+
case BuiltinValueKind::CreateAsyncTask:
27462747
case BuiltinValueKind::CreateAsyncTaskFuture:
2747-
return getCreateAsyncTaskFuture(Context, Id);
2748+
return getCreateAsyncTask(Context, Id);
27482749

27492750
case BuiltinValueKind::CreateAsyncTaskGroupFuture:
27502751
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
@@ -3858,6 +3858,7 @@ void irgen::emitTaskCancel(IRGenFunction &IGF, llvm::Value *task) {
38583858

38593859
llvm::Value *irgen::emitTaskCreate(
38603860
IRGenFunction &IGF,
3861+
bool isCreateAsyncTask,
38613862
llvm::Value *flags,
38623863
llvm::Value *taskGroup,
38633864
llvm::Value *taskOptions,
@@ -3880,7 +3881,8 @@ llvm::Value *irgen::emitTaskCreate(
38803881
taskFunction, localContextInfo});
38813882
} else if (futureResultType) {
38823883
result = IGF.Builder.CreateCall(
3883-
IGF.IGM.getTaskCreateFutureFn(),
3884+
isCreateAsyncTask ? IGF.IGM.getTaskCreateFn()
3885+
: IGF.IGM.getTaskCreateFutureFn(),
38843886
{flags,
38853887
taskOptions,
38863888
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
@@ -756,13 +756,27 @@ BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, UnsafeGuaranteed)
756756
const int PARAMETER_INDEX_CREATE_ASYNC_TASK_FUTURE_FUNCTION = 3;
757757
const int PARAMETER_INDEX_CREATE_ASYNC_TASK_GROUP_FUTURE_FUNCTION = 4;
758758

759+
OperandOwnership
760+
OperandOwnershipBuiltinClassifier::visitCreateAsyncTask(BuiltinInst *bi,
761+
StringRef attr) {
762+
// The function operand is consumed by the new task.
763+
if (&op == &bi->getOperandRef(PARAMETER_INDEX_CREATE_ASYNC_TASK_FUTURE_FUNCTION))
764+
return OperandOwnership::DestroyingConsume;
765+
766+
// FIXME: These are considered InteriorPointer because they may propagate a
767+
// pointer into a borrowed values. If they do not propagate an interior pointer,
768+
// then they should be InstantaneousUse instead and should not require a
769+
// guaranteed value.
770+
return OperandOwnership::InteriorPointer;
771+
}
772+
759773
OperandOwnership
760774
OperandOwnershipBuiltinClassifier::visitCreateAsyncTaskFuture(BuiltinInst *bi,
761775
StringRef attr) {
762776
// The function operand is consumed by the new task.
763777
if (&op == &bi->getOperandRef(PARAMETER_INDEX_CREATE_ASYNC_TASK_FUTURE_FUNCTION))
764778
return OperandOwnership::DestroyingConsume;
765-
779+
766780
// FIXME: These are considered InteriorPointer because they may propagate a
767781
// pointer into a borrowed values. If they do not propagate an interior pointer,
768782
// 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
@@ -1852,6 +1852,7 @@ static void visitBuiltinAddress(BuiltinInst *builtin,
18521852
case BuiltinValueKind::IntInstrprofIncrement:
18531853
case BuiltinValueKind::TSanInoutAccess:
18541854
case BuiltinValueKind::CancelAsyncTask:
1855+
case BuiltinValueKind::CreateAsyncTask:
18551856
case BuiltinValueKind::CreateAsyncTaskFuture:
18561857
case BuiltinValueKind::CreateAsyncTaskGroupFuture:
18571858
case BuiltinValueKind::AutoDiffCreateLinearMapContext:

0 commit comments

Comments
 (0)