===============================
ORC Design and Implementation
===============================

.. contents::
   :local:

Introduction
============

This document aims to provide a high-level overview of the design and
implementation of the ORC JIT APIs. Except where otherwise stated all discussion
refers to the modern ORCv2 APIs (available since LLVM 7). Clients wishing to
transition from OrcV1 should see Section :ref:`transitioning_orcv1_to_orcv2`.

Use-cases
=========

ORC provides a modular API for building JIT compilers. There are a number
of use cases for such an API. For example:

1. The LLVM tutorials use a simple ORC-based JIT class to execute expressions
compiled from a toy language: Kaleidoscope.

2. The LLVM debugger, LLDB, uses a cross-compiling JIT for expression
evaluation. In this use case, cross compilation allows expressions compiled
in the debugger process to be executed on the debug target process, which may
be on a different device/architecture.

3. In high-performance JITs (e.g. JVMs, Julia) that want to make use of LLVM's
optimizations within an existing JIT infrastructure.

4. In interpreters and REPLs, e.g. Cling (C++) and the Swift interpreter.

By adopting a modular, library-based design we aim to make ORC useful in as many
of these contexts as possible.

Features
========

ORC provides the following features:

**JIT-linking**
  ORC provides APIs to link relocatable object files (COFF, ELF, MachO) [1]_
  into a target process at runtime. The target process may be the same process
  that contains the JIT session object and jit-linker, or may be another process
  (even one running on a different machine or architecture) that communicates
  with the JIT via RPC.

**LLVM IR compilation**
  ORC provides off the shelf components (IRCompileLayer, SimpleCompiler,
  ConcurrentIRCompiler) that make it easy to add LLVM IR to a JIT'd process.

**Eager and lazy compilation**
  By default, ORC will compile symbols as soon as they are looked up in the JIT
  session object (``ExecutionSession``). Compiling eagerly by default makes it
  easy to use ORC as an in-memory compiler for an existing JIT (similar to how
  MCJIT is commonly used). However ORC also provides built-in support for lazy
  compilation via lazy-reexports (see :ref:`Laziness`).

**Support for Custom Compilers and Program Representations**
  Clients can supply custom compilers for each symbol that they define in their
  JIT session. ORC will run the user-supplied compiler when the a definition of
  a symbol is needed. ORC is actually fully language agnostic: LLVM IR is not
  treated specially, and is supported via the same wrapper mechanism (the
  ``MaterializationUnit`` class) that is used for custom compilers.

**Concurrent JIT'd code** and **Concurrent Compilation**
  JIT'd code may be executed in multiple threads, may spawn new threads, and may
  re-enter the ORC (e.g. to request lazy compilation) concurrently from multiple
  threads. Compilers launched my ORC can run concurrently (provided the client
  sets up an appropriate dispatcher). Built-in dependency tracking ensures that
  ORC does not release pointers to JIT'd code or data until all dependencies
  have also been JIT'd and they are safe to call or use.

**Removable Code**
  Resources for JIT'd program representations

**Orthogonality** and **Composability**
  Each of the features above can be used independently. It is possible to put
  ORC components together to make a non-lazy, in-process, single threaded JIT
  or a lazy, out-of-process, concurrent JIT, or anything in between.

LLJIT and LLLazyJIT
===================

ORC provides two basic JIT classes off-the-shelf. These are useful both as
examples of how to assemble ORC components to make a JIT, and as replacements
for earlier LLVM JIT APIs (e.g. MCJIT).

The LLJIT class uses an IRCompileLayer and RTDyldObjectLinkingLayer to support
compilation of LLVM IR and linking of relocatable object files. All operations
are performed eagerly on symbol lookup (i.e. a symbol's definition is compiled
as soon as you attempt to look up its address). LLJIT is a suitable replacement
for MCJIT in most cases (note: some more advanced features, e.g.
JITEventListeners are not supported yet).

The LLLazyJIT extends LLJIT and adds a CompileOnDemandLayer to enable lazy
compilation of LLVM IR. When an LLVM IR module is added via the addLazyIRModule
method, function bodies in that module will not be compiled until they are first
called. LLLazyJIT aims to provide a replacement of LLVM's original (pre-MCJIT)
JIT API.

LLJIT and LLLazyJIT instances can be created using their respective builder
classes: LLJITBuilder and LLazyJITBuilder. For example, assuming you have a
module ``M`` loaded on a ThreadSafeContext ``Ctx``:

