Skip to content

Commit fa54ff8

Browse files
committed
IRGen: Fix lowering of Builtin.createAsyncTask and Builtin.createAsyncTaskFuture
Thick async functions store their async context size in the closure context. Only if the closure context is nil can we assume the partial_apply_forwarder function to be the address of an async function pointer struct value.
1 parent cd8029a commit fa54ff8

File tree

3 files changed

+31
-25
lines changed

3 files changed

+31
-25
lines changed

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,23 +1498,24 @@ FUNCTION(TaskCancel,
14981498
ATTRS(NoUnwind, ArgMemOnly))
14991499

15001500
// AsyncTaskAndContext swift_task_create(
1501-
// size_t flags, AsyncTask *task, AsyncFunctionPointer *function);
1501+
// size_t flags, AsyncTask *task, TaskContinuationFunction* function,
1502+
// size_t contextSize);
15021503
FUNCTION(TaskCreateFunc,
1503-
swift_task_create, SwiftCC,
1504+
swift_task_create_f, SwiftCC,
15041505
ConcurrencyAvailability,
15051506
RETURNS(AsyncTaskAndContextTy),
1506-
ARGS(SizeTy, SwiftTaskPtrTy, AsyncFunctionPointerPtrTy),
1507+
ARGS(SizeTy, SwiftTaskPtrTy, TaskContinuationFunctionPtrTy, SizeTy),
15071508
ATTRS(NoUnwind, ArgMemOnly))
15081509

1509-
// AsyncTaskAndContext swift_task_create_future(
1510+
// AsyncTaskAndContext swift_task_create_future_f(
15101511
// size_t flags, AsyncTask *task, const Metadata *futureResultType,
1511-
// AsyncFunctionPointer *function);
1512+
// TaskContinuationFunction *function, size_t contextSize);
15121513
FUNCTION(TaskCreateFutureFunc,
1513-
swift_task_create_future, SwiftCC,
1514+
swift_task_create_future_f, SwiftCC,
15141515
ConcurrencyAvailability,
15151516
RETURNS(AsyncTaskAndContextTy),
15161517
ARGS(SizeTy, SwiftTaskPtrTy, TypeMetadataPtrTy,
1517-
AsyncFunctionPointerPtrTy),
1518+
TaskContinuationFunctionPtrTy, SizeTy),
15181519
ATTRS(NoUnwind, ArgMemOnly))
15191520

15201521
#undef RETURNS

lib/IRGen/GenCall.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3600,8 +3600,6 @@ llvm::Value *irgen::emitTaskCreate(
36003600
SubstitutionMap subs) {
36013601
parentTask = IGF.Builder.CreateBitOrPointerCast(
36023602
parentTask, IGF.IGM.SwiftTaskPtrTy);
3603-
taskFunction = IGF.Builder.CreateBitOrPointerCast(
3604-
taskFunction, IGF.IGM.AsyncFunctionPointerPtrTy);
36053603

36063604
// Determine the size of the async context for the closure.
36073605
ASTContext &ctx = IGF.IGM.IRGen.SIL.getASTContext();
@@ -3625,29 +3623,36 @@ llvm::Value *irgen::emitTaskCreate(
36253623

36263624
// Call the function.
36273625
llvm::CallInst *result;
3626+
llvm::Value *theSize, *theFunction;
3627+
std::tie(theFunction, theSize) =
3628+
getAsyncFunctionAndSize(IGF, SILFunctionTypeRepresentation::Thick,
3629+
FunctionPointer::forExplosionValue(
3630+
IGF, taskFunction, taskFunctionCanSILType),
3631+
localContextInfo);
3632+
theFunction = IGF.Builder.CreateBitOrPointerCast(
3633+
theFunction, IGF.IGM.TaskContinuationFunctionPtrTy);
3634+
theSize = IGF.Builder.CreateZExtOrBitCast(theSize, IGF.IGM.SizeTy);
36283635
if (futureResultType) {
36293636
result = IGF.Builder.CreateCall(
36303637
IGF.IGM.getTaskCreateFutureFuncFn(),
3631-
{ flags, parentTask, futureResultType, taskFunction });
3638+
{ flags, parentTask, futureResultType, theFunction, theSize });
36323639
} else {
3633-
result = IGF.Builder.CreateCall(
3634-
IGF.IGM.getTaskCreateFuncFn(),
3635-
{ flags, parentTask, taskFunction });
3640+
result = IGF.Builder.CreateCall(IGF.IGM.getTaskCreateFuncFn(),
3641+
{flags, parentTask, theFunction, theSize});
36363642
}
36373643
result->setDoesNotThrow();
36383644
result->setCallingConv(IGF.IGM.SwiftCC);
36393645

36403646
// Write the local context information into the initial context for the task.
3641-
if (layout.hasLocalContext()) {
3642-
// Dig out the initial context returned from task creation.
3643-
auto initialContext = IGF.Builder.CreateExtractValue(result, { 1 });
3644-
Address initialContextAddr = layout.emitCastTo(IGF, initialContext);
3645-
3646-
auto localContextLayout = layout.getLocalContextLayout();
3647-
auto localContextAddr = localContextLayout.project(
3648-
IGF, initialContextAddr, llvm::None);
3649-
IGF.Builder.CreateStore(localContextInfo, localContextAddr);
3650-
}
3647+
assert(layout.hasLocalContext());
3648+
// Dig out the initial context returned from task creation.
3649+
auto initialContext = IGF.Builder.CreateExtractValue(result, {1});
3650+
Address initialContextAddr = layout.emitCastTo(IGF, initialContext);
3651+
3652+
auto localContextLayout = layout.getLocalContextLayout();
3653+
auto localContextAddr =
3654+
localContextLayout.project(IGF, initialContextAddr, llvm::None);
3655+
IGF.Builder.CreateStore(localContextInfo, localContextAddr);
36513656

36523657
return result;
36533658
}

