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 36namespace llvm { 37namespace orc { 38 39class KaleidoscopeJIT { 40private: 41 std::unique_ptr<TargetMachine> TM; 42 const DataLayout DL; 43 ObjectLinkingLayer<> ObjectLayer; 44 IRCompileLayer<decltype(ObjectLayer)> CompileLayer; 45 46public: 47 typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle; 48 49 KaleidoscopeJIT() 50 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), 51 CompileLayer(ObjectLayer, SimpleCompiler(*TM)) { 52 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); 53 } 54 55 TargetMachine &getTargetMachine() { return *TM; } 56 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 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 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