[LLVMdev] a life-cycle question for MCJIT
Sanjoy Das
sanjoy at playingwithpointers.com
Thu Jun 4 16:15:00 PDT 2015
Context:
We use MCJIT to generate machine code in our LLVM based JIT compiler.
The code generation process has roughly 5 steps:
0. Generate and optimize LLVM IR.
1. Call generateCodeForModule on the output of (0) to translate LLVM
IR to machine code.
2. Figure out the final locations for the code and data generated by
MCJIT using an allocator specific to our runtime. Make
mapSectionAddress calls to convey this information to MCJIT.
3. Call finalizeObject() to apply relocations.
4. Copy over the relocated code to buffers allocated by our custom
allocator.
The problem:
After running step (1) we may, in rare cases, decide that the
generated code is not usable by our runtime [*], and we have to
"abort" the compile. However, step (1) populates
Dyld->ExternalSymbolRelocations (and possibly other similar data
structures) with the set of pending relocations, and the
ExecutionEngine interface provides no way of cleaning this up without
running (3). Since we use a single long-living instance of MCJIT per
compiler thread, when we abort the compile after running
(1) and before running (3) these relocations get applied to future
compiles and cause problems.
To get around this issue, is it reasonable to add a hook to the
ExecutionEngine interface that resets the state of an MCJIT (and
containing RuntimeDyld) instance from after (1) to before it?
A second potential solution is to "pretend" to run through steps (2)
and (3) to have MCJIT and RuntimeDyld clear their internal states; but
I'd prefer not going this route if it can be avoided.
[*]: why this happens is not important to this discussion, but it is
sufficient to note that a) we cannot reliably predict this before
running step (1) and b) there are no simple tweaks that will prevent
this from happening.
-- Sanjoy
More information about the llvm-dev
mailing list