1 //===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Contains a simple JIT definition for use in the kaleidoscope tutorials. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 15 #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 16 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ExecutionEngine/ExecutionEngine.h" 19 #include "llvm/ExecutionEngine/RuntimeDyld.h" 20 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 21 #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 22 #include "llvm/ExecutionEngine/Orc/JITSymbol.h" 23 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 24 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" 25 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/IR/Mangler.h" 28 #include "llvm/Support/DynamicLibrary.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include "llvm/Target/TargetMachine.h" 31 #include <algorithm> 32 #include <memory> 33 #include <string> 34 #include <vector> 35 36 namespace llvm { 37 namespace orc { 38 39 class KaleidoscopeJIT { 40 private: 41 std::unique_ptr<TargetMachine> TM; 42 const DataLayout DL; 43 ObjectLinkingLayer<> ObjectLayer; 44 IRCompileLayer<decltype(ObjectLayer)> CompileLayer; 45 46 public: 47 typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle; 48 KaleidoscopeJIT()49 KaleidoscopeJIT() 50 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), 51 CompileLayer(ObjectLayer, SimpleCompiler(*TM)) { 52 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); 53 } 54 getTargetMachine()55 TargetMachine &getTargetMachine() { return *TM; } 56 addModule(std::unique_ptr<Module> M)57 ModuleHandle addModule(std::unique_ptr<Module> M) { 58 // Build our symbol resolver: 59 // Lambda 1: Look back into the JIT itself to find symbols that are part of 60 // the same "logical dylib". 61 // Lambda 2: Search for external symbols in the host process. 62 auto Resolver = createLambdaResolver( 63 [&](const std::string &Name) { 64 if (auto Sym = CompileLayer.findSymbol(Name, false)) 65 return Sym.toRuntimeDyldSymbol(); 66 return RuntimeDyld::SymbolInfo(nullptr); 67 }, 68 [](const std::string &Name) { 69 if (auto SymAddr = 70 RTDyldMemoryManager::getSymbolAddressInProcess(Name)) 71 return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported); 72 return RuntimeDyld::SymbolInfo(nullptr); 73 }); 74 75 // Build a singlton module set to hold our module. 76 std::vector<std::unique_ptr<Module>> Ms; 77 Ms.push_back(std::move(M)); 78 79 // Add the set to the JIT with the resolver we created above and a newly 80 // created SectionMemoryManager. 81 return CompileLayer.addModuleSet(std::move(Ms), 82 make_unique<SectionMemoryManager>(), 83 std::move(Resolver)); 84 } 85 findSymbol(const std::string Name)86 JITSymbol findSymbol(const std::string Name) { 87 std::string MangledName; 88 raw_string_ostream MangledNameStream(MangledName); 89 Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 90 return CompileLayer.findSymbol(MangledNameStream.str(), true); 91 } 92 removeModule(ModuleHandle H)93 void removeModule(ModuleHandle H) { 94 CompileLayer.removeModuleSet(H); 95 } 96 97 }; 98 99 } // end namespace orc 100 } // end namespace llvm 101 102 #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 103