test/IRGen/async/builtins.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ sil hidden [ossa] @launch_task : $@convention(method) @async (Int, Optional<Buil
3434
bb0(%0 : $Int, %1: @unowned $Optional<Builtin.NativeObject>, %2: @guaranteed $@async @callee_guaranteed () -> (@error Error)):
3535
%3 = begin_borrow %1 : $Optional<Builtin.NativeObject>
3636
// CHECK: call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[FN_CONTEXT:%.*]])
37-
// CHECK: [[NEW_TASK_AND_CONTEXT:%.*]] = call swiftcc %swift.async_task_and_context @swift_task_create(
37+
// CHECK: [[NEW_TASK_AND_CONTEXT:%.*]] = call swiftcc %swift.async_task_and_context @swift_task_create_f(
3838
// CHECK-NEXT: [[NEW_CONTEXT_RAW:%.*]] = extractvalue %swift.async_task_and_context [[NEW_TASK_AND_CONTEXT]], 1
3939
// CHECK-NEXT: [[NEW_CONTEXT:%.*]] = bitcast %swift.context* [[NEW_CONTEXT_RAW]] to
4040
// CHECK-NEXT: [[CONTEXT_INFO_LOC:%.*]] = getelementptr inbounds <{{.*}}>* [[NEW_CONTEXT]]
@@ -53,7 +53,7 @@ bb0(%0 : $Int, %1: @unowned $Optional<Builtin.NativeObject>, %2: @guaranteed $@a
5353
// CHECK: call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[FN_CONTEXT:%.*]])
5454
%9 = metatype $@thick T.Type
5555
%10 = init_existential_metatype %9 : $@thick T.Type, $@thick Any.Type
56-
// CHECK: [[NEW_TASK_AND_CONTEXT:%.*]] = call swiftcc %swift.async_task_and_context @swift_task_create_future(
56+
// CHECK: [[NEW_TASK_AND_CONTEXT:%.*]] = call swiftcc %swift.async_task_and_context @swift_task_create_future_f(
5757
// CHECK-NEXT: [[NEW_CONTEXT_RAW:%.*]] = extractvalue %swift.async_task_and_context [[NEW_TASK_AND_CONTEXT]], 1
5858
// CHECK-NEXT: [[NEW_CONTEXT:%.*]] = bitcast %swift.context* [[NEW_CONTEXT_RAW]] to
5959
// CHECK-NEXT: [[CONTEXT_INFO_LOC:%.*]] = getelementptr inbounds <{{.*}}>* [[NEW_CONTEXT]]

0 commit comments

Comments
 (0)