RFC: MCJIT enhancements - JIT overview

I would like to take part in this discussion
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-July/052022.html) but
there are still subjects related to JIT in LLVM that I do not
understand completely. So I decided to write down some basic
information about JIT system. Please correct me if anything of it is


JIT is a Just-In-Time *compiler*. It takes LLVM IR code and generates
(emits?) target machine code. It can be used during an execution of a
program and generated code will be placed directly in the memory.
LLVM has currently 2 JIT implementations:
* Legacy JIT - the old one that has many features like: multiple
module compilation, lazy compilation, lazy function creation,
* MCJIT - new implementation that takes one module and just does the job.

Q: What are other differences? Why is MCJIT considered faster and better?

Lazy compilation

When LLVM module is loaded and passed to JIT, JIT will not generate
machine code instantly for the module. It will generate code only for
the parts that are just about to be executed. Granularity of the parts
can be different: blocks, functions or modules (if we consider
multi-module JIT). Elements called "functions stubs" are used to mock
the calls to functions that have not been JIT'd yet.

Legacy JIT supports lazy compilation and function stubs. MCJIT does
neither. It is considered to implement lazy compilation on module
level in MCJIT.

Q: If MCJIT have module level lazy compilation, will it need function stubs?

Multi-module JIT'ing

One instance of a JIT can support compiling more than one module. You
can add some number of modules to JIT, they will be compiled and the
generated code will be placed in some common memory managed by Memory

Supported by Legacy JIT, not by MCJIT.

Q: How are functions from different modules linked with one another?
Q: What are differences between JIT'ing multiple modules and linking
multiple modules into one and then JIT'ing one module?

Lazy functions creator

It is a feature of a JIT that allows you to load functions or modules
on demand. When functions with a specific name cannot be found (it is
not present in loaded modules or native libraries) a user callback
called LazyFunctionCreator is called with the name of that function.
The user responsibility is to somehow provide a pointer to that
function. It can be to load some module, JIT it and return the pointer
to the function.

Legacy JIT supports this feature but only for functions. Global
variables cannot be loaded on demand in that way.