Deleting order and acquiring generated function

Hi all,

I’m using LLVM to generate a fairly large number of separate functions at run-time. To minimize the memory overhead, I’d like to delete the IR and everything else that is no longer needed after a function has been generated (I don’t use lazy compilation or anything like that).

I noticed that deleting the ExecutionEngine deletes everything (Module, Function(s), ExistingModuleProvider, and even the LLVMBuilder). Unfortunately it also frees the generated function in memory itself.

So is there an existing way to delete everything except the in-memory generated function? Alternatively, is there a way to just delete the IR and related overhead so everything is ready for generating the next function?

If both are possible, which is the best approach? I have to generate new functions from time to time, so keeping some of the LLVM objects around seems like a good idea if the cost of reconstructing them is considerable. As far as I can tell LLVM looks relatively light-weight though so I’d prefer deleting everything and keeping just the generated functions…

Thanks again for any info,

Nicolas Capens

When JITEmitter is teared down, it also deletes the JITMemoryManager instance. That in turns release the memory of the generated functions. Is this what you are referring to?

The DefaultJITMemoryManager is pretty simple. You can obviously write your own memory manager class that maps the memory in a way that’s persistent. Then all you have to do is to pass a handle of it to JITEmitter.

Evan

Hi Evan,

Thanks a lot for the information!

It’s a viable solution to write my own JITMemoryManager, however I noticed that the JIT doesn’t know the length of the binary function before it is actually emitted. This is a bit inconvenient especially since I have to generate new functions at irregular times. I’m not too keen on using the non-standard _expand function to resize memory to the right size.

Anyway, I also noticed that it’s also possible to do the following:

executionEngine->removeModuleProvider(moduleProvider);

delete moduleProvider;

module->dropAllReferences();

delete module;

This way the memory overhead of the IR of the function is removed and the executionEngine stays around for further use and still manages the memory of the binary functions.

So is this a sane approach?

Kind regards,

Nicolas

There is a new feature since post-2.2 llvm, that gives the size of the to-be generated function to the memory manager. vmkit has the same constraints.

Just look at include/llvm/ExecutionEngine/JITMemoryManager.h, the flag SizeRequired

Nicolas

Nicolas Capens wrote: