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