MCJit and remove module memory leak?

I’m on llvm 3.8.1 and was wondering if there’s a memory leak in the removeModule impl of mcjit.
In the tutorial http://llvm.org/releases/3.8.1/docs/tutorial/LangImpl4.html a module is removed from the Jit by invoking removeModule.

According to the tutorial:

“Its API is very simple:: addModule adds an LLVM IR module to the JIT, making its functions available for execution; removeModule removes a module, freeing any memory associated with the code in that module;”

But when I look into the implementation of remove module, it only erases the ptr from AddedModules
//return AddedModules.erase(M) || LoadedModules.erase(M) || FinalizedModules.erase(M);

When you add a module, the unique ptr is stripped, and the raw ptr is stored.
//AddedModules.insert(M.release());

This should imply that the person who is invoking removeModule also should invoke a delete on the ptr?

Am I missing something here?

Hi Koffie,

Kaleidoscope is no longer using MCJIT - it has been moved over to the ORC-based KaleidoscopeJIT class (see llvm/examples/Kaleidoscope/include/KaleidoscopeJIT.h). The removeModule method there does not leak memory.

I’ve added documentation in r286026 to describe MCJIT removeModule’s crazy ownership contract.

This will be fixed properly when we kill off ExecutionEngine. :slight_smile:

  • Lang.

I Lol’ed at your commit msg :slight_smile:
We will start migrating to ORC for next release, but for now, this release invoke delete after remove right?

There’s a orc mcjit drop in replacement in the source tree.
Am I correct to assume that Orc is used (and emulating mcjit behaviour) when replacing

LLVMLinkInOrcMCJITReplacement();
//LLVMLinkInMCJIT();

and linking with libOrcJit ?
Does this replacement handle memory better than original mcjit ?

Hi Kevin, Koffie,

We will start migrating to ORC for next release, but for now, this release invoke delete after remove right?

MCJIT’s removeModule method does not delete the module. You’ll need to do that manually. OrcMCJITReplacement is a bug-for-bug compatible implementation of MCJIT using ORC components, so it does not free the memory either.

Does this mean MCJIT is dead/deprecated and projects using it should start
migrating away now? If so, what’s the time frame?

The short answer is yes: I expect MCJIT to be deprecated soon and eventually killed off. I’ll be sending an email with details and a discussion of the timeline to the dev-list in the next few days. That will contain suggestions on how to transition to the new APIs (which I expect to be relatively painless for most people). I can CC you on it if that helps?

Cheers,
Lang.

Hi Lang,

I’m starting to migrate the MCJIT to ORC.
The ideal scenario for a jit would be to generate the code and release module related objects.

I had this in mind:

  • Add module to jit
  • Generate code
  • Remove module
  • Retain memory section that was used to store the generated code.

Using this scenario, memory usage will be kept to a minimum. (I’m seeing quite some mem usage with MCJIT, it allocates a lot of memory but only uses small portion of it).
Do you have any pointers on how to get this starting ? I’m willing to share the results once it’s finished. I might be useful to others as well.

Hi Koffie,

What you’ve described sounds like the KaleidoscopeJIT class from http://llvm.org/docs/tutorial/BuildingAJIT1.html : Modules that are added are compiled to executable code and the module immediately deleted. The executable code persists until the JIT instance is destroyed, or you call “removeModule” (passing the handle returned from addModule).

Cheers,
Lang.

Hi Lang,

I actually meant, create execution engine, add module, jit, delete module/execution engine and only keep the jitted memory parts