I'm having issues getting the LLVM ORC JIT API to work properly with my project. This is my code (running LLVM 18.1.8):
class Jit
{
private:
ExecutionSession _executionSession;
RTDyldObjectLinkingLayer _objectLayer;
IRCompileLayer _compileLayer;
IRTransformLayer _optimizeLayer;
DataLayout _dataLayout;
MangleAndInterner _mangle;
ThreadSafeContext _context;
ThreadSafeModule _module;
public:
JITDylib* getMain()
{
return _executionSession.getJITDylibByName("<main>");
}
Jit(std::unique_ptr<SelfExecutorProcessControl>&& processControl, JITTargetMachineBuilder jitTargetMachineBuilder, DataLayout dataLayout, Module* module) :
_executionSession(std::move(processControl)),
_objectLayer(_executionSession, []() { return std::make_unique<SectionMemoryManager>(); }),
_compileLayer(_executionSession, _objectLayer, std::make_unique<ConcurrentIRCompiler>(std::move(jitTargetMachineBuilder))),
_optimizeLayer(_executionSession, _compileLayer, optimizeModule),
_dataLayout(dataLayout),
_mangle(_executionSession, dataLayout),
_context(std::make_unique<LLVMContext>()),
_module(std::move(std::unique_ptr<Module>(module)), _context)
{
_executionSession.createJITDylib("<main>");
getMain()->addGenerator(
cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(_dataLayout.getGlobalPrefix())));
_optimizeLayer.add(
*getMain(),
std::move(_module));
LLVMMemoryBufferRef memBufferRef;
char* message = nullptr;
LLVMCreateMemoryBufferWithContentsOfFile(
"path/to/my/file.obj",
&memBufferRef,
&message);
MemoryBuffer* memBuffer = (MemoryBuffer*)memBufferRef;
_objectLayer.add(getMain()->getDefaultResourceTracker(), std::unique_ptr<MemoryBuffer>(memBuffer));
getMain()->getDefaultResourceTracker()->Retain();
}
Expected<ExecutorSymbolDef> lookup(StringRef Name)
{
return _executionSession.lookup({ getMain() }, _mangle(Name.str()));
}
private:
static Expected<ThreadSafeModule> optimizeModule(
ThreadSafeModule threadSafeModule,
const MaterializationResponsibility& responsibility)
{
std::cout << "Optimize" << std::endl;
return std::move(threadSafeModule);
}
};
This is working such that I can lookup a single symbol, call it and get a result back. However, I have a couple of issues (which might be related but I'm not sure on that):
- I can't seem to be able to get the module back afterwards. It seems that ThreadSafeModule has "getModuleUnlocked", but the ThreadSafeModule is itself impossible to get.
- I need to be able to call multiple functions, but currently only the first lookup works and all others just error with "Symbol not found" (including if I lookup the same one twice)
Are these just hard limitations of LLVM, or am I missing something here?
Any help you could give would be greatly appreciated.
Thanks.