@@ -3466,8 +3466,52 @@ void irgen::emitTaskCancel(IRGenFunction &IGF, llvm::Value *task) {
3466
3466
auto *call = IGF.Builder .CreateCall (IGF.IGM .getTaskCancelFn (), {task});
3467
3467
call->setDoesNotThrow ();
3468
3468
call->setCallingConv (IGF.IGM .SwiftCC );
3469
- call->addAttribute (llvm::AttributeList::FunctionIndex,
3470
- llvm::Attribute::ReadNone);
3469
+ }
3470
+
3471
+ llvm::Value *irgen::emitTaskCreate (
3472
+ IRGenFunction &IGF, llvm::Value *flags, llvm::Value *parentTask,
3473
+ llvm::Value *taskFunction, llvm::Value *localContextInfo) {
3474
+ parentTask = IGF.Builder .CreateBitOrPointerCast (
3475
+ parentTask, IGF.IGM .SwiftTaskPtrTy );
3476
+ taskFunction = IGF.Builder .CreateBitOrPointerCast (
3477
+ taskFunction, IGF.IGM .TaskContinuationFunctionPtrTy );
3478
+
3479
+ // Determine the size of the async context for the closure.
3480
+ // FIXME: If the task function comes in as an AsyncFunctionPointer, we might
3481
+ // want to use swift_task_create instead of swift_task_create_f.
3482
+ ASTContext &ctx = IGF.IGM .IRGen .SIL .getASTContext ();
3483
+ auto extInfo = ASTExtInfoBuilder ().withAsync ().withThrows ().build ();
3484
+ auto taskFunctionType = FunctionType::get (
3485
+ { }, ctx.TheEmptyTupleType , extInfo);
3486
+ CanSILFunctionType taskFunctionCanSILType =
3487
+ IGF.IGM .getLoweredType (taskFunctionType).castTo <SILFunctionType>();
3488
+ auto layout = getAsyncContextLayout (
3489
+ IGF.IGM , taskFunctionCanSILType, taskFunctionCanSILType,
3490
+ SubstitutionMap ());
3491
+ auto layoutSize = getAsyncContextSize (layout);
3492
+ auto layoutSizeVal = llvm::ConstantInt::get (
3493
+ IGF.IGM .SizeTy , layoutSize.getValue ());
3494
+
3495
+ // Call the function.
3496
+ auto *result = IGF.Builder .CreateCall (
3497
+ IGF.IGM .getTaskCreateFuncFn (),
3498
+ { flags, parentTask, taskFunction, layoutSizeVal });
3499
+ result->setDoesNotThrow ();
3500
+ result->setCallingConv (IGF.IGM .SwiftCC );
3501
+
3502
+ // Write the local context information into the initial context for the task.
3503
+ if (layout.hasLocalContext ()) {
3504
+ // Dig out the initial context returned from task creation.
3505
+ auto initialContext = IGF.Builder .CreateExtractValue (result, { 1 });
3506
+ Address initialContextAddr = layout.emitCastTo (IGF, initialContext);
3507
+
3508
+ auto localContextLayout = layout.getLocalContextLayout ();
3509
+ auto localContextAddr = localContextLayout.project (
3510
+ IGF, initialContextAddr, llvm::None);
3511
+ IGF.Builder .CreateStore (localContextInfo, localContextAddr);
3512
+ }
3513
+
3514
+ return result;
3471
3515
}
3472
3516
3473
3517
std::pair<Address, Size> irgen::emitAllocAsyncContext (IRGenFunction &IGF,
0 commit comments