@@ -3466,8 +3466,52 @@ void irgen::emitTaskCancel(IRGenFunction &IGF, llvm::Value *task) {
34663466 auto *call = IGF.Builder .CreateCall (IGF.IGM .getTaskCancelFn (), {task});
34673467 call->setDoesNotThrow ();
34683468 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;
34713515}
34723516
34733517std::pair<Address, Size> irgen::emitAllocAsyncContext (IRGenFunction &IGF,
0 commit comments