[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