1*9880d681SAndroid Build Coastguard Worker //===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // Contains a simple JIT definition for use in the kaleidoscope tutorials. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 15*9880d681SAndroid Build Coastguard Worker #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/iterator_range.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/ExecutionEngine.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/JITSymbolFlags.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RuntimeDyld.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/SectionMemoryManager.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/JITSymbol.h" 26*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 27*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" 28*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h" 30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h" 31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DynamicLibrary.h" 32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 33*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h" 34*9880d681SAndroid Build Coastguard Worker #include <algorithm> 35*9880d681SAndroid Build Coastguard Worker #include <memory> 36*9880d681SAndroid Build Coastguard Worker #include <string> 37*9880d681SAndroid Build Coastguard Worker #include <vector> 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker namespace llvm { 40*9880d681SAndroid Build Coastguard Worker namespace orc { 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker class KaleidoscopeJIT { 43*9880d681SAndroid Build Coastguard Worker public: 44*9880d681SAndroid Build Coastguard Worker typedef ObjectLinkingLayer<> ObjLayerT; 45*9880d681SAndroid Build Coastguard Worker typedef IRCompileLayer<ObjLayerT> CompileLayerT; 46*9880d681SAndroid Build Coastguard Worker typedef CompileLayerT::ModuleSetHandleT ModuleHandleT; 47*9880d681SAndroid Build Coastguard Worker KaleidoscopeJIT()48*9880d681SAndroid Build Coastguard Worker KaleidoscopeJIT() 49*9880d681SAndroid Build Coastguard Worker : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), 50*9880d681SAndroid Build Coastguard Worker CompileLayer(ObjectLayer, SimpleCompiler(*TM)) { 51*9880d681SAndroid Build Coastguard Worker llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); 52*9880d681SAndroid Build Coastguard Worker } 53*9880d681SAndroid Build Coastguard Worker getTargetMachine()54*9880d681SAndroid Build Coastguard Worker TargetMachine &getTargetMachine() { return *TM; } 55*9880d681SAndroid Build Coastguard Worker addModule(std::unique_ptr<Module> M)56*9880d681SAndroid Build Coastguard Worker ModuleHandleT addModule(std::unique_ptr<Module> M) { 57*9880d681SAndroid Build Coastguard Worker // We need a memory manager to allocate memory and resolve symbols for this 58*9880d681SAndroid Build Coastguard Worker // new module. Create one that resolves symbols by looking back into the 59*9880d681SAndroid Build Coastguard Worker // JIT. 60*9880d681SAndroid Build Coastguard Worker auto Resolver = createLambdaResolver( 61*9880d681SAndroid Build Coastguard Worker [&](const std::string &Name) { 62*9880d681SAndroid Build Coastguard Worker if (auto Sym = findMangledSymbol(Name)) 63*9880d681SAndroid Build Coastguard Worker return Sym.toRuntimeDyldSymbol(); 64*9880d681SAndroid Build Coastguard Worker return RuntimeDyld::SymbolInfo(nullptr); 65*9880d681SAndroid Build Coastguard Worker }, 66*9880d681SAndroid Build Coastguard Worker [](const std::string &S) { return nullptr; }); 67*9880d681SAndroid Build Coastguard Worker auto H = CompileLayer.addModuleSet(singletonSet(std::move(M)), 68*9880d681SAndroid Build Coastguard Worker make_unique<SectionMemoryManager>(), 69*9880d681SAndroid Build Coastguard Worker std::move(Resolver)); 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker ModuleHandles.push_back(H); 72*9880d681SAndroid Build Coastguard Worker return H; 73*9880d681SAndroid Build Coastguard Worker } 74*9880d681SAndroid Build Coastguard Worker removeModule(ModuleHandleT H)75*9880d681SAndroid Build Coastguard Worker void removeModule(ModuleHandleT H) { 76*9880d681SAndroid Build Coastguard Worker ModuleHandles.erase( 77*9880d681SAndroid Build Coastguard Worker std::find(ModuleHandles.begin(), ModuleHandles.end(), H)); 78*9880d681SAndroid Build Coastguard Worker CompileLayer.removeModuleSet(H); 79*9880d681SAndroid Build Coastguard Worker } 80*9880d681SAndroid Build Coastguard Worker findSymbol(const std::string Name)81*9880d681SAndroid Build Coastguard Worker JITSymbol findSymbol(const std::string Name) { 82*9880d681SAndroid Build Coastguard Worker return findMangledSymbol(mangle(Name)); 83*9880d681SAndroid Build Coastguard Worker } 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker private: mangle(const std::string & Name)86*9880d681SAndroid Build Coastguard Worker std::string mangle(const std::string &Name) { 87*9880d681SAndroid Build Coastguard Worker std::string MangledName; 88*9880d681SAndroid Build Coastguard Worker { 89*9880d681SAndroid Build Coastguard Worker raw_string_ostream MangledNameStream(MangledName); 90*9880d681SAndroid Build Coastguard Worker Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 91*9880d681SAndroid Build Coastguard Worker } 92*9880d681SAndroid Build Coastguard Worker return MangledName; 93*9880d681SAndroid Build Coastguard Worker } 94*9880d681SAndroid Build Coastguard Worker singletonSet(T t)95*9880d681SAndroid Build Coastguard Worker template <typename T> static std::vector<T> singletonSet(T t) { 96*9880d681SAndroid Build Coastguard Worker std::vector<T> Vec; 97*9880d681SAndroid Build Coastguard Worker Vec.push_back(std::move(t)); 98*9880d681SAndroid Build Coastguard Worker return Vec; 99*9880d681SAndroid Build Coastguard Worker } 100*9880d681SAndroid Build Coastguard Worker findMangledSymbol(const std::string & Name)101*9880d681SAndroid Build Coastguard Worker JITSymbol findMangledSymbol(const std::string &Name) { 102*9880d681SAndroid Build Coastguard Worker // Search modules in reverse order: from last added to first added. 103*9880d681SAndroid Build Coastguard Worker // This is the opposite of the usual search order for dlsym, but makes more 104*9880d681SAndroid Build Coastguard Worker // sense in a REPL where we want to bind to the newest available definition. 105*9880d681SAndroid Build Coastguard Worker for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend())) 106*9880d681SAndroid Build Coastguard Worker if (auto Sym = CompileLayer.findSymbolIn(H, Name, true)) 107*9880d681SAndroid Build Coastguard Worker return Sym; 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker // If we can't find the symbol in the JIT, try looking in the host process. 110*9880d681SAndroid Build Coastguard Worker if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) 111*9880d681SAndroid Build Coastguard Worker return JITSymbol(SymAddr, JITSymbolFlags::Exported); 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker return nullptr; 114*9880d681SAndroid Build Coastguard Worker } 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker std::unique_ptr<TargetMachine> TM; 117*9880d681SAndroid Build Coastguard Worker const DataLayout DL; 118*9880d681SAndroid Build Coastguard Worker ObjLayerT ObjectLayer; 119*9880d681SAndroid Build Coastguard Worker CompileLayerT CompileLayer; 120*9880d681SAndroid Build Coastguard Worker std::vector<ModuleHandleT> ModuleHandles; 121*9880d681SAndroid Build Coastguard Worker }; 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker } // end namespace orc 124*9880d681SAndroid Build Coastguard Worker } // end namespace llvm 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 127