================ @@ -243,95 +321,105 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co CGF.EmitBlock(SuspendBlock); auto &Builder = CGF.Builder; - llvm::Function *CoroSave = CGF.CGM.getIntrinsic(llvm::Intrinsic::coro_save); - auto *NullPtr = llvm::ConstantPointerNull::get(CGF.CGM.Int8PtrTy); - auto *SaveCall = Builder.CreateCall(CoroSave, {NullPtr}); auto SuspendWrapper = CodeGenFunction(CGF.CGM).generateAwaitSuspendWrapper( CGF.CurFn->getName(), Prefix, S); - CGF.CurCoro.InSuspendBlock = true; - assert(CGF.CurCoro.Data && CGF.CurCoro.Data->CoroBegin && "expected to be called in coroutine context"); - SmallVector<llvm::Value *, 3> SuspendIntrinsicCallArgs; - SuspendIntrinsicCallArgs.push_back( - CGF.getOrCreateOpaqueLValueMapping(S.getOpaqueValue()).getPointer(CGF)); - - SuspendIntrinsicCallArgs.push_back(CGF.CurCoro.Data->CoroBegin); - SuspendIntrinsicCallArgs.push_back(SuspendWrapper); - - const auto SuspendReturnType = S.getSuspendReturnType(); - llvm::Intrinsic::ID AwaitSuspendIID; - - switch (SuspendReturnType) { - case CoroutineSuspendExpr::SuspendReturnType::SuspendVoid: - AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_void; - break; - case CoroutineSuspendExpr::SuspendReturnType::SuspendBool: - AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_bool; - break; - case CoroutineSuspendExpr::SuspendReturnType::SuspendHandle: - AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_handle; - break; - } - - llvm::Function *AwaitSuspendIntrinsic = CGF.CGM.getIntrinsic(AwaitSuspendIID); - // SuspendHandle might throw since it also resumes the returned handle. + const auto SuspendReturnType = S.getSuspendReturnType(); const bool AwaitSuspendCanThrow = SuspendReturnType == CoroutineSuspendExpr::SuspendReturnType::SuspendHandle || StmtCanThrow(S.getSuspendExpr()); - llvm::CallBase *SuspendRet = nullptr; - // FIXME: add call attributes? - if (AwaitSuspendCanThrow) - SuspendRet = - CGF.EmitCallOrInvoke(AwaitSuspendIntrinsic, SuspendIntrinsicCallArgs); - else - SuspendRet = CGF.EmitNounwindRuntimeCall(AwaitSuspendIntrinsic, - SuspendIntrinsicCallArgs); + llvm::Value *Awaiter = + CGF.getOrCreateOpaqueLValueMapping(S.getOpaqueValue()).getPointer(CGF); + llvm::Value *Frame = CGF.CurCoro.Data->CoroBegin; - assert(SuspendRet); - CGF.CurCoro.InSuspendBlock = false; + if (useCoroAwaitSuspendDestroy(S)) { // Call `await_suspend_destroy` & cleanup + emitAwaitSuspendDestroy(CGF, Coro, SuspendWrapper, Awaiter, Frame, + AwaitSuspendCanThrow); + } else { // Normal suspend path -- can actually suspend, uses intrinsics ---------------- snarkmaster wrote:
Sure, I'll give it a try. If the argument list isn't too gross, I'd also prefer that. Here, I was trying to change the existing code layout as little as necessary. https://github.com/llvm/llvm-project/pull/152623 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits