Question about addModule in orc::IRCompileLayer (now orc::LegacyIRCompileLayer)

I am trying to convert some very old code based on LLVM 3.4.2 to LLVM 7. So I want to replace some old LLVM JIT code with OrcJIT. I am new to this stuff and when I study the Kaleidoscope example, I started wondering about this.

LLVMContext stores raw pointers to Module and will destroy the Module when the context is destroyed. But in the example, the module’s ownership is transferred to IRCompileLayer (which in trunk seems to be now LegacyIRCompileLayer) which will destroy the module after eagerly compiling it using SimpleCompiler. Wouldn’t that leave the pointer to the same Module held in LLVMContext’s OwnedModules dangling?

AFAIK, LLVMContext always owns the modules with which it is constructed (it holds them as Module*) unless it is explicitly removed from the Context. So it is not clear how std::unique_ptr can be used on the same pointer.

Specifically, the problem is in this line:

TheModule = llvm::make_unique(“my cool jit”, TheContext);

TheModule owns the new module but so does TheContext (though not explicitly via unique_ptr).

And then later we have:

TheJIT->addModule(std::move(TheModule));

The ownership is transferred but TheContext is still pointing to Module.

Note my question is not specifically about Kaleidoscope example but more about orc::LegacyIRCompileLayer::addModule expecting the caller to transfer ownership of a module.

Am I missing something here? TIA.

/Riyaz

Hi Riyaz,

The state of Module/Context ownership is very muddled in the codebase. As you have discovered: LLVMContext’s notionally own their modules (via raw pointers deleted upon destruction of the context), however in practice we always hold llvm Modules by unique_ptr. Since the Module destructor removes the raw pointer from the Context, this doesn’t usually blow up. It’s pretty broken though.

I would argue that you should use unique_ptr and ignore LLVMContext ownership.

If you are feeling game, I would also recommend looking into ORCv2. The ORCv1 layers (including LegacyIRCompileLayer) are being deprecated in favor of new versions that support concurrent compilation. To make concurrent compilation safe and efficient, ORCv2 introduces a wrapper called ThreadSafeModule that owns a pair of a Module and a context. The easiest way to start using ORCv2 (and see an example of ThreadSafeModule usage) is via the LLJIT class. See llvm/examples/HowToUseLLJIT.

Cheers,
Lang.