.. code-block:: c++

  // Try to detect the host arch and construct an LLJIT instance.
  auto JIT = LLJITBuilder().create();

  // If we could not construct an instance, return an error.
  if (!JIT)
    return JIT.takeError();

  // Add the module.
  if (auto Err = JIT->addIRModule(TheadSafeModule(std::move(M), Ctx)))
    return Err;

  // Look up the JIT'd code entry point.
  auto EntrySym = JIT->lookup("entry");
  if (!EntrySym)
    return EntrySym.takeError();

  // Cast the entry point address to a function pointer.
  auto *Entry = (void(*)())EntrySym.getAddress();

  // Call into JIT'd code.
  Entry();

The builder classes provide a number of configuration options that can be
specified before the JIT instance is constructed. For example:

.. code-block:: c++

  // Build an LLLazyJIT instance that uses four worker threads for compilation,
  // and jumps to a specific error handler (rather than null) on lazy compile
  // failures.

  void handleLazyCompileFailure() {
    // JIT'd code will jump here if lazy compilation fails, giving us an
    // opportunity to exit or throw an exception into JIT'd code.
    throw JITFailed();
  }

  auto JIT = LLLazyJITBuilder()
               .setNumCompileThreads(4)
               .setLazyCompileFailureAddr(
                   toJITTargetAddress(&handleLazyCompileFailure))
               .create();

  // ...

For users wanting to get started with LLJIT a minimal example program can be
found at ``llvm/examples/HowToUseLLJIT``.

Design Overview
===============

ORC's JIT program model aims to emulate the linking and symbol resolution
rules used by the static and dynamic linkers. This allows ORC to JIT
arbitrary LLVM IR, including IR produced by an ordinary static compiler (e.g.
clang) that uses constructs like symbol linkage and visibility, and weak [3]_
and common symbol definitions.

To see how this works, imagine a program ``foo`` which links against a pair
of dynamic libraries: ``libA`` and ``libB``. On the command line, building this
program might look like:

.. code-block:: bash

  $ clang++ -shared -o libA.dylib a1.cpp a2.cpp
  $ clang++ -shared -o libB.dylib b1.cpp b2.cpp
  $ clang++ -o myapp myapp.cpp -L. -lA -lB
  $ ./myapp

In ORC, this would translate into API calls on a hypothetical CXXCompilingLayer
(with error checking omitted for brevity) as:

.. code-block:: c++

  ExecutionSession ES;
  RTDyldObjectLinkingLayer ObjLinkingLayer(
      ES, []() { return std::make_unique<SectionMemoryManager>(); });
  CXXCompileLayer CXXLayer(ES, ObjLinkingLayer);

  // Create JITDylib "A" and add code to it using the CXX layer.
  auto &LibA = ES.createJITDylib("A");
  CXXLayer.add(LibA, MemoryBuffer::getFile("a1.cpp"));
  CXXLayer.add(LibA, MemoryBuffer::getFile("a2.cpp"));

  // Create JITDylib "B" and add code to it using the CXX layer.
  auto &LibB = ES.createJITDylib("B");
  CXXLayer.add(LibB, MemoryBuffer::getFile("b1.cpp"));
  CXXLayer.add(LibB, MemoryBuffer::getFile("b2.cpp"));

  // Create and specify the search order for the main JITDylib. This is
  // equivalent to a "links against" relationship in a command-line link.
  auto &MainJD = ES.createJITDylib("main");
  MainJD.addToLinkOrder(&LibA);
  MainJD.addToLinkOrder(&LibB);
  CXXLayer.add(MainJD, MemoryBuffer::getFile("main.cpp"));

  // Look up the JIT'd main, cast it to a function pointer, then call it.
  auto MainSym = ExitOnErr(ES.lookup({&MainJD}, "main"));
  auto *Main = (int(*)(int, char*[]))MainSym.getAddress();

  int Result = Main(...);

This example tells us nothing about *how* or *when* compilation will happen.
That will depend on the implementation of the hypothetical CXXCompilingLayer.
The same linker-based symbol resolution rules will apply regardless of that
implementation, however. For example, if a1.cpp and a2.cpp both define a
function "foo" then ORCv2 will generate a duplicate definition error. On the
other hand, if a1.cpp and b1.cpp both define "foo" there is no error (different
dynamic libraries may define the same symbol). If main.cpp refers to "foo", it
should bind to the definition in LibA rather than the one in LibB, since
main.cpp is part of the "main" dylib, and the main dylib links against LibA
before LibB.

Many JIT clients will have no need for this strict adherence to the usual
ahead-of-time linking rules, and should be able to get by just fine by putting
all of their code in a single JITDylib. However, clients who want to JIT code
for languages/projects that traditionally rely on ahead-of-time linking (e.g.
C++) will find that this feature makes life much easier.

