Skip to content

Commit 69bdb6b

Browse files
committed
LLVMCodeBuilder: Properly destroy finished coroutines
1 parent bf3bded commit 69bdb6b

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

src/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
13631363
if (m_warp)
13641364
m_builder.CreateRet(m_builder.getInt1(true));
13651365
else
1366-
m_builder.CreateRet(coro->createResume(resumeFunc->getArg(0)));
1366+
m_builder.CreateRet(coro->createResume(resumeFunc, resumeFunc->getArg(0)));
13671367

13681368
verifyFunction(resumeFunc);
13691369

src/engine/internal/llvm/llvmcoroutine.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,32 @@ void LLVMCoroutine::createSuspend()
105105
m_builder->SetInsertPoint(resumeBranch);
106106
}
107107

108-
llvm::Value *LLVMCoroutine::createResume(llvm::Value *coroHandle)
108+
llvm::Value *LLVMCoroutine::createResume(llvm::Function *function, llvm::Value *coroHandle)
109109
{
110+
llvm::LLVMContext &ctx = m_builder->getContext();
111+
llvm::Function *coroDone = llvm::Intrinsic::getDeclaration(m_module, llvm::Intrinsic::coro_done);
112+
113+
llvm::Value *ret = m_builder->CreateAlloca(m_builder->getInt1Ty());
114+
llvm::Value *done = m_builder->CreateCall(coroDone, { coroHandle });
115+
done = m_builder->CreateCall(coroDone, { coroHandle });
116+
117+
llvm::BasicBlock *destroyBranch = llvm::BasicBlock::Create(ctx, "", function);
118+
llvm::BasicBlock *resumeBranch = llvm::BasicBlock::Create(ctx, "", function);
119+
llvm::BasicBlock *nextBranch = llvm::BasicBlock::Create(ctx, "", function);
120+
m_builder->CreateCondBr(done, destroyBranch, resumeBranch);
121+
122+
m_builder->SetInsertPoint(destroyBranch);
123+
m_builder->CreateCall(llvm::Intrinsic::getDeclaration(m_module, llvm::Intrinsic::coro_destroy), { coroHandle });
124+
m_builder->CreateBr(nextBranch);
125+
126+
m_builder->SetInsertPoint(resumeBranch);
110127
m_builder->CreateCall(llvm::Intrinsic::getDeclaration(m_module, llvm::Intrinsic::coro_resume), { coroHandle });
111-
return m_builder->CreateCall(llvm::Intrinsic::getDeclaration(m_module, llvm::Intrinsic::coro_done), { coroHandle });
128+
done = m_builder->CreateCall(coroDone, { coroHandle });
129+
m_builder->CreateStore(done, ret);
130+
m_builder->CreateCondBr(done, destroyBranch, nextBranch);
131+
132+
m_builder->SetInsertPoint(nextBranch);
133+
return m_builder->CreateLoad(m_builder->getInt1Ty(), ret);
112134
}
113135

114136
void LLVMCoroutine::end()

src/engine/internal/llvm/llvmcoroutine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class LLVMCoroutine
2222
llvm::Value *didSuspendVar() const;
2323

2424
void createSuspend();
25-
llvm::Value *createResume(llvm::Value *coroHandle);
25+
llvm::Value *createResume(llvm::Function *function, llvm::Value *coroHandle);
2626
void end();
2727

2828
private:

0 commit comments

Comments
 (0)