14c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar//===------ OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution -------===// 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#include "OrcLazyJIT.h" 114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h" 120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#include "llvm/Support/Debug.h" 130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#include "llvm/Support/DynamicLibrary.h" 146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include <cstdio> 150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#include <system_error> 164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarusing namespace llvm; 184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarnamespace { 200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar enum class DumpKind { NoDump, DumpFuncsToStdOut, DumpModsToStdErr, 220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar DumpModsToDisk }; 230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar cl::opt<DumpKind> OrcDumpKind("orc-lazy-debug", 250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar cl::desc("Debug dumping for the orc-lazy JIT."), 260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar cl::init(DumpKind::NoDump), 270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar cl::values( 280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar clEnumValN(DumpKind::NoDump, "no-dump", 290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "Don't dump anything."), 300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar clEnumValN(DumpKind::DumpFuncsToStdOut, 310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "funcs-to-stdout", 320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "Dump function names to stdout."), 330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar clEnumValN(DumpKind::DumpModsToStdErr, 340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "mods-to-stderr", 350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "Dump modules to stderr."), 360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar clEnumValN(DumpKind::DumpModsToDisk, 370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "mods-to-disk", 380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "Dump modules to the current " 390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "working directory. (WARNING: " 400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar "will overwrite existing files)."), 41cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar clEnumValEnd), 42cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar cl::Hidden); 43cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 44cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar cl::opt<bool> OrcInlineStubs("orc-lazy-inline-stubs", 45cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar cl::desc("Try to inline stubs"), 46cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar cl::init(true), cl::Hidden); 470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar} 480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 49cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstd::unique_ptr<OrcLazyJIT::CompileCallbackMgr> 50cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarOrcLazyJIT::createCompileCallbackMgr(Triple T) { 514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar switch (T.getArch()) { 520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar default: return nullptr; 534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case Triple::x86_64: { 55cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64> CCMgrT; 56cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return llvm::make_unique<CCMgrT>(0); 574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 61cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarOrcLazyJIT::IndirectStubsManagerBuilder 62cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarOrcLazyJIT::createIndirectStubsMgrBuilder(Triple T) { 63cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar switch (T.getArch()) { 64cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar default: return nullptr; 65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case Triple::x86_64: 67cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return [](){ 68cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return llvm::make_unique< 69cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar orc::LocalIndirectStubsManager<orc::OrcX86_64>>(); 70cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar }; 71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 72cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 73cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarOrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { 750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar switch (OrcDumpKind) { 770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar case DumpKind::NoDump: 786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return [](std::unique_ptr<Module> M) { return M; }; 790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar case DumpKind::DumpFuncsToStdOut: 810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return [](std::unique_ptr<Module> M) { 820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printf("[ "); 830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar for (const auto &F : *M) { 850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (F.isDeclaration()) 860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar continue; 870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (F.hasName()) { 890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar std::string Name(F.getName()); 900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printf("%s ", Name.c_str()); 910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar } else 920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printf("<anon> "); 930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar } 940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printf("]\n"); 966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return M; 970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar }; 980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar case DumpKind::DumpModsToStdErr: 1000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return [](std::unique_ptr<Module> M) { 1010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar dbgs() << "----- Module Start -----\n" << *M 1020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar << "----- Module End -----\n"; 1030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return M; 1050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar }; 1060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 1070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar case DumpKind::DumpModsToDisk: 1080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return [](std::unique_ptr<Module> M) { 1090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar std::error_code EC; 1100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, 1110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar sys::fs::F_Text); 1120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (EC) { 1130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar errs() << "Couldn't open " << M->getModuleIdentifier() 1140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar << " for dumping.\nError:" << EC.message() << "\n"; 1150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar exit(1); 1160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar } 1170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar Out << *M; 1186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return M; 1190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar }; 1200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar } 1210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar llvm_unreachable("Unknown DumpKind"); 1220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar} 1230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Defined in lli.cpp. 1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarCodeGenOpt::Level getOptLevel(); 1266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 127cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 128cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainartemplate <typename PtrTy> 129cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic PtrTy fromTargetAddress(orc::TargetAddress Addr) { 130cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr)); 131cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 132cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 1334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarint llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) { 1340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // Add the program's symbols into the JIT's search space. 1350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { 1360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar errs() << "Error loading program symbols.\n"; 1370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return 1; 1380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar } 1390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 1400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // Grab a target machine and try to build a factory function for the 1410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // target-specific Orc callback manager. 1426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar EngineBuilder EB; 1436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar EB.setOptLevel(getOptLevel()); 1446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto TM = std::unique_ptr<TargetMachine>(EB.selectTarget()); 145cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto CompileCallbackMgr = 146cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar OrcLazyJIT::createCompileCallbackMgr(Triple(TM->getTargetTriple())); 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // If we couldn't build the factory function then there must not be a callback 1490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // manager for this target. Bail out. 150cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!CompileCallbackMgr) { 1510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar errs() << "No callback manager available for target '" 152cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << TM->getTargetTriple().str() << "'.\n"; 153cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return 1; 154cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 155cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 156cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto IndirectStubsMgrBuilder = 157cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar OrcLazyJIT::createIndirectStubsMgrBuilder(Triple(TM->getTargetTriple())); 158cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 159cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // If we couldn't build a stubs-manager-builder for this target then bail out. 160cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!IndirectStubsMgrBuilder) { 161cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar errs() << "No indirect stubs manager available for target '" 162cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << TM->getTargetTriple().str() << "'.\n"; 1634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 1; 1644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // Everything looks good. Build the JIT. 167cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar OrcLazyJIT J(std::move(TM), std::move(CompileCallbackMgr), 168cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar std::move(IndirectStubsMgrBuilder), 169cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar OrcInlineStubs); 1700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 1710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // Add the module, look up main and run it. 1724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto MainHandle = J.addModule(std::move(M)); 1734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto MainSym = J.findSymbolIn(MainHandle, "main"); 1744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!MainSym) { 1764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar errs() << "Could not find main function.\n"; 1774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 1; 1784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef int (*MainFnPtr)(int, char*[]); 181cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto Main = fromTargetAddress<MainFnPtr>(MainSym.getAddress()); 1824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Main(ArgC, ArgV); 1834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 184