Symbol lookup in ORC serves two other important functions, beyond providing
addresses for symbols: (1) It triggers compilation of the symbol(s) searched for
(if they have not been compiled already), and (2) it provides the
synchronization mechanism for concurrent compilation. The pseudo-code for the
lookup process is:

.. code-block:: none

  construct a query object from a query set and query handler
  lock the session
  lodge query against requested symbols, collect required materializers (if any)
  unlock the session
  dispatch materializers (if any)

In this context a materializer is something that provides a working definition
of a symbol upon request. Usually materializers are just wrappers for compilers,
but they may also wrap a jit-linker directly (if the program representation
backing the definitions is an object file), or may even be a class that writes
bits directly into memory (for example, if the definitions are
stubs). Materialization is the blanket term for any actions (compiling, linking,
splatting bits, registering with runtimes, etc.) that are required to generate a
symbol definition that is safe to call or access.

As each materializer completes its work it notifies the JITDylib, which in turn
notifies any query objects that are waiting on the newly materialized
definitions. Each query object maintains a count of the number of symbols that
it is still waiting on, and once this count reaches zero the query object calls
the query handler with a *SymbolMap* (a map of symbol names to addresses)
describing the result. If any symbol fails to materialize the query immediately
calls the query handler with an error.

The collected materialization units are sent to the ExecutionSession to be
dispatched, and the dispatch behavior can be set by the client. By default each
materializer is run on the calling thread. Clients are free to create new
threads to run materializers, or to send the work to a work queue for a thread
pool (this is what LLJIT/LLLazyJIT do).

Top Level APIs
==============

Many of ORC's top-level APIs are visible in the example above:

- *ExecutionSession* represents the JIT'd program and provides context for the
  JIT: It contains the JITDylibs, error reporting mechanisms, and dispatches the
  materializers.

- *JITDylibs* provide the symbol tables.

- *Layers* (ObjLinkingLayer and CXXLayer) are wrappers around compilers and
  allow clients to add uncompiled program representations supported by those
  compilers to JITDylibs.

- *ResourceTrackers* allow you to remove code.

Several other important APIs are used explicitly. JIT clients need not be aware
of them, but Layer authors will use them:

- *MaterializationUnit* - When XXXLayer::add is invoked it wraps the given
  program representation (in this example, C++ source) in a MaterializationUnit,
  which is then stored in the JITDylib. MaterializationUnits are responsible for
  describing the definitions they provide, and for unwrapping the program
  representation and passing it back to the layer when compilation is required
  (this ownership shuffle makes writing thread-safe layers easier, since the
  ownership of the program representation will be passed back on the stack,
  rather than having to be fished out of a Layer member, which would require
  synchronization).

- *MaterializationResponsibility* - When a MaterializationUnit hands a program
  representation back to the layer it comes with an associated
  MaterializationResponsibility object. This object tracks the definitions
  that must be materialized and provides a way to notify the JITDylib once they
  are either successfully materialized or a failure occurs.

Absolute Symbols, Aliases, and Reexports
========================================

ORC makes it easy to define symbols with absolute addresses, or symbols that
are simply aliases of other symbols:

Absolute Symbols
----------------

Absolute symbols are symbols that map directly to addresses without requiring
further materialization, for example: "foo" = 0x1234. One use case for
absolute symbols is allowing resolution of process symbols. E.g.

