1 ===============================
2 ORC Design and Implementation
3 ===============================
11 This document aims to provide a high-level overview of the design and
12 implementation of the ORC JIT APIs. Except where otherwise stated, all
13 discussion applies to the design of the APIs as of LLVM verison 9 (ORCv2).
18 ORC provides a modular API for building JIT compilers. There are a range
19 of use cases for such an API. For example:
21 1. The LLVM tutorials use a simple ORC-based JIT class to execute expressions
22 compiled from a toy languge: Kaleidoscope.
24 2. The LLVM debugger, LLDB, uses a cross-compiling JIT for expression
25 evaluation. In this use case, cross compilation allows expressions compiled
26 in the debugger process to be executed on the debug target process, which may
27 be on a different device/architecture.
29 3. In high-performance JITs (e.g. JVMs, Julia) that want to make use of LLVM's
30 optimizations within an existing JIT infrastructure.
32 4. In interpreters and REPLs, e.g. Cling (C++) and the Swift interpreter.
34 By adoping a modular, library-based design we aim to make ORC useful in as many
35 of these contexts as possible.
40 ORC provides the following features:
42 - *JIT-linking* links relocatable object files (COFF, ELF, MachO) [1]_ into a
43 target process an runtime. The target process may be the same process that
44 contains the JIT session object and jit-linker, or may be another process
45 (even one running on a different machine or architecture) that communicates
48 - *LLVM IR compilation*, which is provided by off the shelf components
49 (IRCompileLayer, SimpleCompiler, ConcurrentIRCompiler) that make it easy to
50 add LLVM IR to a JIT'd process.
52 - *Eager and lazy compilation*. By default, ORC will compile symbols as soon as
53 they are looked up in the JIT session object (``ExecutionSession``). Compiling
54 eagerly by default makes it easy to use ORC as a simple in-memory compiler for
55 an existing JIT. ORC also provides a simple mechanism, lazy-reexports, for
56 deferring compilation until first call.
58 - *Support for custom compilers and program representations*. Clients can supply
59 custom compilers for each symbol that they define in their JIT session. ORC
60 will run the user-supplied compiler when the a definition of a symbol is
61 needed. ORC is actually fully language agnostic: LLVM IR is not treated
62 specially, and is supported via the same wrapper mechanism (the
63 ``MaterializationUnit`` class) that is used for custom compilers.
65 - *Concurrent JIT'd code* and *concurrent compilation*. JIT'd code may spawn
66 multiple threads, and may re-enter the JIT (e.g. for lazy compilation)
67 concurrently from multiple threads. The ORC APIs also support running multiple
68 compilers concurrently, and provides off-the-shelf infrastructure to track
69 dependencies on running compiles (e.g. to ensure that we never call into code
70 until it is safe to do so, even if that involves waiting on multiple
73 - *Orthogonality* and *composability*: Each of the features above can be used (or
74 not) independently. It is possible to put ORC components together to make a
75 non-lazy, in-process, single threaded JIT or a lazy, out-of-process,
76 concurrent JIT, or anything in between.
81 ORC provides two basic JIT classes off-the-shelf. These are useful both as
82 examples of how to assemble ORC components to make a JIT, and as replacements
83 for earlier LLVM JIT APIs (e.g. MCJIT).
85 The LLJIT class uses an IRCompileLayer and RTDyldObjectLinkingLayer to support
86 compilation of LLVM IR and linking of relocatable object files. All operations
87 are performed eagerly on symbol lookup (i.e. a symbol's definition is compiled
88 as soon as you attempt to look up its address). LLJIT is a suitable replacement
89 for MCJIT in most cases (note: some more advanced features, e.g.
90 JITEventListeners are not supported yet).
92 The LLLazyJIT extends LLJIT and adds a CompileOnDemandLayer to enable lazy
93 compilation of LLVM IR. When an LLVM IR module is added via the addLazyIRModule
94 method, function bodies in that module will not be compiled until they are first
95 called. LLLazyJIT aims to provide a replacement of LLVM's original (pre-MCJIT)
98 LLJIT and LLLazyJIT instances can be created using their respective builder
99 classes: LLJITBuilder and LLazyJITBuilder. For example, assuming you have a
100 module ``M`` loaded on an ThreadSafeContext ``Ctx``:
104 // Try to detect the host arch and construct an LLJIT instance.
105 auto JIT = LLJITBuilder().create();
107 // If we could not construct an instance, return an error.
109 return JIT.takeError();
112 if (auto Err = JIT->addIRModule(TheadSafeModule(std::move(M), Ctx)))
115 // Look up the JIT'd code entry point.
116 auto EntrySym = JIT->lookup("entry");
118 return EntrySym.takeError();
120 auto *Entry = (void(*)())EntrySym.getAddress();
124 The builder clasess provide a number of configuration options that can be
125 specified before the JIT instance is constructed. For example:
129 // Build an LLLazyJIT instance that uses four worker threads for compilation,
130 // and jumps to a specific error handler (rather than null) on lazy compile
133 void handleLazyCompileFailure() {
134 // JIT'd code will jump here if lazy compilation fails, giving us an
135 // opportunity to exit or throw an exception into JIT'd code.
139 auto JIT = LLLazyJITBuilder()
140 .setNumCompileThreads(4)
141 .setLazyCompileFailureAddr(
142 toJITTargetAddress(&handleLazyCompileFailure))
147 For users wanting to get started with LLJIT a minimal example program can be
148 found at ``llvm/examples/HowToUseLLJIT``.
153 ORC's JIT'd program model aims to emulate the linking and symbol resolution
154 rules used by the static and dynamic linkers. This allows ORC to JIT
155 arbitrary LLVM IR, including IR produced by an ordinary static compiler (e.g.
156 clang) that uses constructs like symbol linkage and visibility, and weak [3]_
157 and common symbol definitions.
159 To see how this works, imagine a program ``foo`` which links against a pair
160 of dynamic libraries: ``libA`` and ``libB``. On the command line, building this
161 program might look like:
165 $ clang++ -shared -o libA.dylib a1.cpp a2.cpp
166 $ clang++ -shared -o libB.dylib b1.cpp b2.cpp
167 $ clang++ -o myapp myapp.cpp -L. -lA -lB
170 In ORC, this would translate into API calls on a "CXXCompilingLayer" (with error
171 checking omitted for brevity) as:
176 RTDyldObjectLinkingLayer ObjLinkingLayer(
177 ES, []() { return std::make_unique<SectionMemoryManager>(); });
178 CXXCompileLayer CXXLayer(ES, ObjLinkingLayer);
180 // Create JITDylib "A" and add code to it using the CXX layer.
181 auto &LibA = ES.createJITDylib("A");
182 CXXLayer.add(LibA, MemoryBuffer::getFile("a1.cpp"));
183 CXXLayer.add(LibA, MemoryBuffer::getFile("a2.cpp"));
185 // Create JITDylib "B" and add code to it using the CXX layer.
186 auto &LibB = ES.createJITDylib("B");
187 CXXLayer.add(LibB, MemoryBuffer::getFile("b1.cpp"));
188 CXXLayer.add(LibB, MemoryBuffer::getFile("b2.cpp"));
190 // Specify the search order for the main JITDylib. This is equivalent to a
191 // "links against" relationship in a command-line link.
192 ES.getMainJITDylib().setSearchOrder({{&LibA, false}, {&LibB, false}});
193 CXXLayer.add(ES.getMainJITDylib(), MemoryBuffer::getFile("main.cpp"));
195 // Look up the JIT'd main, cast it to a function pointer, then call it.
196 auto MainSym = ExitOnErr(ES.lookup({&ES.getMainJITDylib()}, "main"));
197 auto *Main = (int(*)(int, char*[]))MainSym.getAddress();
199 v int Result = Main(...);
201 This example tells us nothing about *how* or *when* compilation will happen.
202 That will depend on the implementation of the hypothetical CXXCompilingLayer.
203 The same linker-based symbol resolution rules will apply regardless of that
204 implementation, however. For example, if a1.cpp and a2.cpp both define a
205 function "foo" then ORCv2 will generate a duplicate definition error. On the
206 other hand, if a1.cpp and b1.cpp both define "foo" there is no error (different
207 dynamic libraries may define the same symbol). If main.cpp refers to "foo", it
208 should bind to the definition in LibA rather than the one in LibB, since
209 main.cpp is part of the "main" dylib, and the main dylib links against LibA
212 Many JIT clients will have no need for this strict adherence to the usual
213 ahead-of-time linking rules, and should be able to get by just fine by putting
214 all of their code in a single JITDylib. However, clients who want to JIT code
215 for languages/projects that traditionally rely on ahead-of-time linking (e.g.
216 C++) will find that this feature makes life much easier.
218 Symbol lookup in ORC serves two other important functions, beyond providing
219 addresses for symbols: (1) It triggers compilation of the symbol(s) searched for
220 (if they have not been compiled already), and (2) it provides the
221 synchronization mechanism for concurrent compilation. The pseudo-code for the
226 construct a query object from a query set and query handler
228 lodge query against requested symbols, collect required materializers (if any)
230 dispatch materializers (if any)
232 In this context a materializer is something that provides a working definition
233 of a symbol upon request. Usually materializers are just wrappers for compilers,
234 but they may also wrap a jit-linker directly (if the program representation
235 backing the definitions is an object file), or may even be a class that writes
236 bits directly into memory (for example, if the definitions are
237 stubs). Materialization is the blanket term for any actions (compiling, linking,
238 splatting bits, registering with runtimes, etc.) that are requried to generate a
239 symbol definition that is safe to call or access.
241 As each materializer completes its work it notifies the JITDylib, which in turn
242 notifies any query objects that are waiting on the newly materialized
243 definitions. Each query object maintains a count of the number of symbols that
244 it is still waiting on, and once this count reaches zero the query object calls
245 the query handler with a *SymbolMap* (a map of symbol names to addresses)
246 describing the result. If any symbol fails to materialize the query immediately
247 calls the query handler with an error.
249 The collected materialization units are sent to the ExecutionSession to be
250 dispatched, and the dispatch behavior can be set by the client. By default each
251 materializer is run on the calling thread. Clients are free to create new
252 threads to run materializers, or to send the work to a work queue for a thread
253 pool (this is what LLJIT/LLLazyJIT do).
258 Many of ORC's top-level APIs are visible in the example above:
260 - *ExecutionSession* represents the JIT'd program and provides context for the
261 JIT: It contains the JITDylibs, error reporting mechanisms, and dispatches the
264 - *JITDylibs* provide the symbol tables.
266 - *Layers* (ObjLinkingLayer and CXXLayer) are wrappers around compilers and
267 allow clients to add uncompiled program representations supported by those
268 compilers to JITDylibs.
270 Several other important APIs are used explicitly. JIT clients need not be aware
271 of them, but Layer authors will use them:
273 - *MaterializationUnit* - When XXXLayer::add is invoked it wraps the given
274 program representation (in this example, C++ source) in a MaterializationUnit,
275 which is then stored in the JITDylib. MaterializationUnits are responsible for
276 describing the definitions they provide, and for unwrapping the program
277 representation and passing it back to the layer when compilation is required
278 (this ownership shuffle makes writing thread-safe layers easier, since the
279 ownership of the program representation will be passed back on the stack,
280 rather than having to be fished out of a Layer member, which would require
283 - *MaterializationResponsibility* - When a MaterializationUnit hands a program
284 representation back to the layer it comes with an associated
285 MaterializationResponsibility object. This object tracks the definitions
286 that must be materialized and provides a way to notify the JITDylib once they
287 are either successfully materialized or a failure occurs.
292 TBD: absolute symbols, aliases, off-the-shelf layers.
297 Laziness in ORC is provided by a utility called "lazy-reexports". The aim of
298 this utility is to re-use the synchronization provided by the symbol lookup
299 mechanism to make it safe to lazily compile functions, even if calls to the
300 stub occur simultaneously on multiple threads of JIT'd code. It does this by
301 reducing lazy compilation to symbol lookup: The lazy stub performs a lookup of
302 its underlying definition on first call, updating the function body pointer
303 once the definition is available. If additional calls arrive on other threads
304 while compilation is ongoing they will be safely blocked by the normal lookup
305 synchronization guarantee (no result until the result is safe) and can also
306 proceed as soon as compilation completes.
310 Supporting Custom Compilers
311 ===========================
315 Transitioning from ORCv1 to ORCv2
316 =================================
318 Since LLVM 7.0, new ORC development work has focused on adding support for
319 concurrent JIT compilation. The new APIs (including new layer interfaces and
320 implementations, and new utilities) that support concurrency are collectively
321 referred to as ORCv2, and the original, non-concurrent layers and utilities
322 are now referred to as ORCv1.
324 The majority of the ORCv1 layers and utilities were renamed with a 'Legacy'
325 prefix in LLVM 8.0, and have deprecation warnings attached in LLVM 9.0. In LLVM
326 10.0 ORCv1 will be removed entirely.
328 Transitioning from ORCv1 to ORCv2 should be easy for most clients. Most of the
329 ORCv1 layers and utilities have ORCv2 counterparts [2]_ that can be directly
330 substituted. However there are some design differences between ORCv1 and ORCv2
333 1. ORCv2 fully adopts the JIT-as-linker model that began with MCJIT. Modules
334 (and other program representations, e.g. Object Files) are no longer added
335 directly to JIT classes or layers. Instead, they are added to ``JITDylib``
336 instances *by* layers. The ``JITDylib`` determines *where* the definitions
337 reside, the layers determine *how* the definitions will be compiled.
338 Linkage relationships between ``JITDylibs`` determine how inter-module
339 references are resolved, and symbol resolvers are no longer used. See the
340 section `Design Overview`_ for more details.
342 Unless multiple JITDylibs are needed to model linkage relationsips, ORCv1
343 clients should place all code in the main JITDylib (returned by
344 ``ExecutionSession::getMainJITDylib()``). MCJIT clients should use LLJIT
345 (see `LLJIT and LLLazyJIT`_).
347 2. All JIT stacks now need an ``ExecutionSession`` instance. ExecutionSession
348 manages the string pool, error reporting, synchronization, and symbol
351 3. ORCv2 uses uniqued strings (``SymbolStringPtr`` instances) rather than
352 string values in order to reduce memory overhead and improve lookup
353 performance. See the subsection `How to manage symbol strings`_.
355 4. IR layers require ThreadSafeModule instances, rather than
356 std::unique_ptr<Module>s. ThreadSafeModule is a wrapper that ensures that
357 Modules that use the same LLVMContext are not accessed concurrently.
358 See `How to use ThreadSafeModule and ThreadSafeContext`_.
360 5. Symbol lookup is no longer handled by layers. Instead, there is a
361 ``lookup`` method on JITDylib that takes a list of JITDylibs to scan.
369 auto Sym = ES.lookup({&JD1, &JD2}, ES.intern("_main"));
371 6. Module removal is not yet supported. There is no equivalent of the
372 layer concept removeModule/removeObject methods. Work on resource tracking
373 and removal in ORCv2 is ongoing.
375 For code examples and suggestions of how to use the ORCv2 APIs, please see
376 the section `How-tos`_.
381 How to manage symbol strings
382 ############################
384 Symbol strings in ORC are uniqued to improve lookup performance, reduce memory
385 overhead, and allow symbol names to function as efficient keys. To get the
386 unique ``SymbolStringPtr`` for a string value, call the
387 ``ExecutionSession::intern`` method:
393 auto MainSymbolName = ES.intern("main");
395 If you wish to perform lookup using the C/IR name of a symbol you will also
396 need to apply the platform linker-mangling before interning the string. On
397 Linux this mangling is a no-op, but on other platforms it usually involves
398 adding a prefix to the string (e.g. '_' on Darwin). The mangling scheme is
399 based on the DataLayout for the target. Given a DataLayout and an
400 ExecutionSession, you can create a MangleAndInterner function object that
401 will perform both jobs for you:
406 const DataLayout &DL = ...;
407 MangleAndInterner Mangle(ES, DL);
411 // Portable IR-symbol-name lookup:
412 auto Sym = ES.lookup({&ES.getMainJITDylib()}, Mangle("main"));
414 How to create JITDylibs and set up linkage relationships
415 ########################################################
417 In ORC, all symbol definitions reside in JITDylibs. JITDylibs are created by
418 calling the ``ExecutionSession::createJITDylib`` method with a unique name:
423 auto &JD = ES.createJITDylib("libFoo.dylib");
425 The JITDylib is owned by the ``ExecutionEngine`` instance and will be freed
426 when it is destroyed.
428 A JITDylib representing the JIT main program is created by ExecutionEngine by
429 default. A reference to it can be obtained by calling
430 ``ExecutionSession::getMainJITDylib()``:
435 auto &MainJD = ES.getMainJITDylib();
437 How to use ThreadSafeModule and ThreadSafeContext
438 #################################################
440 ThreadSafeModule and ThreadSafeContext are wrappers around Modules and
441 LLVMContexts respectively. A ThreadSafeModule is a pair of a
442 std::unique_ptr<Module> and a (possibly shared) ThreadSafeContext value. A
443 ThreadSafeContext is a pair of a std::unique_ptr<LLVMContext> and a lock.
444 This design serves two purposes: providing a locking scheme and lifetime
445 management for LLVMContexts. The ThreadSafeContext may be locked to prevent
446 accidental concurrent access by two Modules that use the same LLVMContext.
447 The underlying LLVMContext is freed once all ThreadSafeContext values pointing
448 to it are destroyed, allowing the context memory to be reclaimed as soon as
449 the Modules referring to it are destroyed.
451 ThreadSafeContexts can be explicitly constructed from a
452 std::unique_ptr<LLVMContext>:
456 ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());
458 ThreadSafeModules can be constructed from a pair of a std::unique_ptr<Module>
459 and a ThreadSafeContext value. ThreadSafeContext values may be shared between
460 multiple ThreadSafeModules:
464 ThreadSafeModule TSM1(
465 std::make_unique<Module>("M1", *TSCtx.getContext()), TSCtx);
467 ThreadSafeModule TSM2(
468 std::make_unique<Module>("M2", *TSCtx.getContext()), TSCtx);
470 Before using a ThreadSafeContext, clients should ensure that either the context
471 is only accessible on the current thread, or that the context is locked. In the
472 example above (where the context is never locked) we rely on the fact that both
473 ``TSM1`` and ``TSM2``, and TSCtx are all created on one thread. If a context is
474 going to be shared between threads then it must be locked before any accessing
475 or creating any Modules attached to it. E.g.
479 ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());
481 ThreadPool TP(NumThreads);
484 for (auto &ModulePath : ModulePaths) {
487 auto Lock = TSCtx.getLock();
488 auto M = loadModuleOnContext(ModulePath, TSCtx.getContext());
489 J.addModule(ThreadSafeModule(std::move(M), TSCtx));
495 To make exclusive access to Modules easier to manage the ThreadSafeModule class
496 provides a convenince function, ``withModuleDo``, that implicitly (1) locks the
497 associated context, (2) runs a given function object, (3) unlocks the context,
498 and (3) returns the result generated by the function object. E.g.
502 ThreadSafeModule TSM = getModule(...);
505 size_t NumFunctionsInModule =
507 [](Module &M) { // <- Context locked before entering lambda.
509 } // <- Context unlocked after leaving.
512 Clients wishing to maximize possibilities for concurrent compilation will want
513 to create every new ThreadSafeModule on a new ThreadSafeContext. For this
514 reason a convenience constructor for ThreadSafeModule is provided that implicitly
515 constructs a new ThreadSafeContext value from a std::unique_ptr<LLVMContext>:
519 // Maximize concurrency opportunities by loading every module on a
521 for (const auto &IRPath : IRPaths) {
522 auto Ctx = std::make_unique<LLVMContext>();
523 auto M = std::make_unique<LLVMContext>("M", *Ctx);
524 CompileLayer.add(ES.getMainJITDylib(),
525 ThreadSafeModule(std::move(M), std::move(Ctx)));
528 Clients who plan to run single-threaded may choose to save memory by loading
529 all modules on the same context:
533 // Save memory by using one context for all Modules:
534 ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());
535 for (const auto &IRPath : IRPaths) {
536 ThreadSafeModule TSM(parsePath(IRPath, *TSCtx.getContext()), TSCtx);
537 CompileLayer.add(ES.getMainJITDylib(), ThreadSafeModule(std::move(TSM));
540 How to Add Process and Library Symbols to the JITDylibs
541 =======================================================
543 JIT'd code typically needs access to symbols in the host program or in
544 supporting libraries. References to process symbols can be "baked in" to code
545 as it is compiled by turning external references into pre-resolved integer
546 constants, however this ties the JIT'd code to the current process's virtual
547 memory layout (meaning that it can not be cached between runs) and makes
548 debugging lower level program representations difficult (as all external
549 references are opaque integer values). A bettor solution is to maintain symbolic
550 external references and let the jit-linker bind them for you at runtime. To
551 allow the JIT linker to find these external definitions their addresses must
552 be added to a JITDylib that the JIT'd definitions link against.
554 Adding definitions for external symbols could be done using the absoluteSymbols
559 const DataLayout &DL = getDataLayout();
560 MangleAndInterner Mangle(ES, DL);
562 auto &JD = ES.getMainJITDylib();
566 { Mangle("puts"), pointerToJITTargetAddress(&puts)},
567 { Mangle("gets"), pointerToJITTargetAddress(&getS)}
570 Manually adding absolute symbols for a large or changing interface is cumbersome
571 however, so ORC provides an alternative to generate new definitions on demand:
572 *definition generators*. If a definition generator is attached to a JITDylib,
573 then any unsuccessful lookup on that JITDylib will fall back to calling the
574 definition generator, and the definition generator may choose to generate a new
575 definition for the missing symbols. Of particular use here is the
576 ``DynamicLibrarySearchGenerator`` utility. This can be used to reflect the whole
577 exported symbol set of the process or a specific dynamic library, or a subset
578 of either of these determined by a predicate.
580 For example, to load the whole interface of a runtime library:
584 const DataLayout &DL = getDataLayout();
585 auto &JD = ES.getMainJITDylib();
587 JD.setGenerator(DynamicLibrarySearchGenerator::Load("/path/to/lib"
588 DL.getGlobalPrefix()));
590 // IR added to JD can now link against all symbols exported by the library
591 // at '/path/to/lib'.
592 CompileLayer.add(JD, loadModule(...));
594 Or, to expose a whitelisted set of symbols from the main process:
598 const DataLayout &DL = getDataLayout();
599 MangleAndInterner Mangle(ES, DL);
601 auto &JD = ES.getMainJITDylib();
603 DenseSet<SymbolStringPtr> Whitelist({
608 // Use GetForCurrentProcess with a predicate function that checks the
611 DynamicLibrarySearchGenerator::GetForCurrentProcess(
612 DL.getGlobalPrefix(),
613 [&](const SymbolStringPtr &S) { return Whitelist.count(S); }));
615 // IR added to JD can now link against any symbols exported by the process
616 // and contained in the whitelist.
617 CompileLayer.add(JD, loadModule(...));
622 TBD: Speculative compilation. Object Caches.
624 .. [1] Formats/architectures vary in terms of supported features. MachO and
625 ELF tend to have better support than COFF. Patches very welcome!
627 .. [2] The ``LazyEmittingLayer``, ``RemoteObjectClientLayer`` and
628 ``RemoteObjectServerLayer`` do not have counterparts in the new
629 system. In the case of ``LazyEmittingLayer`` it was simply no longer
630 needed: in ORCv2, deferring compilation until symbols are looked up is
631 the default. The removal of ``RemoteObjectClientLayer`` and
632 ``RemoteObjectServerLayer`` means that JIT stacks can no longer be split
633 across processes, however this functionality appears not to have been
636 .. [3] Weak definitions are currently handled correctly within dylibs, but if
637 multiple dylibs provide a weak definition of a symbol then each will end
638 up with its own definition (similar to how weak definitions are handled
639 in Windows DLLs). This will be fixed in the future.