diff options
Diffstat (limited to 'tools/lli')
-rw-r--r-- | tools/lli/Android.mk | 1 | ||||
-rw-r--r-- | tools/lli/CMakeLists.txt | 3 | ||||
-rw-r--r-- | tools/lli/OrcLazyJIT.cpp | 53 | ||||
-rw-r--r-- | tools/lli/OrcLazyJIT.h | 97 | ||||
-rw-r--r-- | tools/lli/RemoteMemoryManager.cpp | 1 | ||||
-rw-r--r-- | tools/lli/lli.cpp | 29 |
6 files changed, 176 insertions, 8 deletions
diff --git a/tools/lli/Android.mk b/tools/lli/Android.mk index d771e56..a67c969 100644 --- a/tools/lli/Android.mk +++ b/tools/lli/Android.mk @@ -9,6 +9,7 @@ LLVM_ROOT_PATH := $(LOCAL_PATH)/../.. lli_SRC_FILES := \ lli.cpp \ + OrcLazyJIT.cpp \ RemoteMemoryManager.cpp \ RemoteTarget.cpp \ RemoteTargetExternal.cpp \ diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt index 463c853..f98275b 100644 --- a/tools/lli/CMakeLists.txt +++ b/tools/lli/CMakeLists.txt @@ -35,8 +35,9 @@ endif( LLVM_USE_INTEL_JITEVENTS ) add_llvm_tool(lli lli.cpp + OrcLazyJIT.cpp RemoteMemoryManager.cpp RemoteTarget.cpp RemoteTargetExternal.cpp ) -set_target_properties(lli PROPERTIES ENABLE_EXPORTS 1) +export_executable_symbols(lli) diff --git a/tools/lli/OrcLazyJIT.cpp b/tools/lli/OrcLazyJIT.cpp new file mode 100644 index 0000000..4a8d3b9 --- /dev/null +++ b/tools/lli/OrcLazyJIT.cpp @@ -0,0 +1,53 @@ +//===------ 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/ExecutionEngine/Orc/OrcTargetSupport.h" + +using namespace llvm; + +std::unique_ptr<OrcLazyJIT::CompileCallbackMgr> +OrcLazyJIT::createCallbackMgr(Triple T, LLVMContext &Context) { + switch (T.getArch()) { + default: + // Flag error. + Error = true; + return nullptr; + + case Triple::x86_64: { + typedef orc::JITCompileCallbackManager<CompileLayerT, + orc::OrcX86_64> CCMgrT; + return make_unique<CCMgrT>(CompileLayer, Context, 0, 64); + } + } +} + +int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) { + OrcLazyJIT J(std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget()), + getGlobalContext()); + + if (!J.Ok()) { + errs() << "Could not construct JIT.\n"; + return 1; + } + + auto MainHandle = J.addModule(std::move(M)); + auto MainSym = J.findSymbolIn(MainHandle, "main"); + + if (!MainSym) { + errs() << "Could not find main function.\n"; + return 1; + } + + typedef int (*MainFnPtr)(int, char*[]); + auto Main = reinterpret_cast<MainFnPtr>( + static_cast<uintptr_t>(MainSym.getAddress())); + + return Main(ArgC, ArgV); +} diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h new file mode 100644 index 0000000..76e1ac6 --- /dev/null +++ b/tools/lli/OrcLazyJIT.h @@ -0,0 +1,97 @@ +//===--- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Simple Orc-based JIT. Uses the compile-on-demand layer to break up and +// lazily compile modules. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H +#define LLVM_TOOLS_LLI_ORCLAZYJIT_H + +#include "llvm/ADT/Triple.h" +#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" +#include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" +#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" +#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/IR/LLVMContext.h" + +namespace llvm { + +class OrcLazyJIT { +public: + + typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr; + typedef orc::ObjectLinkingLayer<> ObjLayerT; + typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT; + typedef orc::LazyEmittingLayer<CompileLayerT> LazyEmitLayerT; + typedef orc::CompileOnDemandLayer<LazyEmitLayerT, + CompileCallbackMgr> CODLayerT; + typedef CODLayerT::ModuleSetHandleT ModuleHandleT; + + OrcLazyJIT(std::unique_ptr<TargetMachine> TM, LLVMContext &Context) + : Error(false), TM(std::move(TM)), + Mang(this->TM->getDataLayout()), + ObjectLayer([](){ return llvm::make_unique<SectionMemoryManager>(); }), + CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), + LazyEmitLayer(CompileLayer), + CCMgr(createCallbackMgr(Triple(this->TM->getTargetTriple()), Context)), + CODLayer(LazyEmitLayer, *CCMgr) { } + + bool Ok() const { return !Error; } + + ModuleHandleT addModule(std::unique_ptr<Module> M) { + // Attach a data-layout if one isn't already present. + if (M->getDataLayout().isDefault()) + M->setDataLayout(*TM->getDataLayout()); + + std::vector<std::unique_ptr<Module>> S; + S.push_back(std::move(M)); + return CODLayer.addModuleSet(std::move(S)); + } + + orc::JITSymbol findSymbol(const std::string &Name) { + return CODLayer.findSymbol(mangle(Name), true); + } + + orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) { + return CODLayer.findSymbolIn(H, mangle(Name), true); + } + +private: + + std::unique_ptr<CompileCallbackMgr> + createCallbackMgr(Triple T, LLVMContext &Context); + + std::string mangle(const std::string &Name) { + std::string MangledName; + { + raw_string_ostream MangledNameStream(MangledName); + Mang.getNameWithPrefix(MangledNameStream, Name); + } + return MangledName; + } + + bool Error; + std::unique_ptr<TargetMachine> TM; + Mangler Mang; + + ObjLayerT ObjectLayer; + CompileLayerT CompileLayer; + LazyEmitLayerT LazyEmitLayer; + std::unique_ptr<CompileCallbackMgr> CCMgr; + CODLayerT CODLayer; +}; + +int runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]); + +} // end namespace llvm + +#endif diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp index 47da8fb..0a16210 100644 --- a/tools/lli/RemoteMemoryManager.cpp +++ b/tools/lli/RemoteMemoryManager.cpp @@ -16,6 +16,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 9c2b781..47ce2c0 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/LLVMContext.h" +#include "OrcLazyJIT.h" #include "RemoteMemoryManager.h" #include "RemoteTarget.h" #include "RemoteTargetExternal.h" @@ -42,6 +43,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Memory.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" @@ -65,6 +67,9 @@ using namespace llvm; #define DEBUG_TYPE "lli" namespace { + + enum class JITKind { MCJIT, OrcMCJITReplacement, OrcLazy }; + cl::opt<std::string> InputFile(cl::desc("<input bitcode>"), cl::Positional, cl::init("-")); @@ -75,12 +80,19 @@ namespace { cl::desc("Force interpretation: disable JIT"), cl::init(false)); - cl::opt<bool> UseOrcMCJITReplacement("use-orcmcjit", - cl::desc("Use the experimental " - "OrcMCJITReplacement as a " - "drop-in replacement for " - "MCJIT."), - cl::init(false)); + cl::opt<JITKind> UseJITKind("jit-kind", + cl::desc("Choose underlying JIT kind."), + cl::init(JITKind::MCJIT), + cl::values( + clEnumValN(JITKind::MCJIT, "mcjit", + "MCJIT"), + clEnumValN(JITKind::OrcMCJITReplacement, + "orc-mcjit", + "Orc-based MCJIT replacement"), + clEnumValN(JITKind::OrcLazy, + "orc-lazy", + "Orc-based lazy JIT."), + clEnumValEnd)); // The MCJIT supports building for a target address space separate from // the JIT compilation process. Use a forked process and a copying @@ -403,6 +415,9 @@ int main(int argc, char **argv, char * const *envp) { return 1; } + if (UseJITKind == JITKind::OrcLazy) + return runOrcLazyJIT(std::move(Owner), argc, argv); + if (EnableCacheManager) { std::string CacheName("file:"); CacheName.append(InputFile); @@ -429,7 +444,7 @@ int main(int argc, char **argv, char * const *envp) { builder.setEngineKind(ForceInterpreter ? EngineKind::Interpreter : EngineKind::JIT); - builder.setUseOrcMCJITReplacement(UseOrcMCJITReplacement); + builder.setUseOrcMCJITReplacement(UseJITKind == JITKind::OrcMCJITReplacement); // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) |