.. code-block: c++

  JD.define(absoluteSymbols(SymbolMap({
      { Mangle("printf"),
        { pointerToJITTargetAddress(&printf),
          JITSymbolFlags::Callable } }
    });

With this mapping established code added to the JIT can refer to printf
symbolically rather than requiring the address of printf to be "baked in".
This in turn allows cached versions of the JIT'd code (e.g. compiled objects)
to be re-used across JIT sessions as the JIT'd code no longer changes, only the
absolute symbol definition does.

For process and library symbols the DynamicLibrarySearchGenerator utility (See
:ref:`How to Add Process and Library Symbols to JITDylibs
<ProcessAndLibrarySymbols>`) can be used to automatically build absolute
symbol mappings for you. However the absoluteSymbols function is still useful
for making non-global objects in your JIT visible to JIT'd code. For example,
imagine that your JIT standard library needs access to your JIT object to make
some calls. We could bake the address of your object into the library, but then
it would need to be recompiled for each session:

.. code-block: c++

  // From standard library for JIT'd code:

  class MyJIT {
  public:
    void log(const char *Msg);
  };

  void log(const char *Msg) { ((MyJIT*)0x1234)->log(Msg); }

We can turn this into a symbolic reference in the JIT standard library:

.. code-block: c++

  extern MyJIT *__MyJITInstance;

  void log(const char *Msg) { __MyJITInstance->log(Msg); }

And then make our JIT object visible to the JIT standard library with an
absolute symbol definition when the JIT is started:

.. code-block: c++

  MyJIT J = ...;

  auto &JITStdLibJD = ... ;

  JITStdLibJD.define(absoluteSymbols(SymbolMap({
      { Mangle("__MyJITInstance"),
        { pointerToJITTargetAddress(&J), JITSymbolFlags() } }
    });

Aliases and Reexports
---------------------

Aliases and reexports allow you to define new symbols that map to existing
symbols. This can be useful for changing linkage relationships between symbols
across sessions without having to recompile code. For example, imagine that
JIT'd code has access to a log function, ``void log(const char*)`` for which
there are two implementations in the JIT standard library: ``log_fast`` and
``log_detailed``. Your JIT can choose which one of these definitions will be
used when the ``log`` symbol is referenced by setting up an alias at JIT startup
time:

.. code-block: c++

  auto &JITStdLibJD = ... ;

  auto LogImplementationSymbol =
   Verbose ? Mangle("log_detailed") : Mangle("log_fast");

  JITStdLibJD.define(
    symbolAliases(SymbolAliasMap({
        { Mangle("log"),
          { LogImplementationSymbol
            JITSymbolFlags::Exported | JITSymbolFlags::Callable } }
      });

The ``symbolAliases`` function allows you to define aliases within a single
JITDylib. The ``reexports`` function provides the same functionality, but
operates across JITDylib boundaries. E.g.

.. code-block: c++

  auto &JD1 = ... ;
  auto &JD2 = ... ;

  // Make 'bar' in JD2 an alias for 'foo' from JD1.
  JD2.define(
    reexports(JD1, SymbolAliasMap({
        { Mangle("bar"), { Mangle("foo"), JITSymbolFlags::Exported } }
      });

The reexports utility can be handy for composing a single JITDylib interface by
re-exporting symbols from several other JITDylibs.

.. _Laziness:

Laziness
========

Laziness in ORC is provided by a utility called "lazy reexports". A lazy
reexport is similar to a regular reexport or alias: It provides a new name for
an existing symbol. Unlike regular reexports however, lookups of lazy reexports
do not trigger immediate materialization of the reexported symbol. Instead, they
only trigger materialization of a function stub. This function stub is
initialized to point at a *lazy call-through*, which provides reentry into the
JIT. If the stub is called at runtime then the lazy call-through will look up
the reexported symbol (triggering materialization for it if necessary), update
the stub (to call directly to the reexported symbol on subsequent calls), and
then return via the reexported symbol. By re-using the existing symbol lookup
mechanism, lazy reexports inherit the same concurrency guarantees: calls to lazy
reexports can be made from multiple threads concurrently, and the reexported
symbol can be any state of compilation (uncompiled, already in the process of
being compiled, or already compiled) and the call will succeed. This allows
laziness to be safely mixed with features like remote compilation, concurrent
compilation, concurrent JIT'd code, and speculative compilation.

There is one other key difference between regular reexports and lazy reexports
that some clients must be aware of: The address of a lazy reexport will be
*different* from the address of the reexported symbol (whereas a regular
reexport is guaranteed to have the same address as the reexported symbol).
Clients who care about pointer equality will generally want to use the address
of the reexport as the canonical address of the reexported symbol. This will
allow the address to be taken without forcing materialization of the reexport.

Usage example:

If JITDylib ``JD`` contains definitions for symbols ``foo_body`` and
``bar_body``, we can create lazy entry points ``Foo`` and ``Bar`` in JITDylib
``JD2`` by calling:

.. code-block:: c++

  auto ReexportFlags = JITSymbolFlags::Exported | JITSymbolFlags::Callable;
  JD2.define(
    lazyReexports(CallThroughMgr, StubsMgr, JD,
                  SymbolAliasMap({
                    { Mangle("foo"), { Mangle("foo_body"), ReexportedFlags } },
                    { Mangle("bar"), { Mangle("bar_body"), ReexportedFlags } }
                  }));

A full example of how to use lazyReexports with the LLJIT class can be found at
``llvm/examples/OrcV2Examples/LLJITWithLazyReexports``.

Supporting Custom Compilers
===========================

TBD.

.. _transitioning_orcv1_to_orcv2:

Transitioning from ORCv1 to ORCv2
=================================

Since LLVM 7.0, new ORC development work has focused on adding support for
concurrent JIT compilation. The new APIs (including new layer interfaces and
implementations, and new utilities) that support concurrency are collectively
referred to as ORCv2, and the original, non-concurrent layers and utilities
are now referred to as ORCv1.

The majority of the ORCv1 layers and utilities were renamed with a 'Legacy'
prefix in LLVM 8.0, and have deprecation warnings attached in LLVM 9.0. In LLVM
12.0 ORCv1 will be removed entirely.

Transitioning from ORCv1 to ORCv2 should be easy for most clients. Most of the
ORCv1 layers and utilities have ORCv2 counterparts [2]_ that can be directly
substituted. However there are some design differences between ORCv1 and ORCv2
to be aware of:

  1. ORCv2 fully adopts the JIT-as-linker model that began with MCJIT. Modules
     (and other program representations, e.g. Object Files)  are no longer added
     directly to JIT classes or layers. Instead, they are added to ``JITDylib``
     instances *by* layers. The ``JITDylib`` determines *where* the definitions
     reside, the layers determine *how* the definitions will be compiled.
     Linkage relationships between ``JITDylibs`` determine how inter-module
     references are resolved, and symbol resolvers are no longer used. See the
     section `Design Overview`_ for more details.

     Unless multiple JITDylibs are needed to model linkage relationships, ORCv1
     clients should place all code in a single JITDylib.
     MCJIT clients should use LLJIT (see `LLJIT and LLLazyJIT`_), and can place
     code in LLJIT's default created main JITDylib (See
     ``LLJIT::getMainJITDylib()``).

  2. All JIT stacks now need an ``ExecutionSession`` instance. ExecutionSession
     manages the string pool, error reporting, synchronization, and symbol
     lookup.

  3. ORCv2 uses uniqued strings (``SymbolStringPtr`` instances) rather than
     string values in order to reduce memory overhead and improve lookup
     performance. See the subsection `How to manage symbol strings`_.

  4. IR layers require ThreadSafeModule instances, rather than
     std::unique_ptr<Module>s. ThreadSafeModule is a wrapper that ensures that
     Modules that use the same LLVMContext are not accessed concurrently.
     See `How to use ThreadSafeModule and ThreadSafeContext`_.

  5. Symbol lookup is no longer handled by layers. Instead, there is a
     ``lookup`` method on JITDylib that takes a list of JITDylibs to scan.

     .. code-block:: c++

       ExecutionSession ES;
       JITDylib &JD1 = ...;
       JITDylib &JD2 = ...;

       auto Sym = ES.lookup({&JD1, &JD2}, ES.intern("_main"));

  6. The removeModule/removeObject methods are replaced by
     ``ResourceTracker::remove``.
     See the subsection `How to remove code`_.

For code examples and suggestions of how to use the ORCv2 APIs, please see
the section `How-tos`_.

How-tos
=======

How to manage symbol strings
----------------------------

Symbol strings in ORC are uniqued to improve lookup performance, reduce memory
overhead, and allow symbol names to function as efficient keys. To get the
unique ``SymbolStringPtr`` for a string value, call the
``ExecutionSession::intern`` method:

  .. code-block:: c++

    ExecutionSession ES;
    /// ...
    auto MainSymbolName = ES.intern("main");

If you wish to perform lookup using the C/IR name of a symbol you will also
need to apply the platform linker-mangling before interning the string. On
Linux this mangling is a no-op, but on other platforms it usually involves
adding a prefix to the string (e.g. '_' on Darwin). The mangling scheme is
based on the DataLayout for the target. Given a DataLayout and an
ExecutionSession, you can create a MangleAndInterner function object that
will perform both jobs for you:

  .. code-block:: c++

    ExecutionSession ES;
    const DataLayout &DL = ...;
    MangleAndInterner Mangle(ES, DL);

    // ...

    // Portable IR-symbol-name lookup:
    auto Sym = ES.lookup({&MainJD}, Mangle("main"));

How to create JITDylibs and set up linkage relationships
--------------------------------------------------------

In ORC, all symbol definitions reside in JITDylibs. JITDylibs are created by
calling the ``ExecutionSession::createJITDylib`` method with a unique name:

  .. code-block:: c++

    ExecutionSession ES;
    auto &JD = ES.createJITDylib("libFoo.dylib");

The JITDylib is owned by the ``ExecutionEngine`` instance and will be freed
when it is destroyed.

How to remove code
------------------

To remove an individual module from a JITDylib it must first be added using an
explicit ``ResourceTracker``. The module can then be removed by calling
``ResourceTracker::remove``:

  .. code-block:: c++

    auto &JD = ... ;
    auto M = ... ;

    auto RT = JD.createResourceTracker();
    Layer.add(RT, std::move(M)); // Add M to JD, tracking resources with RT

    RT.remove(); // Remove M from JD.

Modules added directly to a JITDylib will be tracked by that JITDylib's default
resource tracker.

All code can be removed from a JITDylib by calling ``JITDylib::clear``. This
leaves the cleared JITDylib in an empty but usable state.

JITDylibs can be removed by calling ``ExecutionSession::removeJITDylib``. This
clears the JITDylib and then puts it into a defunct state. No further operations
can be performed on the JITDylib, and it will be destroyed as soon as the last
handle to it is released.

An example of how to use the resource management APIs can be found at
``llvm/examples/OrcV2Examples/LLJITRemovableCode``.


How to add the support for custom program representation
--------------------------------------------------------
In order to add the support for a custom program representation, a custom ``MaterializationUnit``
for the program representation, and a custom ``Layer`` are needed. The Layer will have two
operations: ``add`` and ``emit``. The ``add`` operation takes an instance of your program
representation, builds one of your custom ``MaterializationUnits`` to hold it, then adds it
to a ``JITDylib``. The emit operation takes a ``MaterializationResponsibility`` object and an
instance of your program representation and materializes it, usually by compiling it and handing
the resulting object off to an ``ObjectLinkingLayer``.

Your custom ``MaterializationUnit`` will have two operations: ``materialize`` and ``discard``. The
``materialize`` function will be called for you when any symbol provided by the unit is looked up,
and it should just call the ``emit`` function on your layer, passing in the given
``MaterializationResponsibility`` and the wrapped program representation. The ``discard`` function
will be called if some weak symbol provided by your unit is not needed (because the JIT found an
overriding definition). You can use this to drop your definition early, or just ignore it and let
the linker drops the definition later.

Here is an example of an ASTLayer:

  .. code-block:: c++

    // ... In you JIT class
    AstLayer astLayer;
    // ...


    class AstMaterializationUnit : public orc::MaterializationUnit {
    public:
      AstMaterializationUnit(AstLayer &l, Ast &ast)
      : llvm::orc::MaterializationUnit(l.getInterface(ast)), astLayer(l),
      ast(ast) {};

      llvm::StringRef getName() const override {
        return "AstMaterializationUnit";
      }

      void materialize(std::unique_ptr<orc::MaterializationResponsibility> r) override {
        astLayer.emit(std::move(r), ast);
      };

    private:
      void discard(const llvm::orc::JITDylib &jd, const llvm::orc::SymbolStringPtr &sym) override {
        llvm_unreachable("functions are not overridable");
      }


      AstLayer &astLayer;
      Ast &ast;
    };

    class AstLayer {
      llvhm::orc::IRLayer &baseLayer;
      llvhm::orc::MangleAndInterner &mangler;

    public:
      AstLayer(llvm::orc::IRLayer &baseLayer, llvm::orc::MangleAndInterner &mangler)
      : baseLayer(baseLayer), mangler(mangler){};

      llvm::Error add(llvm::orc::ResourceTrackerSP &rt, Ast &ast) {
        return rt->getJITDylib().define(std::make_unique<AstMaterializationUnit>(*this, ast), rt);
      }

      void emit(std::unique_ptr<orc::MaterializationResponsibility> mr, Ast &ast) {
        // compileAst is just function that compiles the given AST and returns
        // a `llvm::orc::ThreadSafeModule`
        baseLayer.emit(std::move(mr), compileAst(ast));
      }

      llvm::orc::MaterializationUnit::Interface getInterface(Ast &ast) {
          SymbolFlagsMap Symbols;
          // Find all the symbols in the AST and for each of them
          // add it to the Symbols map.
          Symbols[mangler(someNameFromAST)] =
            JITSymbolFlags(JITSymbolFlags::Exported | JITSymbolFlags::Callable);
          return MaterializationUnit::Interface(std::move(Symbols), nullptr);
      }
    };

Take look at the source code of `Building A JIT's Chapter 4 <tutorial/BuildingAJIT4.html>`_ for a complete example.

How to use ThreadSafeModule and ThreadSafeContext
-------------------------------------------------

ThreadSafeModule and ThreadSafeContext are wrappers around Modules and
LLVMContexts respectively. A ThreadSafeModule is a pair of a
std::unique_ptr<Module> and a (possibly shared) ThreadSafeContext value. A
ThreadSafeContext is a pair of a std::unique_ptr<LLVMContext> and a lock.
This design serves two purposes: providing a locking scheme and lifetime
management for LLVMContexts. The ThreadSafeContext may be locked to prevent
accidental concurrent access by two Modules that use the same LLVMContext.
The underlying LLVMContext is freed once all ThreadSafeContext values pointing
to it are destroyed, allowing the context memory to be reclaimed as soon as
the Modules referring to it are destroyed.

ThreadSafeContexts can be explicitly constructed from a
std::unique_ptr<LLVMContext>:

  .. code-block:: c++

    ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());

ThreadSafeModules can be constructed from a pair of a std::unique_ptr<Module>
and a ThreadSafeContext value. ThreadSafeContext values may be shared between
multiple ThreadSafeModules:

  .. code-block:: c++

    ThreadSafeModule TSM1(
      std::make_unique<Module>("M1", *TSCtx.getContext()), TSCtx);

    ThreadSafeModule TSM2(
      std::make_unique<Module>("M2", *TSCtx.getContext()), TSCtx);

Before using a ThreadSafeContext, clients should ensure that either the context
is only accessible on the current thread, or that the context is locked. In the
example above (where the context is never locked) we rely on the fact that both
``TSM1`` and ``TSM2``, and TSCtx are all created on one thread. If a context is
going to be shared between threads then it must be locked before any accessing
or creating any Modules attached to it. E.g.

  .. code-block:: c++

    ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());

    ThreadPool TP(NumThreads);
    JITStack J;

    for (auto &ModulePath : ModulePaths) {
      TP.async(
        [&]() {
          auto Lock = TSCtx.getLock();
          auto M = loadModuleOnContext(ModulePath, TSCtx.getContext());
          J.addModule(ThreadSafeModule(std::move(M), TSCtx));
        });
    }

    TP.wait();

To make exclusive access to Modules easier to manage the ThreadSafeModule class
provides a convenience function, ``withModuleDo``, that implicitly (1) locks the
associated context, (2) runs a given function object, (3) unlocks the context,
and (3) returns the result generated by the function object. E.g.

  .. code-block:: c++

    ThreadSafeModule TSM = getModule(...);

    // Dump the module:
    size_t NumFunctionsInModule =
      TSM.withModuleDo(
        [](Module &M) { // <- Context locked before entering lambda.
          return M.size();
        } // <- Context unlocked after leaving.
      );

Clients wishing to maximize possibilities for concurrent compilation will want
to create every new ThreadSafeModule on a new ThreadSafeContext. For this
reason a convenience constructor for ThreadSafeModule is provided that implicitly
constructs a new ThreadSafeContext value from a std::unique_ptr<LLVMContext>:

  .. code-block:: c++

    // Maximize concurrency opportunities by loading every module on a
    // separate context.
    for (const auto &IRPath : IRPaths) {
      auto Ctx = std::make_unique<LLVMContext>();
      auto M = std::make_unique<LLVMContext>("M", *Ctx);
      CompileLayer.add(MainJD, ThreadSafeModule(std::move(M), std::move(Ctx)));
    }

Clients who plan to run single-threaded may choose to save memory by loading
all modules on the same context:

  .. code-block:: c++

    // Save memory by using one context for all Modules:
    ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());
    for (const auto &IRPath : IRPaths) {
      ThreadSafeModule TSM(parsePath(IRPath, *TSCtx.getContext()), TSCtx);
      CompileLayer.add(MainJD, ThreadSafeModule(std::move(TSM));
    }

.. _ProcessAndLibrarySymbols:

How to Add Process and Library Symbols to JITDylibs
===================================================

JIT'd code may need to access symbols in the host program or in supporting
libraries. The best way to enable this is to reflect these symbols into your
JITDylibs so that they appear the same as any other symbol defined within the
execution session (i.e. they are findable via `ExecutionSession::lookup`, and
so visible to the JIT linker during linking).

One way to reflect external symbols is to add them manually using the
absoluteSymbols function:

  .. code-block:: c++

    const DataLayout &DL = getDataLayout();
    MangleAndInterner Mangle(ES, DL);

    auto &JD = ES.createJITDylib("main");

    JD.define(
      absoluteSymbols({
        { Mangle("puts"), pointerToJITTargetAddress(&puts)},
        { Mangle("gets"), pointerToJITTargetAddress(&getS)}
      }));

Using absoluteSymbols is reasonable if the set of symbols to be reflected is
small and fixed. On the other hand, if the set of symbols is large or variable
it may make more sense to have the definitions added for you on demand by a
*definition generator*.A definition generator is an object that can be attached
to a JITDylib, receiving a callback whenever a lookup within that JITDylib fails
to find one or more symbols. The definition generator is given a chance to
produce a definition of the missing symbol(s) before the lookup proceeds.

ORC provides the ``DynamicLibrarySearchGenerator`` utility for reflecting symbols
from the process (or a specific dynamic library) for you. For example, to reflect
the whole interface of a runtime library:

  .. code-block:: c++

    const DataLayout &DL = getDataLayout();
    auto &JD = ES.createJITDylib("main");

    if (auto DLSGOrErr =
        DynamicLibrarySearchGenerator::Load("/path/to/lib"
                                            DL.getGlobalPrefix()))
      JD.addGenerator(std::move(*DLSGOrErr);
    else
      return DLSGOrErr.takeError();

    // IR added to JD can now link against all symbols exported by the library
    // at '/path/to/lib'.
    CompileLayer.add(JD, loadModule(...));

The ``DynamicLibrarySearchGenerator`` utility can also be constructed with a
filter function to restrict the set of symbols that may be reflected. For
example, to expose an allowed set of symbols from the main process:

  .. code-block:: c++

    const DataLayout &DL = getDataLayout();
    MangleAndInterner Mangle(ES, DL);

    auto &JD = ES.createJITDylib("main");

    DenseSet<SymbolStringPtr> AllowList({
        Mangle("puts"),
        Mangle("gets")
      });

    // Use GetForCurrentProcess with a predicate function that checks the
    // allowed list.
    JD.addGenerator(cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
          DL.getGlobalPrefix(),
          [&](const SymbolStringPtr &S) { return AllowList.count(S); })));

    // IR added to JD can now link against any symbols exported by the process
    // and contained in the list.
    CompileLayer.add(JD, loadModule(...));

References to process or library symbols could also be hardcoded into your IR
or object files using the symbols' raw addresses, however symbolic resolution
using the JIT symbol tables should be preferred: it keeps the IR and objects
readable and reusable in subsequent JIT sessions. Hardcoded addresses are
difficult to read, and usually only good for one session.

Roadmap
=======

ORC is still undergoing active development. Some current and future works are
listed below.

Current Work
------------

1. **TargetProcessControl: Improvements to in-tree support for out-of-process
   execution**

   The ``TargetProcessControl`` API provides various operations on the JIT
   target process (the one which will execute the JIT'd code), including
   memory allocation, memory writes, function execution, and process queries
   (e.g. for the target triple). By targeting this API new components can be
   developed which will work equally well for in-process and out-of-process
   JITing.


2. **ORC RPC based TargetProcessControl implementation**

   An ORC RPC based implementation of the ``TargetProcessControl`` API is
   currently under development to enable easy out-of-process JITing via
   file descriptors / sockets.

3. **Core State Machine Cleanup**

   The core ORC state machine is currently implemented between JITDylib and
   ExecutionSession. Methods are slowly being moved to `ExecutionSession`. This
   will tidy up the code base, and also allow us to support asynchronous removal
   of JITDylibs (in practice deleting an associated state object in
   ExecutionSession and leaving the JITDylib instance in a defunct state until
   all references to it have been released).

Near Future Work
----------------

1. **ORC JIT Runtime Libraries**

   We need a runtime library for JIT'd code. This would include things like
   TLS registration, reentry functions, registration code for language runtimes
   (e.g. Objective C and Swift) and other JIT specific runtime code. This should
   be built in a similar manner to compiler-rt (possibly even as part of it).

2. **Remote jit_dlopen / jit_dlclose**

   To more fully mimic the environment that static programs operate in we would
   like JIT'd code to be able to "dlopen" and "dlclose" JITDylibs, running all of
   their initializers/deinitializers on the current thread. This would require
   support from the runtime library described above.

3. **Debugging support**

   ORC currently supports the GDBRegistrationListener API when using RuntimeDyld
   as the underlying JIT linker. We will need a new solution for JITLink based
   platforms.

Further Future Work
-------------------

1. **Speculative Compilation**

   ORC's support for concurrent compilation allows us to easily enable
   *speculative* JIT compilation: compilation of code that is not needed yet,
   but which we have reason to believe will be needed in the future. This can be
   used to hide compile latency and improve JIT throughput. A proof-of-concept
   example of speculative compilation with ORC has already been developed (see
   ``llvm/examples/SpeculativeJIT``). Future work on this is likely to focus on
   re-using and improving existing profiling support (currently used by PGO) to
   feed speculation decisions, as well as built-in tools to simplify use of
   speculative compilation.

.. [1] Formats/architectures vary in terms of supported features. MachO and
       ELF tend to have better support than COFF. Patches very welcome!

.. [2] The ``LazyEmittingLayer``, ``RemoteObjectClientLayer`` and
       ``RemoteObjectServerLayer`` do not have counterparts in the new
       system. In the case of ``LazyEmittingLayer`` it was simply no longer
       needed: in ORCv2, deferring compilation until symbols are looked up is
       the default. The removal of ``RemoteObjectClientLayer`` and
       ``RemoteObjectServerLayer`` means that JIT stacks can no longer be split
       across processes, however this functionality appears not to have been
       used.

.. [3] Weak definitions are currently handled correctly within dylibs, but if
       multiple dylibs provide a weak definition of a symbol then each will end
       up with its own definition (similar to how weak definitions are handled
       in Windows DLLs). This will be fixed in the future.
