14c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar//===--- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution --*- C++ -*-===// 24c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// 34c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 44c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// 54c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 64c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 74c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// 84c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 94c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// 104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// Simple Orc-based JIT. Uses the compile-on-demand layer to break up and 114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// lazily compile modules. 124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// 134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H 164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#define LLVM_TOOLS_LLI_ORCLAZYJIT_H 174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/Triple.h" 194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" 204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/CompileUtils.h" 212c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 232c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" 244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" 254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/IR/LLVMContext.h" 284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarnamespace llvm { 304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarclass OrcLazyJIT { 324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarpublic: 334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr; 354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef orc::ObjectLinkingLayer<> ObjLayerT; 364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT; 372c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)> 382c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar TransformFtor; 392c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar typedef orc::IRTransformLayer<CompileLayerT, TransformFtor> IRDumpLayerT; 402c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar typedef orc::LazyEmittingLayer<IRDumpLayerT> LazyEmitLayerT; 414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef orc::CompileOnDemandLayer<LazyEmitLayerT, 424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileCallbackMgr> CODLayerT; 434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef CODLayerT::ModuleSetHandleT ModuleHandleT; 444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 452c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar typedef std::function< 462c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::unique_ptr<CompileCallbackMgr>(IRDumpLayerT&, 472c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar RuntimeDyld::MemoryManager&, 482c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar LLVMContext&)> 492c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CallbackManagerBuilder; 502c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 512c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar static CallbackManagerBuilder createCallbackManagerBuilder(Triple T); 522c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 532c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar OrcLazyJIT(std::unique_ptr<TargetMachine> TM, LLVMContext &Context, 542c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CallbackManagerBuilder &BuildCallbackMgr) 552c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar : TM(std::move(TM)), 564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Mang(this->TM->getDataLayout()), 572c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar ObjectLayer(), 584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), 592c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar IRDumpLayer(CompileLayer, createDebugDumper()), 602c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar LazyEmitLayer(IRDumpLayer), 612c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)), 622c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CODLayer(LazyEmitLayer, *CCMgr), 632c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {} 642c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 652c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar ~OrcLazyJIT() { 662c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Run any destructors registered with __cxa_atexit. 672c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CXXRuntimeOverrides.runDestructors(); 682c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Run any IR destructors. 692c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar for (auto &DtorRunner : IRStaticDestructorRunners) 702c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DtorRunner.runViaLayer(CODLayer); 712c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar } 724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 732c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar template <typename PtrTy> 742c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar static PtrTy fromTargetAddress(orc::TargetAddress Addr) { 752c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr)); 762c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar } 774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ModuleHandleT addModule(std::unique_ptr<Module> M) { 794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Attach a data-layout if one isn't already present. 804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (M->getDataLayout().isDefault()) 814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar M->setDataLayout(*TM->getDataLayout()); 824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 832c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Record the static constructors and destructors. We have to do this before 842c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // we hand over ownership of the module to the JIT. 852c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::vector<std::string> CtorNames, DtorNames; 862c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar for (auto Ctor : orc::getConstructors(*M)) 872c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CtorNames.push_back(mangle(Ctor.Func->getName())); 882c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar for (auto Dtor : orc::getDestructors(*M)) 892c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DtorNames.push_back(mangle(Dtor.Func->getName())); 902c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 912c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Symbol resolution order: 922c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // 1) Search the JIT symbols. 932c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // 2) Check for C++ runtime overrides. 942c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // 3) Search the host process (LLI)'s symbol table. 952c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar auto Resolver = 962c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar orc::createLambdaResolver( 972c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar [this](const std::string &Name) { 982c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 992c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar if (auto Sym = CODLayer.findSymbol(Name, true)) 1002c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags()); 1012c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1022c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) 1032c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return Sym; 1042c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1052c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) 1062c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported); 1072c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1082c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return RuntimeDyld::SymbolInfo(nullptr); 1092c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar }, 1102c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar [](const std::string &Name) { return RuntimeDyld::SymbolInfo(nullptr); } 1112c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar ); 1122c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1132c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Add the module to the JIT. 1144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::vector<std::unique_ptr<Module>> S; 1154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar S.push_back(std::move(M)); 1162c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar auto H = CODLayer.addModuleSet(std::move(S), nullptr, std::move(Resolver)); 1172c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1182c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Run the static constructors, and save the static destructor runner for 1192c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // execution when the JIT is torn down. 1202c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames), H); 1212c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar CtorRunner.runViaLayer(CODLayer); 1222c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1232c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar IRStaticDestructorRunners.push_back( 1242c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar orc::CtorDtorRunner<CODLayerT>(std::move(DtorNames), H)); 1252c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return H; 1274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar orc::JITSymbol findSymbol(const std::string &Name) { 1304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return CODLayer.findSymbol(mangle(Name), true); 1314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) { 1344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return CODLayer.findSymbolIn(H, mangle(Name), true); 1354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarprivate: 1384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::string mangle(const std::string &Name) { 1404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::string MangledName; 1414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar { 1424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar raw_string_ostream MangledNameStream(MangledName); 1434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Mang.getNameWithPrefix(MangledNameStream, Name); 1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return MangledName; 1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1482c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar static TransformFtor createDebugDumper(); 1492c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<TargetMachine> TM; 1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Mangler Mang; 1522c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar SectionMemoryManager CCMgrMemMgr; 1534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ObjLayerT ObjectLayer; 1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CompileLayerT CompileLayer; 1562c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar IRDumpLayerT IRDumpLayer; 1574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LazyEmitLayerT LazyEmitLayer; 1584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::unique_ptr<CompileCallbackMgr> CCMgr; 1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CODLayerT CODLayer; 1602c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 1612c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; 1622c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar std::vector<orc::CtorDtorRunner<CODLayerT>> IRStaticDestructorRunners; 1634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}; 1644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarint runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]); 1664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} // end namespace llvm 1684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#endif 170