[llvm] r234805 - [Orc] Add an Orc layer for applying arbitrary transforms to IR, use it to add
Lang Hames
lhames at gmail.com
Mon Apr 13 15:12:54 PDT 2015
Author: lhames
Date: Mon Apr 13 17:12:54 2015
New Revision: 234805
URL: http://llvm.org/viewvc/llvm-project?rev=234805&view=rev
Log:
[Orc] Add an Orc layer for applying arbitrary transforms to IR, use it to add
debugging output to the LLI orc-lazy JIT, and update the orc-lazy "hello.ll"
test to actually test for lazy compilation.
Added:
llvm/trunk/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
Modified:
llvm/trunk/test/ExecutionEngine/OrcLazy/hello.ll
llvm/trunk/tools/lli/OrcLazyJIT.cpp
llvm/trunk/tools/lli/OrcLazyJIT.h
Added: llvm/trunk/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h?rev=234805&view=auto
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h (added)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h Mon Apr 13 17:12:54 2015
@@ -0,0 +1,101 @@
+//===----- IRTransformLayer.h - Run all IR through a functor ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Run all IR passed in through a user supplied functor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
+#define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
+
+#include "JITSymbol.h"
+
+namespace llvm {
+namespace orc {
+
+/// @brief IR mutating layer.
+///
+/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
+/// immediately applies the user supplied functor to each module, then adds
+/// the set of transformed modules to the layer below.
+template <typename BaseLayerT, typename TransformFtor>
+class IRTransformLayer {
+public:
+ /// @brief Handle to a set of added modules.
+ typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
+
+ /// @brief Construct an IRTransformLayer with the given BaseLayer
+ IRTransformLayer(BaseLayerT &BaseLayer,
+ TransformFtor Transform = TransformFtor())
+ : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
+
+ /// @brief Apply the transform functor to each module in the module set, then
+ /// add the resulting set of modules to the base layer, along with the
+ /// memory manager and symbol resolver.
+ ///
+ /// @return A handle for the added modules.
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
+ ModuleSetHandleT addModuleSet(ModuleSetT Ms,
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
+
+ for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I)
+ *I = Transform(std::move(*I));
+
+ return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
+ std::move(Resolver));
+ }
+
+ /// @brief Remove the module set associated with the handle H.
+ void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); }
+
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
+ }
+
+ /// @brief Get the address of the given symbol in the context of the set of
+ /// modules represented by the handle H. This call is forwarded to the
+ /// base layer's implementation.
+ /// @param H The handle for the module set to search in.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it is found in the
+ /// given module set.
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
+ }
+
+ /// @brief Immediately emit and finalize the module set represented by the
+ /// given handle.
+ /// @param H Handle for module set to emit/finalize.
+ void emitAndFinalize(ModuleSetHandleT H) {
+ BaseLayer.emitAndFinalize(H);
+ }
+
+ /// @brief Access the transform functor directly.
+ TransformFtor& getTransform() { return Transform; }
+
+ /// @brief Access the mumate functor directly.
+ const TransformFtor& getTransform() const { return Transform; }
+
+private:
+ BaseLayerT &BaseLayer;
+ TransformFtor Transform;
+};
+
+} // End namespace orc.
+} // End namespace llvm.
+
+#endif // LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
Modified: llvm/trunk/test/ExecutionEngine/OrcLazy/hello.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcLazy/hello.ll?rev=234805&r1=234804&r2=234805&view=diff
==============================================================================
--- llvm/trunk/test/ExecutionEngine/OrcLazy/hello.ll (original)
+++ llvm/trunk/test/ExecutionEngine/OrcLazy/hello.ll Mon Apr 13 17:12:54 2015
@@ -1,7 +1,8 @@
-; RUN: lli -jit-kind=orc-lazy %s | FileCheck %s
+; RUN: lli -jit-kind=orc-lazy -orc-lazy-debug=funcs-to-stderr %s | FileCheck %s
;
; CHECK: Hello
-; CHECK-NEXT: Goodbye
+; CHECK: [ main$orc_body ]
+; CHECK: Goodbye
%class.Foo = type { i8 }
Modified: llvm/trunk/tools/lli/OrcLazyJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/OrcLazyJIT.cpp?rev=234805&r1=234804&r2=234805&view=diff
==============================================================================
--- llvm/trunk/tools/lli/OrcLazyJIT.cpp (original)
+++ llvm/trunk/tools/lli/OrcLazyJIT.cpp Mon Apr 13 17:12:54 2015
@@ -9,26 +9,101 @@
#include "OrcLazyJIT.h"
#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/DynamicLibrary.h"
+#include <system_error>
using namespace llvm;
+namespace {
+
+ enum class DumpKind { NoDump, DumpFuncsToStdErr, DumpModsToStdErr,
+ DumpModsToDisk };
+
+ 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::DumpFuncsToStdErr,
+ "funcs-to-stderr",
+ "Dump function names to stderr."),
+ clEnumValN(DumpKind::DumpModsToStdErr,
+ "mods-to-stderr",
+ "Dump modules to stderr."),
+ clEnumValN(DumpKind::DumpModsToDisk,
+ "mods-to-disk",
+ "Dump modules to the current "
+ "working directory. (WARNING: "
+ "will overwrite existing files)."),
+ clEnumValEnd));
+}
+
OrcLazyJIT::CallbackManagerBuilder
OrcLazyJIT::createCallbackManagerBuilder(Triple T) {
switch (T.getArch()) {
default: return nullptr;
case Triple::x86_64: {
- typedef orc::JITCompileCallbackManager<CompileLayerT,
+ typedef orc::JITCompileCallbackManager<IRDumpLayerT,
orc::OrcX86_64> CCMgrT;
- return [](CompileLayerT &CompileLayer, RuntimeDyld::MemoryManager &MemMgr,
+ return [](IRDumpLayerT &IRDumpLayer, RuntimeDyld::MemoryManager &MemMgr,
LLVMContext &Context) {
- return make_unique<CCMgrT>(CompileLayer, MemMgr, Context, 0, 64);
+ return make_unique<CCMgrT>(IRDumpLayer, MemMgr, Context, 0, 64);
};
}
}
}
+OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() {
+
+ switch (OrcDumpKind) {
+ case DumpKind::NoDump:
+ return [](std::unique_ptr<Module> M) { return std::move(M); };
+
+ case DumpKind::DumpFuncsToStdErr:
+ return [](std::unique_ptr<Module> M) {
+ dbgs() << "[ ";
+
+ for (const auto &F : *M) {
+ if (F.isDeclaration())
+ continue;
+
+ if (F.hasName())
+ dbgs() << F.getName() << " ";
+ else
+ dbgs() << "<anon> ";
+ }
+
+ dbgs() << "]\n";
+ return std::move(M);
+ };
+
+ case DumpKind::DumpModsToStdErr:
+ return [](std::unique_ptr<Module> M) {
+ dbgs() << "----- Module Start -----\n" << *M
+ << "----- Module End -----\n";
+
+ return std::move(M);
+ };
+
+ case DumpKind::DumpModsToDisk:
+ return [](std::unique_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 std::move(M);
+ };
+ }
+}
+
int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
// Add the program's symbols into the JIT's search space.
if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
Modified: llvm/trunk/tools/lli/OrcLazyJIT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/OrcLazyJIT.h?rev=234805&r1=234804&r2=234805&view=diff
==============================================================================
--- llvm/trunk/tools/lli/OrcLazyJIT.h (original)
+++ llvm/trunk/tools/lli/OrcLazyJIT.h Mon Apr 13 17:12:54 2015
@@ -20,6 +20,7 @@
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
@@ -33,13 +34,16 @@ public:
typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
typedef orc::ObjectLinkingLayer<> ObjLayerT;
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
- typedef orc::LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
+ typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
+ TransformFtor;
+ typedef orc::IRTransformLayer<CompileLayerT, TransformFtor> IRDumpLayerT;
+ typedef orc::LazyEmittingLayer<IRDumpLayerT> LazyEmitLayerT;
typedef orc::CompileOnDemandLayer<LazyEmitLayerT,
CompileCallbackMgr> CODLayerT;
typedef CODLayerT::ModuleSetHandleT ModuleHandleT;
typedef std::function<
- std::unique_ptr<CompileCallbackMgr>(CompileLayerT&,
+ std::unique_ptr<CompileCallbackMgr>(IRDumpLayerT&,
RuntimeDyld::MemoryManager&,
LLVMContext&)>
CallbackManagerBuilder;
@@ -52,8 +56,9 @@ public:
Mang(this->TM->getDataLayout()),
ObjectLayer(),
CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
- LazyEmitLayer(CompileLayer),
- CCMgr(BuildCallbackMgr(CompileLayer, CCMgrMemMgr, Context)),
+ IRDumpLayer(CompileLayer, createDebugDumper()),
+ LazyEmitLayer(IRDumpLayer),
+ CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)),
CODLayer(LazyEmitLayer, *CCMgr),
CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
@@ -137,12 +142,15 @@ private:
return MangledName;
}
+ static TransformFtor createDebugDumper();
+
std::unique_ptr<TargetMachine> TM;
Mangler Mang;
SectionMemoryManager CCMgrMemMgr;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
+ IRDumpLayerT IRDumpLayer;
LazyEmitLayerT LazyEmitLayer;
std::unique_ptr<CompileCallbackMgr> CCMgr;
CODLayerT CODLayer;
More information about the llvm-commits
mailing list