1=======================================================
2Building a JIT: Starting out with KaleidoscopeJIT
3=======================================================
4
5.. contents::
6   :local:
7
8Chapter 1 Introduction
9======================
10
11**Warning: This tutorial is currently being updated to account for ORC API
12changes. Only Chapter 1 is up-to-date.**
13
14**Example code from Chapters 2 to 4 will compile and run, but has not been
15updated**
16
17Welcome to Chapter 1 of the "Building an ORC-based JIT in LLVM" tutorial. This
18tutorial runs through the implementation of a JIT compiler using LLVM's
19On-Request-Compilation (ORC) APIs. It begins with a simplified version of the
20KaleidoscopeJIT class used in the
21`Implementing a language with LLVM <LangImpl01.html>`_ tutorials and then
22introduces new features like concurrent compilation, optimization, lazy
23compilation and remote execution.
24
25The goal of this tutorial is to introduce you to LLVM's ORC JIT APIs, show how
26these APIs interact with other parts of LLVM, and to teach you how to recombine
27them to build a custom JIT that is suited to your use-case.
28
29The structure of the tutorial is:
30
31- Chapter #1: Investigate the simple KaleidoscopeJIT class. This will
32  introduce some of the basic concepts of the ORC JIT APIs, including the
33  idea of an ORC *Layer*.
34
35- `Chapter #2 <BuildingAJIT2.html>`_: Extend the basic KaleidoscopeJIT by adding
36  a new layer that will optimize IR and generated code.
37
38- `Chapter #3 <BuildingAJIT3.html>`_: Further extend the JIT by adding a
39  Compile-On-Demand layer to lazily compile IR.
40
41- `Chapter #4 <BuildingAJIT4.html>`_: Improve the laziness of our JIT by
42  replacing the Compile-On-Demand layer with a custom layer that uses the ORC
43  Compile Callbacks API directly to defer IR-generation until functions are
44  called.
45
46- `Chapter #5 <BuildingAJIT5.html>`_: Add process isolation by JITing code into
47  a remote process with reduced privileges using the JIT Remote APIs.
48
49To provide input for our JIT we will use a lightly modified version of the
50Kaleidoscope REPL from `Chapter 7 <LangImpl07.html>`_ of the "Implementing a
51language in LLVM tutorial".
52
53Finally, a word on API generations: ORC is the 3rd generation of LLVM JIT API.
54It was preceded by MCJIT, and before that by the (now deleted) legacy JIT.
55These tutorials don't assume any experience with these earlier APIs, but
56readers acquainted with them will see many familiar elements. Where appropriate
57we will make this connection with the earlier APIs explicit to help people who
58are transitioning from them to ORC.
59
60JIT API Basics
61==============
62
63The purpose of a JIT compiler is to compile code "on-the-fly" as it is needed,
64rather than compiling whole programs to disk ahead of time as a traditional
65compiler does. To support that aim our initial, bare-bones JIT API will have
66just two functions:
67
681. void addModule(std::unique_ptr<Module> M) -- Make the given IR module
69   available for execution.
702. Expected<JITSymbol> lookup() -- Search for pointers to
71   symbols (functions or variables) that have been added to the JIT.
72
73A basic use-case for this API, executing the 'main' function from a module,
74will look like:
75
76.. code-block:: c++
77
78  JIT J;
79  J.addModule(buildModule());
80  auto *Main = (int(*)(int, char*[]))J.lookup("main").getAddress();
81  int Result = Main();
82
83The APIs that we build in these tutorials will all be variations on this simple
84theme. Behind this API we will refine the implementation of the JIT to add
85support for concurrent compilation, optimization and lazy compilation.
86Eventually we will extend the API itself to allow higher-level program
87representations (e.g. ASTs) to be added to the JIT.
88
89KaleidoscopeJIT
90===============
91
92In the previous section we described our API, now we examine a simple
93implementation of it: The KaleidoscopeJIT class [1]_ that was used in the
94`Implementing a language with LLVM <LangImpl01.html>`_ tutorials. We will use
95the REPL code from `Chapter 7 <LangImpl07.html>`_ of that tutorial to supply the
96input for our JIT: Each time the user enters an expression the REPL will add a
97new IR module containing the code for that expression to the JIT. If the
98expression is a top-level expression like '1+1' or 'sin(x)', the REPL will also
99use the lookup method of our JIT class find and execute the code for the
100expression. In later chapters of this tutorial we will modify the REPL to enable
101new interactions with our JIT class, but for now we will take this setup for
102granted and focus our attention on the implementation of our JIT itself.
103
104Our KaleidoscopeJIT class is defined in the KaleidoscopeJIT.h header. After the
105usual include guards and #includes [2]_, we get to the definition of our class:
106
107.. code-block:: c++
108
109  #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
110  #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
111
112  #include "llvm/ADT/StringRef.h"
113  #include "llvm/ExecutionEngine/JITSymbol.h"
114  #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
115  #include "llvm/ExecutionEngine/Orc/Core.h"
116  #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
117  #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
118  #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
119  #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
120  #include "llvm/ExecutionEngine/SectionMemoryManager.h"
121  #include "llvm/IR/DataLayout.h"
122  #include "llvm/IR/LLVMContext.h"
123  #include <memory>
124
125  namespace llvm {
126  namespace orc {
127
128  class KaleidoscopeJIT {
129  private:
130
131    ExecutionSession ES;
132    RTDyldObjectLinkingLayer ObjectLayer{ES, getMemoryMgr};
133    IRCompileLayer CompileLayer{ES, ObjectLayer,
134                                ConcurrentIRCompiler(getJTMB())};
135    DataLayout DL{cantFail(getJTMB().getDefaultDataLayoutForTarget())};
136    MangleAndInterner Mangle{ES, DL};
137    ThreadSafeContext Ctx{llvm::make_unique<LLVMContext>()};
138
139    static JITTargetMachineBuilder getJTMB() {
140      return cantFail(JITTargetMachineBuilder::detectHost());
141    }
142
143    static std::unique_ptr<SectionMemoryManager> getMemoryMgr(VModuleKey) {
144      return llvm::make_unique<SectionMemoryManager>();
145    }
146
147We begin with the ExecutionSession member, ``ES``, which provides context for
148our running JIT'd code. It holds the string pool for symbol names, the global
149mutex that guards the critical sections of JIT operations, error logging
150facilities, and other utilities. For basic use cases such as this, a default
151constructed ExecutionSession is all we will need. We will investigate more
152advanced uses of ExecutionSession in later chapters. Following our
153ExecutionSession we have two ORC *layers*: an RTDyldObjectLinkingLayer and an
154IRCompileLayer. We will be talking more about layers in the next chapter, but
155for now you can think of them as analogous to LLVM Passes: they wrap up useful
156JIT utilities behind an easy to compose interface. The first layer, ObjectLayer,
157is the foundation of our JIT: it takes in-memory object files produced by a
158compiler and links them on the fly to make them executable. This
159JIT-on-top-of-a-linker design was introduced in MCJIT, however the linker was
160hidden inside the MCJIT class. In ORC we expose the linker so that clients can
161access and configure it directly if they need to. In this tutorial our
162ObjectLayer will just be used to support the next layer in our stack: the
163CompileLayer, which will be responsible for taking LLVM IR, compiling it, and
164passing the resulting in-memory object files down to the object linking layer
165below. Our ObjectLayer is constructed with a reference to the ExecutionSession
166and the getMemoryMgr utility function, which it uses to generate a new memory
167manager for each object file as it is added. Next up is our CompileLayer, which
168is initialized with a reference to the ExecutionSession, a reference to the
169ObjectLayer (where it will send the objects produced by the compiler), and an IR
170compiler instance. In this case we are using the ConcurrentIRCompiler class
171which is constructed with a JITTargetMachineBuilder and can be called to compile
172IR concurrently from several threads (though in this chapter we will only use
173one).
174
175Following the ExecutionSession and layers we have three supporting member
176variables. The DataLayout, ``DL``; and MangleAndInterner, ``Mangle`` members are
177used to support portable lookups based on IR symbol names (more on that when we
178get to our ``lookup`` function below), and the ThreadSafeContext member,
179``Ctx``, manages an LLVMContext that can be used while building IR Modules for
180the JIT.
181
182After that, we have two static utility functions. The ``getJTMB()`` function
183returns a JITTargetMachineBuilder, which is a factory for building LLVM
184TargetMachine instances that are used by the compiler. In this first tutorial we
185will only need one (implicitly created) TargetMachine, but in future tutorials
186that enable concurrent compilation we will need one per thread. This is why we
187use a target machine builder, rather than a single TargetMachine. (note: Older
188LLVM JIT APIs that did not support concurrent compilation were constructed with
189a single TargetMachines). The ``getMemoryMgr()`` function constructs instances
190of RuntimeDyld::MemoryManager, and is used by the linking layer to generate a
191new memory manager for each object file.
192
193.. code-block:: c++
194
195  public:
196
197    KaleidoscopeJIT() {
198      ES.getMainJITDylib().setGenerator(
199        cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(DL)));
200    }
201
202    const DataLayout &getDataLayout() const { return DL; }
203
204    LLVMContext &getContext() { return *Ctx.getContext(); }
205
206Next up we have our class constructor. Our members have already been
207initialized, so the one thing that remains to do is to tweak the configuration
208of the *JITDylib* that we will store our code in. We want to modify this dylib
209to contain not only the symbols that we add to it, but also the symbols from
210our REPL process as well. We do this by attaching a
211``DynamicLibrarySearchGenerator`` instance using the
212``DynamicLibrarySearchGenerator::GetForCurrentProcess`` method.
213
214Following the constructor we have the ``getDataLayout()`` and ``getContext()``
215methods. These are used to make data structures created and managed by the JIT
216(especially the LLVMContext) available to the REPL code that will build our
217IR modules.
218
219.. code-block:: c++
220
221  void addModule(std::unique_ptr<Module> M) {
222    cantFail(CompileLayer.add(ES.getMainJITDylib(),
223                              ThreadSafeModule(std::move(M), Ctx)));
224  }
225
226  Expected<JITEvaluatedSymbol> lookup(StringRef Name) {
227    return ES.lookup({&ES.getMainJITDylib()}, Mangle(Name.str()));
228  }
229
230Now we come to the first of our JIT API methods: addModule. This method is
231responsible for adding IR to the JIT and making it available for execution. In
232this initial implementation of our JIT we will make our modules "available for
233execution" by adding them to the CompileLayer, which will it turn store the
234Module in the main JITDylib. This process will create new symbol table entries
235in the JITDylib for each definition in the module, and will defer compilation of
236the module until any of its definitions is looked up. Note that this is not lazy
237compilation: just referencing a definition, even if it is never used, will be
238enough to trigger compilation. In later chapters we will teach our JIT to defer
239compilation of functions until they're actually called.  To add our Module we
240must first wrap it in a ThreadSafeModule instance, which manages the lifetime of
241the Module's LLVMContext (our Ctx member) in a thread-friendly way. In our
242example, all modules will share the Ctx member, which will exist for the
243duration of the JIT. Once we switch to concurrent compilation in later chapters
244we will use a new context per module.
245
246Our last method is ``lookup``, which allows us to look up addresses for
247function and variable definitions added to the JIT based on their symbol names.
248As noted above, lookup will implicitly trigger compilation for any symbol
249that has not already been compiled. Our lookup method calls through to
250`ExecutionSession::lookup`, passing in a list of dylibs to search (in our case
251just the main dylib), and the symbol name to search for, with a twist: We have
252to *mangle* the name of the symbol we're searching for first. The ORC JIT
253components use mangled symbols internally the same way a static compiler and
254linker would, rather than using plain IR symbol names. This allows JIT'd code
255to interoperate easily with precompiled code in the application or shared
256libraries. The kind of mangling will depend on the DataLayout, which in turn
257depends on the target platform. To allow us to remain portable and search based
258on the un-mangled name, we just re-produce this mangling ourselves using our
259``Mangle`` member function object.
260
261This brings us to the end of Chapter 1 of Building a JIT. You now have a basic
262but fully functioning JIT stack that you can use to take LLVM IR and make it
263executable within the context of your JIT process. In the next chapter we'll
264look at how to extend this JIT to produce better quality code, and in the
265process take a deeper look at the ORC layer concept.
266
267`Next: Extending the KaleidoscopeJIT <BuildingAJIT2.html>`_
268
269Full Code Listing
270=================
271
272Here is the complete code listing for our running example. To build this
273example, use:
274
275.. code-block:: bash
276
277    # Compile
278    clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy
279    # Run
280    ./toy
281
282Here is the code:
283
284.. literalinclude:: ../../examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h
285   :language: c++
286
287.. [1] Actually we use a cut-down version of KaleidoscopeJIT that makes a
288       simplifying assumption: symbols cannot be re-defined. This will make it
289       impossible to re-define symbols in the REPL, but will make our symbol
290       lookup logic simpler. Re-introducing support for symbol redefinition is
291       left as an exercise for the reader. (The KaleidoscopeJIT.h used in the
292       original tutorials will be a helpful reference).
293
294.. [2] +-----------------------------+-----------------------------------------------+
295       |         File                |               Reason for inclusion            |
296       +=============================+===============================================+
297       |        JITSymbol.h          | Defines the lookup result type                |
298       |                             | JITEvaluatedSymbol                            |
299       +-----------------------------+-----------------------------------------------+
300       |       CompileUtils.h        | Provides the SimpleCompiler class.            |
301       +-----------------------------+-----------------------------------------------+
302       |           Core.h            | Core utilities such as ExecutionSession and   |
303       |                             | JITDylib.                                     |
304       +-----------------------------+-----------------------------------------------+
305       |      ExecutionUtils.h       | Provides the DynamicLibrarySearchGenerator    |
306       |                             | class.                                        |
307       +-----------------------------+-----------------------------------------------+
308       |      IRCompileLayer.h       | Provides the IRCompileLayer class.            |
309       +-----------------------------+-----------------------------------------------+
310       |  JITTargetMachineBuilder.h  | Provides the JITTargetMachineBuilder class.   |
311       +-----------------------------+-----------------------------------------------+
312       | RTDyldObjectLinkingLayer.h  | Provides the RTDyldObjectLinkingLayer class.  |
313       +-----------------------------+-----------------------------------------------+
314       |   SectionMemoryManager.h    | Provides the SectionMemoryManager class.      |
315       +-----------------------------+-----------------------------------------------+
316       |        DataLayout.h         | Provides the DataLayout class.                |
317       +-----------------------------+-----------------------------------------------+
318       |        LLVMContext.h        | Provides the LLVMContext class.               |
319       +-----------------------------+-----------------------------------------------+
320