Skip to content

Commit 575bb3d

Browse files
committed
LLVMCompilerContext: Add destroyCoroutine() method
1 parent 69bdb6b commit 575bb3d

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

src/engine/internal/llvm/llvmcompilercontext.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <llvm/Support/TargetSelect.h>
44
#include <llvm/Passes/PassBuilder.h>
5+
#include <llvm/IR/Verifier.h>
56

67
#include <scratchcpp/target.h>
78
#include <iostream>
@@ -16,7 +17,8 @@ LLVMCompilerContext::LLVMCompilerContext(IEngine *engine, Target *target) :
1617
m_module(std::make_unique<llvm::Module>(target ? target->name() : "", *m_llvmCtx)),
1718
m_llvmCtxPtr(m_llvmCtx.get()),
1819
m_modulePtr(m_module.get()),
19-
m_jit((initTarget(), llvm::orc::LLJITBuilder().create()))
20+
m_jit((initTarget(), llvm::orc::LLJITBuilder().create())),
21+
m_llvmCoroDestroyFunction(createCoroDestroyFunction())
2022
{
2123
if (!m_jit) {
2224
llvm::errs() << "error: failed to create JIT: " << toString(m_jit.takeError()) << "\n";
@@ -46,6 +48,8 @@ void LLVMCompilerContext::initJit()
4648
return;
4749
}
4850

51+
assert(m_llvmCoroDestroyFunction);
52+
const std::string coroDestroyFuncName = m_llvmCoroDestroyFunction->getName().str();
4953
m_jitInitialized = true;
5054
assert(m_llvmCtx);
5155
assert(m_module);
@@ -96,16 +100,56 @@ void LLVMCompilerContext::initJit()
96100
#endif
97101
lookupFunction<void *>(name);
98102
}
103+
104+
// Lookup coro_destroy()
105+
m_coroDestroyFunction = lookupFunction<DestroyCoroFuncType>(coroDestroyFuncName);
106+
assert(m_coroDestroyFunction);
99107
}
100108

101109
bool LLVMCompilerContext::jitInitialized() const
102110
{
103111
return m_jitInitialized;
104112
}
105113

114+
void LLVMCompilerContext::destroyCoroutine(void *handle)
115+
{
116+
if (!m_jitInitialized) {
117+
std::cout << "error: JIT must be initialized to destroy coroutines" << std::endl;
118+
assert(false);
119+
}
120+
121+
assert(m_coroDestroyFunction);
122+
m_coroDestroyFunction(handle);
123+
}
124+
106125
void LLVMCompilerContext::initTarget()
107126
{
108127
llvm::InitializeNativeTarget();
109128
llvm::InitializeNativeTargetAsmPrinter();
110129
llvm::InitializeNativeTargetAsmParser();
111130
}
131+
132+
llvm::Function *LLVMCompilerContext::createCoroDestroyFunction()
133+
{
134+
llvm::IRBuilder<> builder(*m_llvmCtx);
135+
136+
// void coro_destroy(void *handle)
137+
llvm::FunctionType *funcType = llvm::FunctionType::get(builder.getVoidTy(), builder.getVoidTy()->getPointerTo(), false);
138+
llvm::Function *func = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "coro_destroy", m_module.get());
139+
func->setComdat(m_module->getOrInsertComdat(func->getName()));
140+
func->setDSOLocal(true);
141+
func->addFnAttr(llvm::Attribute::NoInline);
142+
func->addFnAttr(llvm::Attribute::OptimizeNone);
143+
144+
llvm::BasicBlock *entry = llvm::BasicBlock::Create(*m_llvmCtx, "entry", func);
145+
builder.SetInsertPoint(entry);
146+
builder.CreateCall(llvm::Intrinsic::getDeclaration(m_module.get(), llvm::Intrinsic::coro_destroy), { func->getArg(0) });
147+
builder.CreateRetVoid();
148+
149+
if (llvm::verifyFunction(*func, &llvm::errs())) {
150+
llvm::errs() << "error: coro_destroy() function verficiation failed!\n";
151+
llvm::errs() << "module name: " << m_module->getName() << "\n";
152+
}
153+
154+
return func;
155+
}

src/engine/internal/llvm/llvmcompilercontext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class LLVMCompilerContext : public CompilerContext
2828
void initJit();
2929
bool jitInitialized() const;
3030

31+
void destroyCoroutine(void *handle);
32+
3133
template<typename T>
3234
T lookupFunction(const std::string &name)
3335
{
@@ -42,13 +44,18 @@ class LLVMCompilerContext : public CompilerContext
4244
}
4345

4446
private:
47+
using DestroyCoroFuncType = void (*)(void *);
48+
4549
void initTarget();
50+
llvm::Function *createCoroDestroyFunction();
4651

4752
std::unique_ptr<llvm::LLVMContext> m_llvmCtx;
4853
std::unique_ptr<llvm::Module> m_module;
4954
llvm::LLVMContext *m_llvmCtxPtr = nullptr;
5055
llvm::Module *m_modulePtr = nullptr;
5156
llvm::Expected<std::unique_ptr<llvm::orc::LLJIT>> m_jit;
57+
llvm::Function *m_llvmCoroDestroyFunction = nullptr;
58+
DestroyCoroFuncType m_coroDestroyFunction = nullptr;
5259
bool m_jitInitialized = false;
5360
};
5461

0 commit comments

Comments
 (0)