1 //===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Contains a simple JIT definition for use in the kaleidoscope tutorials.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
15 #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
17 #include "llvm/ExecutionEngine/ExecutionEngine.h"
18 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
19 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
20 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
21 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
22 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
23 #include "llvm/IR/Mangler.h"
24 #include "llvm/Support/DynamicLibrary.h"
29 class KaleidoscopeJIT {
31 typedef ObjectLinkingLayer<> ObjLayerT;
32 typedef IRCompileLayer<ObjLayerT> CompileLayerT;
33 typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;
36 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
37 CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
38 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
41 TargetMachine &getTargetMachine() { return *TM; }
43 ModuleHandleT addModule(std::unique_ptr<Module> M) {
44 // We need a memory manager to allocate memory and resolve symbols for this
45 // new module. Create one that resolves symbols by looking back into the
47 auto Resolver = createLambdaResolver(
48 [&](const std::string &Name) {
49 if (auto Sym = findMangledSymbol(Name))
50 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
51 return RuntimeDyld::SymbolInfo(nullptr);
53 [](const std::string &S) { return nullptr; });
54 auto H = CompileLayer.addModuleSet(singletonSet(std::move(M)),
55 make_unique<SectionMemoryManager>(),
58 ModuleHandles.push_back(H);
62 void removeModule(ModuleHandleT H) {
64 std::find(ModuleHandles.begin(), ModuleHandles.end(), H));
65 CompileLayer.removeModuleSet(H);
68 JITSymbol findSymbol(const std::string Name) {
69 return findMangledSymbol(mangle(Name));
74 std::string mangle(const std::string &Name) {
75 std::string MangledName;
77 raw_string_ostream MangledNameStream(MangledName);
78 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
83 template <typename T> static std::vector<T> singletonSet(T t) {
85 Vec.push_back(std::move(t));
89 JITSymbol findMangledSymbol(const std::string &Name) {
90 // Search modules in reverse order: from last added to first added.
91 // This is the opposite of the usual search order for dlsym, but makes more
92 // sense in a REPL where we want to bind to the newest available definition.
93 for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend()))
94 if (auto Sym = CompileLayer.findSymbolIn(H, Name, true))
97 // If we can't find the symbol in the JIT, try looking in the host process.
98 if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
99 return JITSymbol(SymAddr, JITSymbolFlags::Exported);
104 std::unique_ptr<TargetMachine> TM;
106 ObjLayerT ObjectLayer;
107 CompileLayerT CompileLayer;
108 std::vector<ModuleHandleT> ModuleHandles;
111 } // End namespace orc.
112 } // End namespace llvm
114 #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H