@@ -665,50 +665,8 @@ void IRGenFunction::emitAwaitAsyncContinuation(
665665 assert (AsyncCoroutineCurrentContinuationContext && " no active continuation" );
666666 auto pointerAlignment = IGM.getPointerAlignment ();
667667
668- // Check whether the continuation has already been resumed.
669- // If so, we can just immediately continue with the control flow.
670- // Otherwise, we need to suspend, and resuming the continuation will
671- // trigger the function to resume.
672- //
673- // We do this by atomically trying to change the synchronization field
674- // in the continuation context from 0 (the state it was initialized
675- // with) to 1. If this fails, the continuation must already have been
676- // resumed, so we can bypass the suspension point and immediately
677- // start interpreting the result stored in the continuation.
678- // Note that we use a strong compare-exchange (the default for the LLVM
679- // cmpxchg instruction), so spurious failures are disallowed; we can
680- // therefore trust that a failure means that the continuation has
681- // already been resumed.
682-
683- auto contAwaitSyncAddr =
684- Builder.CreateStructGEP (AsyncCoroutineCurrentContinuationContext, 1 );
685-
686- auto pendingV = llvm::ConstantInt::get (
687- contAwaitSyncAddr->getType ()->getPointerElementType (),
688- unsigned (ContinuationStatus::Pending));
689- auto awaitedV = llvm::ConstantInt::get (
690- contAwaitSyncAddr->getType ()->getPointerElementType (),
691- unsigned (ContinuationStatus::Awaited));
692- auto results = Builder.CreateAtomicCmpXchg (
693- contAwaitSyncAddr, pendingV, awaitedV,
694- llvm::AtomicOrdering::Release /* success ordering*/ ,
695- llvm::AtomicOrdering::Acquire /* failure ordering */ ,
696- llvm::SyncScope::System);
697- auto firstAtAwait = Builder.CreateExtractValue (results, 1 );
698- auto contBB = createBasicBlock (" await.async.resume" );
699- auto abortBB = createBasicBlock (" await.async.abort" );
700- Builder.CreateCondBr (firstAtAwait, abortBB, contBB);
701- Builder.emitBlock (abortBB);
702- {
703- // We were the first to the sync point. "Abort" (return from the
704- // coroutine partial function, without making a tail call to anything)
705- // because the continuation result is not available yet. When the
706- // continuation is later resumed, the task will get scheduled
707- // starting from the suspension point.
708- emitCoroutineOrAsyncExit ();
709- }
710-
711- Builder.emitBlock (contBB);
668+ // Call swift_continuation_await to check whether the continuation
669+ // has already been resumed.
712670 {
713671 // Set up the suspend point.
714672 SmallVector<llvm::Value *, 8 > arguments;
@@ -718,15 +676,10 @@ void IRGenFunction::emitAwaitAsyncContinuation(
718676 auto resumeProjFn = getOrCreateResumePrjFn ();
719677 arguments.push_back (
720678 Builder.CreateBitOrPointerCast (resumeProjFn, IGM.Int8PtrTy ));
721- // The dispatch function just calls the resume point.
722- auto resumeFnPtr =
723- getFunctionPointerForResumeIntrinsic (AsyncCoroutineCurrentResume);
724679 arguments.push_back (Builder.CreateBitOrPointerCast (
725- createAsyncDispatchFn (resumeFnPtr, { IGM.Int8PtrTy } ),
680+ IGM.getAwaitAsyncContinuationFn ( ),
726681 IGM.Int8PtrTy ));
727- arguments.push_back (AsyncCoroutineCurrentResume);
728- arguments.push_back (Builder.CreateBitOrPointerCast (
729- AsyncCoroutineCurrentContinuationContext, IGM.Int8PtrTy ));
682+ arguments.push_back (AsyncCoroutineCurrentContinuationContext);
730683 auto resultTy =
731684 llvm::StructType::get (IGM.getLLVMContext (), {IGM.Int8PtrTy }, false /* packed*/ );
732685 emitSuspendAsyncCall (swiftAsyncContextIndex, resultTy, arguments);
0 commit comments