I’m using the llvm::EngineBuilder to create an instance of the llvm::ExecutionEngine, I then JIT my code, take the addresses I need and delete the llvm::ExecutionEngine. But now I started to wonder, if I could reuse that instance for a new module again?
I first tried calling llvm::EngineBuilder without setting a Module, I planned to add it later – but when I do this the “create” function will crash.
Another test I ran was calling “removeModule” of the llvm::ExecutionEngine after the call to finalizeObject. Then I added the same module again and ran finalizeObject again. The result was weird, I suddenly became error messages about the relocation – I take this came because I applied a memory mapping in the first run.
So to make it short: Is the llvm::ExecutionEngine designed for a reuse or is it better to create a new instance again?
Could you please give me a minimal code sample to produce this behavior?
What crash you get? By quickly looking through interface, EngineBuilder uses nullptr if no module are provided.
I can only provide you with a screenshot for the first problem I noticed:
This code will crash when calling “eeBuilder.create”.
But I also looked at what happens if I do reuse the llvm::ExecutionEngine. After the call to “finalizeObject” I use “removeModule” for the Module I used.
If I know parse the same module again and pass it to that llvm::ExecutionEngine, it will notice the duplication and rename the symbols, like when it does when you add the same module two times.
If I add a different module everything behaves as before – so overall it seems like you can’t reuse a llvm::ExecutionEngine…
I'm by no means an expert on the JIT layers, but ExecutionEngine is an abstract interface. In theory, each implementation of that interface should function similarly, but in practice YMMV. You're using MCJIT, which is the older JIT flow which is not getting a lot of attention these days. You might get further if you switch to using the OrcMCJITReplacement, or migrate to the Orc APIs more generally.
There are some very handy new interfaces in the Orc APIs, like the LLJIT classes which get things going pretty easy. I've been using LLJIT in my project, and it is really easy to setup, keep around and add multiple IR modules to.
The Orc API sounds interesting – are there helpful tutorials or examples available? The only one I found is the Kaleidoscope tutorial but I had difficulties in the past following that tutorial.