llvm.org GIT mirror llvm / 73405ef
[BuildingAJIT] Update chapter 1 to use the ORCv2 APIs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344667 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 8 months ago
3 changed file(s) with 294 addition(s) and 386 deletion(s). Raw diff Collapse all Expand all
77 Chapter 1 Introduction
88 ======================
99
10 **Warning: This text is currently out of date due to ORC API updates.**
11
12 **The example code has been updated and can be used. The text will be updated
13 once the API churn dies down.**
10 **Warning: This tutorial is currently being updated to account for ORC API
11 changes. Only Chapter 1 is up-to-date.**
12
13 **Example code from Chapters 2 to 4 will compile and run, but has not been
14 updated**
1415
1516 Welcome to Chapter 1 of the "Building an ORC-based JIT in LLVM" tutorial. This
1617 tutorial runs through the implementation of a JIT compiler using LLVM's
1718 On-Request-Compilation (ORC) APIs. It begins with a simplified version of the
1819 KaleidoscopeJIT class used in the
1920 `Implementing a language with LLVM `_ tutorials and then
20 introduces new features like optimization, lazy compilation and remote
21 execution.
21 introduces new features like concurrent compilation, optimization, lazy
22 compilation and remote execution.
2223
2324 The goal of this tutorial is to introduce you to LLVM's ORC JIT APIs, show how
2425 these APIs interact with other parts of LLVM, and to teach you how to recombine
4445 - `Chapter #5 `_: Add process isolation by JITing code into
4546 a remote process with reduced privileges using the JIT Remote APIs.
4647
47 To provide input for our JIT we will use the Kaleidoscope REPL from
48 `Chapter 7 `_ of the "Implementing a language in LLVM tutorial",
49 with one minor modification: We will remove the FunctionPassManager from the
50 code for that chapter and replace it with optimization support in our JIT class
51 in Chapter #2.
48 To provide input for our JIT we will use a lightly modified version of the
49 Kaleidoscope REPL from `Chapter 7 `_ of the "Implementing a
50 language in LLVM tutorial".
5251
5352 Finally, a word on API generations: ORC is the 3rd generation of LLVM JIT API.
5453 It was preceded by MCJIT, and before that by the (now deleted) legacy JIT.
6261
6362 The purpose of a JIT compiler is to compile code "on-the-fly" as it is needed,
6463 rather than compiling whole programs to disk ahead of time as a traditional
65 compiler does. To support that aim our initial, bare-bones JIT API will be:
64 compiler does. To support that aim our initial, bare-bones JIT API will have
65 just two functions:
6666
6767 1. Handle addModule(Module &M) -- Make the given IR module available for
6868 execution.
69 2. JITSymbol findSymbol(const std::string &Name) -- Search for pointers to
69 2. Expected lookup() -- Search for pointers to
7070 symbols (functions or variables) that have been added to the JIT.
71 3. void removeModule(Handle H) -- Remove a module from the JIT, releasing any
72 memory that had been used for the compiled code.
7371
7472 A basic use-case for this API, executing the 'main' function from a module,
7573 will look like:
7876
7977 std::unique_ptr M = buildModule();
8078 JIT J;
81 Handle H = J.addModule(*M);
82 int (*Main)(int, char*[]) = (int(*)(int, char*[]))J.getSymbolAddress("main");
79 J.addModule(*M);
80 auto *Main = (int(*)(int, char*[]))J.lookup("main");.getAddress();
8381 int Result = Main();
84 J.removeModule(H);
8582
8683 The APIs that we build in these tutorials will all be variations on this simple
87 theme. Behind the API we will refine the implementation of the JIT to add
88 support for optimization and lazy compilation. Eventually we will extend the
89 API itself to allow higher-level program representations (e.g. ASTs) to be
90 added to the JIT.
84 theme. Behind this API we will refine the implementation of the JIT to add
85 support for concurrent compilation, optimization and lazy compilation.
86 Eventually we will extend the API itself to allow higher-level program
87 representations (e.g. ASTs) to be added to the JIT.
9188
9289 KaleidoscopeJIT
9390 ===============
9996 input for our JIT: Each time the user enters an expression the REPL will add a
10097 new IR module containing the code for that expression to the JIT. If the
10198 expression is a top-level expression like '1+1' or 'sin(x)', the REPL will also
102 use the findSymbol method of our JIT class find and execute the code for the
103 expression, and then use the removeModule method to remove the code again
104 (since there's no way to re-invoke an anonymous expression). In later chapters
105 of this tutorial we'll modify the REPL to enable new interactions with our JIT
106 class, but for now we will take this setup for granted and focus our attention on
107 the implementation of our JIT itself.
99 use the lookup method of our JIT class find and execute the code for the
100 expression. In later chapters of this tutorial we will modify the REPL to enable
101 new interactions with our JIT class, but for now we will take this setup for
102 granted and focus our attention on the implementation of our JIT itself.
108103
109104 Our KaleidoscopeJIT class is defined in the KaleidoscopeJIT.h header. After the
110105 usual include guards and #includes [2]_, we get to the definition of our class:
114109 #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
115110 #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
116111
117 #include "llvm/ADT/STLExtras.h"
118 #include "llvm/ExecutionEngine/ExecutionEngine.h"
112 #include "llvm/ADT/StringRef.h"
119113 #include "llvm/ExecutionEngine/JITSymbol.h"
120 #include "llvm/ExecutionEngine/RTDyldMemoryManager.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"
121120 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
122 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
123 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
124 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
125 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
126121 #include "llvm/IR/DataLayout.h"
127 #include "llvm/IR/Mangler.h"
128 #include "llvm/Support/DynamicLibrary.h"
129 #include "llvm/Support/raw_ostream.h"
130 #include "llvm/Target/TargetMachine.h"
131 #include
122 #include "llvm/IR/LLVMContext.h"
132123 #include
133 #include
134 #include
135124
136125 namespace llvm {
137126 namespace orc {
138127
139128 class KaleidoscopeJIT {
140129 private:
141 std::unique_ptr TM;
142 const DataLayout DL;
143 RTDyldObjectLinkingLayer ObjectLayer;
144 IRCompileLayer CompileLayer;
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()};
138
139 static JITTargetMachineBuilder getJTMB() {
140 return cantFail(JITTargetMachineBuilder::detectHost());
141 }
142
143 static std::unique_ptr getMemoryMgr(VModuleKey) {
144 return llvm::make_unique();
145 }
146
147 We begin with the ExecutionSession member, ``ES``, which provides context for
148 our running JIT'd code. It holds the string pool for symbol names, the global
149 mutex that guards the critical sections of JIT operations, error logging
150 facilities, and other utilities. For basic use cases such as this, a default
151 constructed ExecutionSession is all we will need. We will investigate more
152 advanced uses of ExecutionSession in later chapters. Following our
153 ExecutionSession we have two ORC *layers*: an RTDyldObjectLinkingLayer and an
154 IRCompileLayer. We will be talking more about layers in the next chapter, but
155 for now you can think of them as analogous to LLVM Passes: they wrap up useful
156 JIT utilities behind an easy to compose interface. The first layer, ObjectLayer,
157 is the foundation of our JIT: it takes in-memory object files produced by a
158 compiler and links them on the fly to make them executable. This
159 JIT-on-top-of-a-linker design was introduced in MCJIT, however the linker was
160 hidden inside the MCJIT class. In ORC we expose the linker so that clients can
161 access and configure it directly if they need to. In this tutorial our
162 ObjectLayer will just be used to support the next layer in our stack: the
163 CompileLayer, which will be responsible for taking LLVM IR, compiling it, and
164 passing the resulting in-memory object files down to the object linking layer
165 below. Our ObjectLayer is constructed with a reference to the ExecutionSession
166 and the getMemoryMgr utility function, which it uses to generate a new memory
167 manager for each object file as it is added. Next up is our CompileLayer, which
168 is initialized with a reference to the ExecutionSession, a reference to the
169 ObjectLayer (where it will send the objects produced by the compiler), and an IR
170 compiler instance. In this case we are using the ConcurrentIRCompiler class
171 which is constructed with a JITTargetMachineBuilder and can be called to compile
172 IR concurrently from several threads (though in this chapter we will only use
173 one).
174
175 Following the ExecutionSession and layers we have three supporting member
176 variables. The DataLayout, ``DL``; and MangleAndInterner, ``Mangle`` members are
177 used to support portable lookups based on IR symbol names (more on that when we
178 get to our ``lookup`` function below), and the ThreadSafeContext member,
179 ``Ctx``, manages an LLVMContext that can be used while building IR Modules for
180 the JIT.
181
182 After that, we have two static utility functions. The ``getJTMB()`` function
183 returns a JITTargetMachineBuilder, which is a factory for building LLVM
184 TargetMachine instances that are used by the compiler. In this first tutorial we
185 will only need one (implicitly created) TargetMachine, but in future tutorials
186 that enable concurrent compilation we will need one per thread. This is why we
187 use a target machine builder, rather than a single TargetMachine. (note: Older
188 LLVM JIT APIs that did not support concurrent compilation were constructed with
189 a single TargetMachines). The ``getMemoryMgr()`` function constructs instances
190 of RuntimeDyld::MemoryManager, and is used by the linking layer to generate a
191 new memory manager for each object file.
192
193 .. code-block:: c++
145194
146195 public:
147 using ModuleHandle = decltype(CompileLayer)::ModuleHandleT;
148
149 Our class begins with four members: A TargetMachine, TM, which will be used to
150 build our LLVM compiler instance; A DataLayout, DL, which will be used for
151 symbol mangling (more on that later), and two ORC *layers*: an
152 RTDyldObjectLinkingLayer and a CompileLayer. We'll be talking more about layers
153 in the next chapter, but for now you can think of them as analogous to LLVM
154 Passes: they wrap up useful JIT utilities behind an easy to compose interface.
155 The first layer, ObjectLayer, is the foundation of our JIT: it takes in-memory
156 object files produced by a compiler and links them on the fly to make them
157 executable. This JIT-on-top-of-a-linker design was introduced in MCJIT, however
158 the linker was hidden inside the MCJIT class. In ORC we expose the linker so
159 that clients can access and configure it directly if they need to. In this
160 tutorial our ObjectLayer will just be used to support the next layer in our
161 stack: the CompileLayer, which will be responsible for taking LLVM IR, compiling
162 it, and passing the resulting in-memory object files down to the object linking
163 layer below.
164
165 That's it for member variables, after that we have a single typedef:
166 ModuleHandle. This is the handle type that will be returned from our JIT's
167 addModule method, and can be passed to the removeModule method to remove a
168 module. The IRCompileLayer class already provides a convenient handle type
169 (IRCompileLayer::ModuleHandleT), so we just alias our ModuleHandle to this.
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
206 Next up we have our class constructor. Our members have already been
207 initialized, so the one thing that remains to do is to tweak the configuration
208 of the *JITDylib* that we will store our code in. We want to modify this dylib
209 to contain not only the symbols that we add to it, but also the symbols from
210 our REPL process as well. We do this by attaching a
211 ``DynamicLibrarySearchGenerator`` instance using the
212 ``DynamicLibrarySearchGenerator::GetForCurrentProcess`` method.
213
214 Following the constructor we have the ``getDataLayout()`` and ``getContext()``
215 methods. 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
217 IR modules.
170218
171219 .. code-block:: c++
172220
173 KaleidoscopeJIT()
174 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
175 ObjectLayer([]() { return std::make_shared(); }),
176 CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
177 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
221 void addModule(std::unique_ptr M) {
222 cantFail(CompileLayer.add(ES.getMainJITDylib(),
223 ThreadSafeModule(std::move(M), Ctx)));
178224 }
179225
180 TargetMachine &getTargetMachine() { return *TM; }
181
182 Next up we have our class constructor. We begin by initializing TM using the
183 EngineBuilder::selectTarget helper method which constructs a TargetMachine for
184 the current process. Then we use our newly created TargetMachine to initialize
185 DL, our DataLayout. After that we need to initialize our ObjectLayer. The
186 ObjectLayer requires a function object that will build a JIT memory manager for
187 each module that is added (a JIT memory manager manages memory allocations,
188 memory permissions, and registration of exception handlers for JIT'd code). For
189 this we use a lambda that returns a SectionMemoryManager, an off-the-shelf
190 utility that provides all the basic memory management functionality required for
191 this chapter. Next we initialize our CompileLayer. The CompileLayer needs two
192 things: (1) A reference to our object layer, and (2) a compiler instance to use
193 to perform the actual compilation from IR to object files. We use the
194 off-the-shelf SimpleCompiler instance for now. Finally, in the body of the
195 constructor, we call the DynamicLibrary::LoadLibraryPermanently method with a
196 nullptr argument. Normally the LoadLibraryPermanently method is called with the
197 path of a dynamic library to load, but when passed a null pointer it will 'load'
198 the host process itself, making its exported symbols available for execution.
199
200 .. code-block:: c++
201
202 ModuleHandle addModule(std::unique_ptr M) {
203 // Build our symbol resolver:
204 // Lambda 1: Look back into the JIT itself to find symbols that are part of
205 // the same "logical dylib".
206 // Lambda 2: Search for external symbols in the host process.
207 auto Resolver = createLambdaResolver(
208 [&](const std::string &Name) {
209 if (auto Sym = CompileLayer.findSymbol(Name, false))
210 return Sym;
211 return JITSymbol(nullptr);
212 },
213 [](const std::string &Name) {
214 if (auto SymAddr =
215 RTDyldMemoryManager::getSymbolAddressInProcess(Name))
216 return JITSymbol(SymAddr, JITSymbolFlags::Exported);
217 return JITSymbol(nullptr);
218 });
219
220 // Add the set to the JIT with the resolver we created above and a newly
221 // created SectionMemoryManager.
222 return cantFail(CompileLayer.addModule(std::move(M),
223 std::move(Resolver)));
226 Expected lookup(StringRef Name) {
227 return ES.lookup({&ES.getMainJITDylib()}, Mangle(Name.str()));
224228 }
225229
226230 Now we come to the first of our JIT API methods: addModule. This method is
227231 responsible for adding IR to the JIT and making it available for execution. In
228232 this initial implementation of our JIT we will make our modules "available for
229 execution" by adding them straight to the CompileLayer, which will immediately
230 compile them. In later chapters we will teach our JIT to defer compilation
231 of individual functions until they're actually called.
232
233 To add our module to the CompileLayer we need to supply both the module and a
234 symbol resolver. The symbol resolver is responsible for supplying the JIT with
235 an address for each *external symbol* in the module we are adding. External
236 symbols are any symbol not defined within the module itself, including calls to
237 functions outside the JIT and calls to functions defined in other modules that
238 have already been added to the JIT. (It may seem as though modules added to the
239 JIT should know about one another by default, but since we would still have to
240 supply a symbol resolver for references to code outside the JIT it turns out to
241 be easier to re-use this one mechanism for all symbol resolution.) This has the
242 added benefit that the user has full control over the symbol resolution
243 process. Should we search for definitions within the JIT first, then fall back
244 on external definitions? Or should we prefer external definitions where
245 available and only JIT code if we don't already have an available
246 implementation? By using a single symbol resolution scheme we are free to choose
247 whatever makes the most sense for any given use case.
248
249 Building a symbol resolver is made especially easy by the *createLambdaResolver*
250 function. This function takes two lambdas [3]_ and returns a JITSymbolResolver
251 instance. The first lambda is used as the implementation of the resolver's
252 findSymbolInLogicalDylib method, which searches for symbol definitions that
253 should be thought of as being part of the same "logical" dynamic library as this
254 Module. If you are familiar with static linking: this means that
255 findSymbolInLogicalDylib should expose symbols with common linkage and hidden
256 visibility. If all this sounds foreign you can ignore the details and just
257 remember that this is the first method that the linker will use to try to find a
258 symbol definition. If the findSymbolInLogicalDylib method returns a null result
259 then the linker will call the second symbol resolver method, called findSymbol,
260 which searches for symbols that should be thought of as external to (but
261 visibile from) the module and its logical dylib. In this tutorial we will adopt
262 the following simple scheme: All modules added to the JIT will behave as if they
263 were linked into a single, ever-growing logical dylib. To implement this our
264 first lambda (the one defining findSymbolInLogicalDylib) will just search for
265 JIT'd code by calling the CompileLayer's findSymbol method. If we don't find a
266 symbol in the JIT itself we'll fall back to our second lambda, which implements
267 findSymbol. This will use the RTDyldMemoryManager::getSymbolAddressInProcess
268 method to search for the symbol within the program itself. If we can't find a
269 symbol definition via either of these paths, the JIT will refuse to accept our
270 module, returning a "symbol not found" error.
271
272 Now that we've built our symbol resolver, we're ready to add our module to the
273 JIT. We do this by calling the CompileLayer's addModule method. The addModule
274 method returns an ``Expected``, since in more
275 advanced JIT configurations it could fail. In our basic configuration we know
276 that it will always succeed so we use the cantFail utility to assert that no
277 error occurred, and extract the handle value. Since we have already typedef'd
278 our ModuleHandle type to be the same as the CompileLayer's handle type, we can
279 return the unwrapped handle directly.
280
281 .. code-block:: c++
282
283 JITSymbol findSymbol(const std::string Name) {
284 std::string MangledName;
285 raw_string_ostream MangledNameStream(MangledName);
286 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
287 return CompileLayer.findSymbol(MangledNameStream.str(), true);
288 }
289
290 JITTargetAddress getSymbolAddress(const std::string Name) {
291 return cantFail(findSymbol(Name).getAddress());
292 }
293
294 void removeModule(ModuleHandle H) {
295 cantFail(CompileLayer.removeModule(H));
296 }
297
298 Now that we can add code to our JIT, we need a way to find the symbols we've
299 added to it. To do that we call the findSymbol method on our CompileLayer, but
300 with a twist: We have to *mangle* the name of the symbol we're searching for
301 first. The ORC JIT components use mangled symbols internally the same way a
302 static compiler and linker would, rather than using plain IR symbol names. This
303 allows JIT'd code to interoperate easily with precompiled code in the
304 application or shared libraries. The kind of mangling will depend on the
305 DataLayout, which in turn depends on the target platform. To allow us to remain
306 portable and search based on the un-mangled name, we just re-produce this
307 mangling ourselves.
308
309 Next we have a convenience function, getSymbolAddress, which returns the address
310 of a given symbol. Like CompileLayer's addModule function, JITSymbol's getAddress
311 function is allowed to fail [4]_, however we know that it will not in our simple
312 example, so we wrap it in a call to cantFail.
313
314 We now come to the last method in our JIT API: removeModule. This method is
315 responsible for destructing the MemoryManager and SymbolResolver that were
316 added with a given module, freeing any resources they were using in the
317 process. In our Kaleidoscope demo we rely on this method to remove the module
318 representing the most recent top-level expression, preventing it from being
319 treated as a duplicate definition when the next top-level expression is
320 entered. It is generally good to free any module that you know you won't need
321 to call further, just to free up the resources dedicated to it. However, you
322 don't strictly need to do this: All resources will be cleaned up when your
323 JIT class is destructed, if they haven't been freed before then. Like
324 ``CompileLayer::addModule`` and ``JITSymbol::getAddress``, removeModule may
325 fail in general but will never fail in our example, so we wrap it in a call to
326 cantFail.
233 execution" by adding them to the CompileLayer, which will it turn store the
234 Module in the main JITDylib. This process will create new symbol table entries
235 in the JITDylib for each definition in the module, and will defer compilation of
236 the module until any of its definitions is looked up. Note that this is not lazy
237 compilation: just referencing a definition, even if it is never used, will be
238 enough to trigger compilation. In later chapters we will teach our JIT to defer
239 compilation of functions until they're actually called. To add our Module we
240 must first wrap it in a ThreadSafeModule instance, which manages the lifetime of
241 the Module's LLVMContext (our Ctx member) in a thread-friendly way. In our
242 example, all modules will share the Ctx member, which will exist for the
243 duration of the JIT. Once we switch to concurrent compilation in later chapters
244 we will use a new context per module.
245
246 Our last method is ``lookup``, which allows us to look up addresses for
247 function and variable definitions added to the JIT based on their symbol names.
248 As noted above, lookup will implicitly trigger compilation for any symbol
249 that 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
251 just the main dylib), and the symbol name to search for, with a twist: We have
252 to *mangle* the name of the symbol we're searching for first. The ORC JIT
253 components use mangled symbols internally the same way a static compiler and
254 linker would, rather than using plain IR symbol names. This allows JIT'd code
255 to interoperate easily with precompiled code in the application or shared
256 libraries. The kind of mangling will depend on the DataLayout, which in turn
257 depends on the target platform. To allow us to remain portable and search based
258 on the un-mangled name, we just re-produce this mangling ourselves using our
259 ``Mangle`` member function object.
327260
328261 This brings us to the end of Chapter 1 of Building a JIT. You now have a basic
329262 but fully functioning JIT stack that you can use to take LLVM IR and make it
361294 .. [2] +-----------------------------+-----------------------------------------------+
362295 | File | Reason for inclusion |
363296 +=============================+===============================================+
364 | STLExtras.h | LLVM utilities that are useful when working |
365 | | with the STL. |
366 +-----------------------------+-----------------------------------------------+
367 | ExecutionEngine.h | Access to the EngineBuilder::selectTarget |
368 | | method. |
369 +-----------------------------+-----------------------------------------------+
370 | | Access to the |
371 | RTDyldMemoryManager.h | RTDyldMemoryManager::getSymbolAddressInProcess|
372 | | method. |
373 +-----------------------------+-----------------------------------------------+
374 | CompileUtils.h | Provides the SimpleCompiler class. |
375 +-----------------------------+-----------------------------------------------+
376 | IRCompileLayer.h | Provides the IRCompileLayer class. |
377 +-----------------------------+-----------------------------------------------+
378 | | Access the createLambdaResolver function, |
379 | LambdaResolver.h | which provides easy construction of symbol |
380 | | resolvers. |
381 +-----------------------------+-----------------------------------------------+
382 | RTDyldObjectLinkingLayer.h | Provides the RTDyldObjectLinkingLayer class. |
383 +-----------------------------+-----------------------------------------------+
384 | Mangler.h | Provides the Mangler class for platform |
385 | | specific name-mangling. |
386 +-----------------------------+-----------------------------------------------+
387 | DynamicLibrary.h | Provides the DynamicLibrary class, which |
388 | | makes symbols in the host process searchable. |
389 +-----------------------------+-----------------------------------------------+
390 | | A fast output stream class. We use the |
391 | raw_ostream.h | raw_string_ostream subclass for symbol |
392 | | mangling |
393 +-----------------------------+-----------------------------------------------+
394 | TargetMachine.h | LLVM target machine description class. |
395 +-----------------------------+-----------------------------------------------+
396
397 .. [3] Actually they don't have to be lambdas, any object with a call operator
398 will do, including plain old functions or std::functions.
399
400 .. [4] ``JITSymbol::getAddress`` will force the JIT to compile the definition of
401 the symbol if it hasn't already been compiled, and since the compilation
402 process could fail getAddress must be able to return this failure.
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 +-----------------------------+-----------------------------------------------+
1313 #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
1414 #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
1515
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ExecutionEngine/ExecutionEngine.h"
16 #include "llvm/ADT/StringRef.h"
1817 #include "llvm/ExecutionEngine/JITSymbol.h"
19 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
18 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
19 #include "llvm/ExecutionEngine/Orc/Core.h"
20 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
21 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
22 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
23 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
2024 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
21 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
22 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
23 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
24 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
2525 #include "llvm/IR/DataLayout.h"
26 #include "llvm/IR/Mangler.h"
27 #include "llvm/Support/DynamicLibrary.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Target/TargetMachine.h"
30 #include
26 #include "llvm/IR/LLVMContext.h"
3127 #include
32 #include
33 #include
3428
3529 namespace llvm {
3630 namespace orc {
3731
3832 class KaleidoscopeJIT {
3933 private:
34
4035 ExecutionSession ES;
41 std::shared_ptr Resolver;
42 std::unique_ptr TM;
43 const DataLayout DL;
44 LegacyRTDyldObjectLinkingLayer ObjectLayer;
45 LegacyIRCompileLayer CompileLayer;
36 RTDyldObjectLinkingLayer ObjectLayer{ES, getMemoryMgr};
37 IRCompileLayer CompileLayer{ES, ObjectLayer,
38 ConcurrentIRCompiler(getJTMB())};
39 DataLayout DL{cantFail(getJTMB().getDefaultDataLayoutForTarget())};
40 MangleAndInterner Mangle{ES, DL};
41 ThreadSafeContext Ctx{llvm::make_unique()};
42
43 static JITTargetMachineBuilder getJTMB() {
44 return cantFail(JITTargetMachineBuilder::detectHost());
45 }
46
47 static std::unique_ptr getMemoryMgr() {
48 return llvm::make_unique();
49 }
4650
4751 public:
48 KaleidoscopeJIT()
49 : Resolver(createLegacyLookupResolver(
50 ES,
51 [this](const std::string &Name) -> JITSymbol {
52 if (auto Sym = CompileLayer.findSymbol(Name, false))
53 return Sym;
54 else if (auto Err = Sym.takeError())
55 return std::move(Err);
56 if (auto SymAddr =
57 RTDyldMemoryManager::getSymbolAddressInProcess(Name))
58 return JITSymbol(SymAddr, JITSymbolFlags::Exported);
59 return nullptr;
60 },
61 [](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
62 TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
63 ObjectLayer(ES,
64 [this](VModuleKey) {
65 return LegacyRTDyldObjectLinkingLayer::Resources{
66 std::make_shared(), Resolver};
67 }),
68 CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
69 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
52
53 KaleidoscopeJIT() {
54 ES.getMainJITDylib().setGenerator(
55 cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(DL)));
7056 }
7157
72 TargetMachine &getTargetMachine() { return *TM; }
58 const DataLayout &getDataLayout() const { return DL; }
7359
74 VModuleKey addModule(std::unique_ptr M) {
75 // Add the module to the JIT with a new VModuleKey.
76 auto K = ES.allocateVModule();
77 cantFail(CompileLayer.addModule(K, std::move(M)));
78 return K;
60 LLVMContext &getContext() { return *Ctx.getContext(); }
61
62 void addModule(std::unique_ptr M) {
63 cantFail(CompileLayer.add(ES.getMainJITDylib(),
64 ThreadSafeModule(std::move(M), Ctx)));
7965 }
8066
81 JITSymbol findSymbol(const std::string Name) {
82 std::string MangledName;
83 raw_string_ostream MangledNameStream(MangledName);
84 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
85 return CompileLayer.findSymbol(MangledNameStream.str(), true);
86 }
87
88 JITTargetAddress getSymbolAddress(const std::string Name) {
89 return cantFail(findSymbol(Name).getAddress());
90 }
91
92 void removeModule(VModuleKey K) {
93 cantFail(CompileLayer.removeModule(K));
67 Expected lookup(StringRef Name) {
68 return ES.lookup({&ES.getMainJITDylib()}, Mangle(Name.str()));
9469 }
9570 };
9671
675675 }
676676
677677 /// toplevelexpr ::= expression
678 static std::unique_ptr ParseTopLevelExpr() {
678 static std::unique_ptr ParseTopLevelExpr(unsigned ExprCount) {
679679 if (auto E = ParseExpression()) {
680680 // Make an anonymous proto.
681 auto Proto = llvm::make_unique("__anon_expr",
681 auto Proto = llvm::make_unique(("__anon_expr" +
682 Twine(ExprCount)).str(),
682683 std::vector());
683684 return llvm::make_unique(std::move(Proto), std::move(E));
684685 }
695696 // Code Generation
696697 //===----------------------------------------------------------------------===//
697698
698 static LLVMContext TheContext;
699 static IRBuilder<> Builder(TheContext);
699 static std::unique_ptr TheJIT;
700 static LLVMContext *TheContext;
701 static std::unique_ptr> Builder;
700702 static std::unique_ptr TheModule;
701703 static std::map NamedValues;
702 static std::unique_ptr TheJIT;
703704 static std::map> FunctionProtos;
704705
705706 Value *LogErrorV(const char *Str) {
728729 const std::string &VarName) {
729730 IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
730731 TheFunction->getEntryBlock().begin());
731 return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
732 return TmpB.CreateAlloca(Type::getDoubleTy(*TheContext), nullptr, VarName);
732733 }
733734
734735 Value *NumberExprAST::codegen() {
735 return ConstantFP::get(TheContext, APFloat(Val));
736 return ConstantFP::get(*TheContext, APFloat(Val));
736737 }
737738
738739 Value *VariableExprAST::codegen() {
742743 return LogErrorV("Unknown variable name");
743744
744745 // Load the value.
745 return Builder.CreateLoad(V, Name.c_str());
746 return Builder->CreateLoad(V, Name.c_str());
746747 }
747748
748749 Value *UnaryExprAST::codegen() {
754755 if (!F)
755756 return LogErrorV("Unknown unary operator");
756757
757 return Builder.CreateCall(F, OperandV, "unop");
758 return Builder->CreateCall(F, OperandV, "unop");
758759 }
759760
760761 Value *BinaryExprAST::codegen() {
777778 if (!Variable)
778779 return LogErrorV("Unknown variable name");
779780
780 Builder.CreateStore(Val, Variable);
781 Builder->CreateStore(Val, Variable);
781782 return Val;
782783 }
783784
788789
789790 switch (Op) {
790791 case '+':
791 return Builder.CreateFAdd(L, R, "addtmp");
792 return Builder->CreateFAdd(L, R, "addtmp");
792793 case '-':
793 return Builder.CreateFSub(L, R, "subtmp");
794 return Builder->CreateFSub(L, R, "subtmp");
794795 case '*':
795 return Builder.CreateFMul(L, R, "multmp");
796 return Builder->CreateFMul(L, R, "multmp");
796797 case '<':
797 L = Builder.CreateFCmpULT(L, R, "cmptmp");
798 L = Builder->CreateFCmpULT(L, R, "cmptmp");
798799 // Convert bool 0/1 to double 0.0 or 1.0
799 return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
800 return Builder->CreateUIToFP(L, Type::getDoubleTy(*TheContext), "booltmp");
800801 default:
801802 break;
802803 }
807808 assert(F && "binary operator not found!");
808809
809810 Value *Ops[] = {L, R};
810 return Builder.CreateCall(F, Ops, "binop");
811 return Builder->CreateCall(F, Ops, "binop");
811812 }
812813
813814 Value *CallExprAST::codegen() {
827828 return nullptr;
828829 }
829830
830 return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
831 return Builder->CreateCall(CalleeF, ArgsV, "calltmp");
831832 }
832833
833834 Value *IfExprAST::codegen() {
836837 return nullptr;
837838
838839 // Convert condition to a bool by comparing equal to 0.0.
839 CondV = Builder.CreateFCmpONE(
840 CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
841
842 Function *TheFunction = Builder.GetInsertBlock()->getParent();
840 CondV = Builder->CreateFCmpONE(
841 CondV, ConstantFP::get(*TheContext, APFloat(0.0)), "ifcond");
842
843 Function *TheFunction = Builder->GetInsertBlock()->getParent();
843844
844845 // Create blocks for the then and else cases. Insert the 'then' block at the
845846 // end of the function.
846 BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
847 BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
848 BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
849
850 Builder.CreateCondBr(CondV, ThenBB, ElseBB);
847 BasicBlock *ThenBB = BasicBlock::Create(*TheContext, "then", TheFunction);
848 BasicBlock *ElseBB = BasicBlock::Create(*TheContext, "else");
849 BasicBlock *MergeBB = BasicBlock::Create(*TheContext, "ifcont");
850
851 Builder->CreateCondBr(CondV, ThenBB, ElseBB);
851852
852853 // Emit then value.
853 Builder.SetInsertPoint(ThenBB);
854 Builder->SetInsertPoint(ThenBB);
854855
855856 Value *ThenV = Then->codegen();
856857 if (!ThenV)
857858 return nullptr;
858859
859 Builder.CreateBr(MergeBB);
860 Builder->CreateBr(MergeBB);
860861 // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
861 ThenBB = Builder.GetInsertBlock();
862 ThenBB = Builder->GetInsertBlock();
862863
863864 // Emit else block.
864865 TheFunction->getBasicBlockList().push_back(ElseBB);
865 Builder.SetInsertPoint(ElseBB);
866 Builder->SetInsertPoint(ElseBB);
866867
867868 Value *ElseV = Else->codegen();
868869 if (!ElseV)
869870 return nullptr;
870871
871 Builder.CreateBr(MergeBB);
872 Builder->CreateBr(MergeBB);
872873 // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
873 ElseBB = Builder.GetInsertBlock();
874 ElseBB = Builder->GetInsertBlock();
874875
875876 // Emit merge block.
876877 TheFunction->getBasicBlockList().push_back(MergeBB);
877 Builder.SetInsertPoint(MergeBB);
878 PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
878 Builder->SetInsertPoint(MergeBB);
879 PHINode *PN = Builder->CreatePHI(Type::getDoubleTy(*TheContext), 2, "iftmp");
879880
880881 PN->addIncoming(ThenV, ThenBB);
881882 PN->addIncoming(ElseV, ElseBB);
902903 // br endcond, loop, endloop
903904 // outloop:
904905 Value *ForExprAST::codegen() {
905 Function *TheFunction = Builder.GetInsertBlock()->getParent();
906 Function *TheFunction = Builder->GetInsertBlock()->getParent();
906907
907908 // Create an alloca for the variable in the entry block.
908909 AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
913914 return nullptr;
914915
915916 // Store the value into the alloca.
916 Builder.CreateStore(StartVal, Alloca);
917 Builder->CreateStore(StartVal, Alloca);
917918
918919 // Make the new basic block for the loop header, inserting after current
919920 // block.
920 BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
921 BasicBlock *LoopBB = BasicBlock::Create(*TheContext, "loop", TheFunction);
921922
922923 // Insert an explicit fall through from the current block to the LoopBB.
923 Builder.CreateBr(LoopBB);
924 Builder->CreateBr(LoopBB);
924925
925926 // Start insertion in LoopBB.
926 Builder.SetInsertPoint(LoopBB);
927 Builder->SetInsertPoint(LoopBB);
927928
928929 // Within the loop, the variable is defined equal to the PHI node. If it
929930 // shadows an existing variable, we have to restore it, so save it now.
944945 return nullptr;
945946 } else {
946947 // If not specified, use 1.0.
947 StepVal = ConstantFP::get(TheContext, APFloat(1.0));
948 StepVal = ConstantFP::get(*TheContext, APFloat(1.0));
948949 }
949950
950951 // Compute the end condition.
954955
955956 // Reload, increment, and restore the alloca. This handles the case where
956957 // the body of the loop mutates the variable.
957 Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
958 Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
959 Builder.CreateStore(NextVar, Alloca);
958 Value *CurVar = Builder->CreateLoad(Alloca, VarName.c_str());
959 Value *NextVar = Builder->CreateFAdd(CurVar, StepVal, "nextvar");
960 Builder->CreateStore(NextVar, Alloca);
960961
961962 // Convert condition to a bool by comparing equal to 0.0.
962 EndCond = Builder.CreateFCmpONE(
963 EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
963 EndCond = Builder->CreateFCmpONE(
964 EndCond, ConstantFP::get(*TheContext, APFloat(0.0)), "loopcond");
964965
965966 // Create the "after loop" block and insert it.
966967 BasicBlock *AfterBB =
967 BasicBlock::Create(TheContext, "afterloop", TheFunction);
968 BasicBlock::Create(*TheContext, "afterloop", TheFunction);
968969
969970 // Insert the conditional branch into the end of LoopEndBB.
970 Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
971 Builder->CreateCondBr(EndCond, LoopBB, AfterBB);
971972
972973 // Any new code will be inserted in AfterBB.
973 Builder.SetInsertPoint(AfterBB);
974 Builder->SetInsertPoint(AfterBB);
974975
975976 // Restore the unshadowed variable.
976977 if (OldVal)
979980 NamedValues.erase(VarName);
980981
981982 // for expr always returns 0.0.
982 return Constant::getNullValue(Type::getDoubleTy(TheContext));
983 return Constant::getNullValue(Type::getDoubleTy(*TheContext));
983984 }
984985
985986 Value *VarExprAST::codegen() {
986987 std::vector OldBindings;
987988
988 Function *TheFunction = Builder.GetInsertBlock()->getParent();
989 Function *TheFunction = Builder->GetInsertBlock()->getParent();
989990
990991 // Register all variables and emit their initializer.
991992 for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
10031004 if (!InitVal)
10041005 return nullptr;
10051006 } else { // If not specified, use 0.0.
1006 InitVal = ConstantFP::get(TheContext, APFloat(0.0));
1007 InitVal = ConstantFP::get(*TheContext, APFloat(0.0));
10071008 }
10081009
10091010 AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
1010 Builder.CreateStore(InitVal, Alloca);
1011 Builder->CreateStore(InitVal, Alloca);
10111012
10121013 // Remember the old variable binding so that we can restore the binding when
10131014 // we unrecurse.
10321033
10331034 Function *PrototypeAST::codegen() {
10341035 // Make the function type: double(double,double) etc.
1035 std::vector Doubles(Args.size(), Type::getDoubleTy(TheContext));
1036 std::vector Doubles(Args.size(), Type::getDoubleTy(*TheContext));
10361037 FunctionType *FT =
1037 FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
1038 FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false);
10381039
10391040 Function *F =
10401041 Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
10611062 BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
10621063
10631064 // Create a new basic block to start insertion into.
1064 BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
1065 Builder.SetInsertPoint(BB);
1065 BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction);
1066 Builder->SetInsertPoint(BB);
10661067
10671068 // Record the function arguments in the NamedValues map.
10681069 NamedValues.clear();
10711072 AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
10721073
10731074 // Store the initial value into the alloca.
1074 Builder.CreateStore(&Arg, Alloca);
1075 Builder->CreateStore(&Arg, Alloca);
10751076
10761077 // Add arguments to variable symbol table.
10771078 NamedValues[Arg.getName()] = Alloca;
10791080
10801081 if (Value *RetVal = Body->codegen()) {
10811082 // Finish off the function.
1082 Builder.CreateRet(RetVal);
1083 Builder->CreateRet(RetVal);
10831084
10841085 // Validate the generated code, checking for consistency.
10851086 verifyFunction(*TheFunction);
11011102
11021103 static void InitializeModule() {
11031104 // Open a new module.
1104 TheModule = llvm::make_unique("my cool jit", TheContext);
1105 TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
1105 TheModule = llvm::make_unique("my cool jit", *TheContext);
1106 TheModule->setDataLayout(TheJIT->getDataLayout());
1107
1108 // Create a new builder for the module.
1109 Builder = llvm::make_unique>(*TheContext);
11061110 }
11071111
11081112 static void HandleDefinition() {
11351139 }
11361140
11371141 static void HandleTopLevelExpression() {
1142 static unsigned ExprCount = 0;
1143
1144 // Update ExprCount. This number will be added to anonymous expressions to
1145 // prevent them from clashing.
1146 ++ExprCount;
1147
11381148 // Evaluate a top-level expression into an anonymous function.
1139 if (auto FnAST = ParseTopLevelExpr()) {
1149 if (auto FnAST = ParseTopLevelExpr(ExprCount)) {
11401150 if (FnAST->codegen()) {
11411151 // JIT the module containing the anonymous expression, keeping a handle so
11421152 // we can free it later.
1143 auto H = TheJIT->addModule(std::move(TheModule));
1153 TheJIT->addModule(std::move(TheModule));
11441154 InitializeModule();
11451155
1146 // Get the anonymous expression's address and cast it to the right type,
1147 // double(*)(), so we can call it as a native function.
1148 double (*FP)() =
1149 (double (*)())(intptr_t)TheJIT->getSymbolAddress("__anon_expr");
1150 assert(FP && "Failed to codegen function");
1151 fprintf(stderr, "Evaluated to %f\n", FP());
1152
1153 // Delete the anonymous expression module from the JIT.
1154 TheJIT->removeModule(H);
1156 // Get the anonymous expression's JITSymbol.
1157 auto Sym = TheJIT->lookup(("__anon_expr" + Twine(ExprCount)).str());
1158
1159 if (Sym) {
1160 // If the lookup succeeded, cast the symbol's address to a function
1161 // pointer then call it.
1162 auto *FP = (double (*)())(intptr_t)Sym->getAddress();
1163 assert(FP && "Failed to codegen function");
1164 fprintf(stderr, "Evaluated to %f\n", FP());
1165 } else {
1166 // Otherwise log the reason the symbol lookup failed.
1167 logAllUnhandledErrors(Sym.takeError(), errs(),
1168 "Could not evaluate: ");
1169 }
11551170 }
11561171 } else {
11571172 // Skip token for error recovery.
12201235 getNextToken();
12211236
12221237 TheJIT = llvm::make_unique();
1238 TheContext = &TheJIT->getContext();
12231239
12241240 InitializeModule();
12251241