Mercurial > hg > CbC > CbC_llvm
view tools/lli/OrcLazyJIT.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | 803732b1fca8 |
children |
line wrap: on
line source
//===- OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution ------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "OrcLazyJIT.h" #include "llvm/ADT/Triple.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include <cstdint> #include <cstdio> #include <cstdlib> #include <system_error> using namespace llvm; namespace { enum class DumpKind { NoDump, DumpFuncsToStdOut, DumpModsToStdOut, DumpModsToDisk }; } // end anonymous namespace static cl::opt<DumpKind> OrcDumpKind( "orc-lazy-debug", cl::desc("Debug dumping for the orc-lazy JIT."), cl::init(DumpKind::NoDump), cl::values(clEnumValN(DumpKind::NoDump, "no-dump", "Don't dump anything."), clEnumValN(DumpKind::DumpFuncsToStdOut, "funcs-to-stdout", "Dump function names to stdout."), clEnumValN(DumpKind::DumpModsToStdOut, "mods-to-stdout", "Dump modules to stdout."), clEnumValN(DumpKind::DumpModsToDisk, "mods-to-disk", "Dump modules to the current " "working directory. (WARNING: " "will overwrite existing files).")), cl::Hidden); static cl::opt<bool> OrcInlineStubs("orc-lazy-inline-stubs", cl::desc("Try to inline stubs"), cl::init(true), cl::Hidden); OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { switch (OrcDumpKind) { case DumpKind::NoDump: return [](std::shared_ptr<Module> M) { return M; }; case DumpKind::DumpFuncsToStdOut: return [](std::shared_ptr<Module> M) { printf("[ "); for (const auto &F : *M) { if (F.isDeclaration()) continue; if (F.hasName()) { std::string Name(F.getName()); printf("%s ", Name.c_str()); } else printf("<anon> "); } printf("]\n"); return M; }; case DumpKind::DumpModsToStdOut: return [](std::shared_ptr<Module> M) { outs() << "----- Module Start -----\n" << *M << "----- Module End -----\n"; return M; }; case DumpKind::DumpModsToDisk: return [](std::shared_ptr<Module> M) { std::error_code EC; raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, sys::fs::F_Text); if (EC) { errs() << "Couldn't open " << M->getModuleIdentifier() << " for dumping.\nError:" << EC.message() << "\n"; exit(1); } Out << *M; return M; }; } llvm_unreachable("Unknown DumpKind"); } // Defined in lli.cpp. CodeGenOpt::Level getOptLevel(); template <typename PtrTy> static PtrTy fromTargetAddress(JITTargetAddress Addr) { return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr)); } int llvm::runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms, const std::vector<std::string> &Args) { // Add the program's symbols into the JIT's search space. if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { errs() << "Error loading program symbols.\n"; return 1; } // Grab a target machine and try to build a factory function for the // target-specific Orc callback manager. EngineBuilder EB; EB.setOptLevel(getOptLevel()); auto TM = std::unique_ptr<TargetMachine>(EB.selectTarget()); Triple T(TM->getTargetTriple()); auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0); // If we couldn't build the factory function then there must not be a callback // manager for this target. Bail out. if (!CompileCallbackMgr) { errs() << "No callback manager available for target '" << TM->getTargetTriple().str() << "'.\n"; return 1; } auto IndirectStubsMgrBuilder = orc::createLocalIndirectStubsManagerBuilder(T); // If we couldn't build a stubs-manager-builder for this target then bail out. if (!IndirectStubsMgrBuilder) { errs() << "No indirect stubs manager available for target '" << TM->getTargetTriple().str() << "'.\n"; return 1; } // Everything looks good. Build the JIT. OrcLazyJIT J(std::move(TM), std::move(CompileCallbackMgr), std::move(IndirectStubsMgrBuilder), OrcInlineStubs); // Add the module, look up main and run it. for (auto &M : Ms) cantFail(J.addModule(std::shared_ptr<Module>(std::move(M)))); if (auto MainSym = J.findSymbol("main")) { typedef int (*MainFnPtr)(int, const char*[]); std::vector<const char *> ArgV; for (auto &Arg : Args) ArgV.push_back(Arg.c_str()); auto Main = fromTargetAddress<MainFnPtr>(cantFail(MainSym.getAddress())); return Main(ArgV.size(), (const char**)ArgV.data()); } else if (auto Err = MainSym.takeError()) logAllUnhandledErrors(std::move(Err), llvm::errs(), ""); else errs() << "Could not find main function.\n"; return 1; }