annotate llvm/docs/tutorial/BuildingAJIT1.rst @ 207:2e18cbf3894f

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