[llvm] r313474 - [ORC] Hook up the LLVMOrcAddObjectFile function in the Orc C Bindings.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 16 20:25:03 PDT 2017


Author: lhames
Date: Sat Sep 16 20:25:03 2017
New Revision: 313474

URL: http://llvm.org/viewvc/llvm-project?rev=313474&view=rev
Log:
[ORC] Hook up the LLVMOrcAddObjectFile function in the Orc C Bindings.

This can be used to add a relocatable object to the JIT session.

Modified:
    llvm/trunk/include/llvm-c/OrcBindings.h
    llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindings.cpp
    llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
    llvm/trunk/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp

Modified: llvm/trunk/include/llvm-c/OrcBindings.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/OrcBindings.h?rev=313474&r1=313473&r2=313474&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/OrcBindings.h (original)
+++ llvm/trunk/include/llvm-c/OrcBindings.h Sat Sep 16 20:25:03 2017
@@ -30,7 +30,6 @@ extern "C" {
 #endif
 
 typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
-typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef;
 typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
 typedef uint32_t LLVMOrcModuleHandle;
 typedef uint64_t LLVMOrcTargetAddress;
@@ -68,18 +67,6 @@ LLVMSharedModuleRef LLVMOrcMakeSharedMod
 void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod);
 
 /**
- * Get an LLVMSharedObjectBufferRef from an LLVMMemoryBufferRef.
- */
-LLVMSharedObjectBufferRef
-LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer);
-
-/**
- * Dispose of a shared object buffer.
- */
-void
-LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer);
-
-/**
  * Create an ORC JIT stack.
  *
  * The client owns the resulting stack, and must call OrcDisposeInstance(...)
@@ -155,10 +142,15 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITSta
 
 /**
  * Add an object file.
+ *
+ * This method takes ownership of the given memory buffer and attempts to add
+ * it to the JIT as an object file.
+ * Clients should *not* dispose of the 'Obj' argument: the JIT will manage it
+ * from this call onwards.
  */
 LLVMOrcErrorCode LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
                                       LLVMOrcModuleHandle *RetHandle,
-                                      LLVMSharedObjectBufferRef Obj,
+                                      LLVMMemoryBufferRef Obj,
                                       LLVMOrcSymbolResolverFn SymbolResolver,
                                       void *SymbolResolverCtx);
 

Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindings.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindings.cpp?rev=313474&r1=313473&r2=313474&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindings.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindings.cpp Sat Sep 16 20:25:03 2017
@@ -20,16 +20,6 @@ void LLVMOrcDisposeSharedModuleRef(LLVMS
   delete unwrap(SharedMod);
 }
 
-LLVMSharedObjectBufferRef
-LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer) {
-  return wrap(new std::shared_ptr<MemoryBuffer>(unwrap(ObjBuffer)));
-}
-
-void
-LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer) {
-  delete unwrap(SharedObjBuffer);
-}
-
 LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {
   TargetMachine *TM2(unwrap(TM));
 
@@ -105,6 +95,18 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITSta
   return J.addIRModuleLazy(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
 }
 
+LLVMOrcErrorCode
+LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
+                     LLVMOrcModuleHandle *RetHandle,
+                     LLVMMemoryBufferRef Obj,
+                     LLVMOrcSymbolResolverFn SymbolResolver,
+                     void *SymbolResolverCtx) {
+  OrcCBindingsStack &J = *unwrap(JITStack);
+  std::unique_ptr<MemoryBuffer> O(unwrap(Obj));
+  return J.addObject(*RetHandle, std::move(O), SymbolResolver,
+                     SymbolResolverCtx);
+}
+
 LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
                                      LLVMOrcModuleHandle H) {
   OrcCBindingsStack &J = *unwrap(JITStack);

Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h?rev=313474&r1=313473&r2=313474&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h Sat Sep 16 20:25:03 2017
@@ -44,26 +44,12 @@ class OrcCBindingsStack;
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
                                    LLVMSharedModuleRef)
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<MemoryBuffer>,
-                                   LLVMSharedObjectBufferRef)
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
 
-class OrcCBindingsStack {
-public:
-
-  using CompileCallbackMgr = orc::JITCompileCallbackManager;
-  using ObjLayerT = orc::RTDyldObjectLinkingLayer;
-  using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
-  using CODLayerT =
-        orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
+namespace detail {
 
-  using CallbackManagerBuilder =
-      std::function<std::unique_ptr<CompileCallbackMgr>()>;
 
-  using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
-
-private:
   class GenericHandle {
   public:
     virtual ~GenericHandle() = default;
@@ -90,13 +76,56 @@ private:
     typename LayerT::ModuleHandleT Handle;
   };
 
-  template <typename LayerT>
+  template <>
+  class GenericHandleImpl<orc::RTDyldObjectLinkingLayer>
+    : public GenericHandle {
+  private:
+    using LayerT = orc::RTDyldObjectLinkingLayer;
+  public:
+
+    GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
+        : Layer(Layer), Handle(std::move(Handle)) {}
+
+    JITSymbol findSymbolIn(const std::string &Name,
+                           bool ExportedSymbolsOnly) override {
+      return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
+    }
+
+    Error removeModule() override { return Layer.removeObject(Handle); }
+
+  private:
+    LayerT &Layer;
+    typename LayerT::ObjHandleT Handle;
+  };
+
+
+  template <typename LayerT, typename HandleT>
   std::unique_ptr<GenericHandleImpl<LayerT>>
-  createGenericHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
+  createGenericHandle(LayerT &Layer, HandleT Handle) {
     return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
                                                         std::move(Handle));
   }
 
+} // end namespace detail
+
+class OrcCBindingsStack {
+public:
+
+  using CompileCallbackMgr = orc::JITCompileCallbackManager;
+  using ObjLayerT = orc::RTDyldObjectLinkingLayer;
+  using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
+  using CODLayerT =
+        orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
+
+  using CallbackManagerBuilder =
+      std::function<std::unique_ptr<CompileCallbackMgr>()>;
+
+  using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
+
+private:
+
+  using OwningObject = object::OwningBinary<object::ObjectFile>;
+
 public:
   using ModuleHandleT = unsigned;
 
@@ -266,6 +295,33 @@ public:
     return LLVMOrcErrSuccess;
   }
 
+  LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle,
+                             std::unique_ptr<MemoryBuffer> ObjBuffer,
+                             LLVMOrcSymbolResolverFn ExternalResolver,
+                             void *ExternalResolverCtx) {
+    if (auto ObjOrErr =
+        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())) {
+      auto &Obj = *ObjOrErr;
+      auto OwningObj =
+        std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
+
+      // Create the resolver.
+      auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
+
+      ModuleHandleT H;
+      if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
+                                              std::move(Resolver)))
+        H = createHandle(ObjectLayer, *HOrErr);
+      else
+        return mapError(HOrErr.takeError());
+
+      RetHandle = H;
+
+      return LLVMOrcErrSuccess;
+    } else
+      return mapError(ObjOrErr.takeError());
+  }
+
   JITSymbol findSymbol(const std::string &Name,
                                  bool ExportedSymbolsOnly) {
     if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
@@ -301,17 +357,19 @@ public:
   const std::string &getErrorMessage() const { return ErrMsg; }
 
 private:
-  template <typename LayerT>
-  unsigned createHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
+  template <typename LayerT, typename HandleT>
+  unsigned createHandle(LayerT &Layer, HandleT Handle) {
     unsigned NewHandle;
     if (!FreeHandleIndexes.empty()) {
       NewHandle = FreeHandleIndexes.back();
       FreeHandleIndexes.pop_back();
-      GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
+      GenericHandles[NewHandle] =
+        detail::createGenericHandle(Layer, std::move(Handle));
       return NewHandle;
     } else {
       NewHandle = GenericHandles.size();
-      GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
+      GenericHandles.push_back(
+        detail::createGenericHandle(Layer, std::move(Handle)));
     }
     return NewHandle;
   }
@@ -338,7 +396,7 @@ private:
   CompileLayerT CompileLayer;
   CODLayerT CODLayer;
 
-  std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
+  std::vector<std::unique_ptr<detail::GenericHandle>> GenericHandles;
   std::vector<unsigned> FreeHandleIndexes;
 
   orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp?rev=313474&r1=313473&r2=313474&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp Sat Sep 16 20:25:03 2017
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "OrcTestCommon.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
 #include "llvm-c/Core.h"
 #include "llvm-c/OrcBindings.h"
 #include "llvm-c/Target.h"
@@ -37,6 +38,15 @@ protected:
     return MB.takeModule();
   }
 
+  std::shared_ptr<object::OwningBinary<object::ObjectFile>>
+  createTestObject() {
+    orc::SimpleCompiler IRCompiler(*TM);
+    auto M = createTestModule(TM->getTargetTriple());
+    M->setDataLayout(TM->createDataLayout());
+    return std::make_shared<object::OwningBinary<object::ObjectFile>>(
+      IRCompiler(*M));
+  }
+
   typedef int (*MainFnTy)();
 
   static int myTestFuncImpl() {
@@ -124,6 +134,36 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRC
   LLVMOrcTargetAddress MainAddr;
   LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
   MainFnTy MainFn = (MainFnTy)MainAddr;
+  int Result = MainFn();
+  EXPECT_EQ(Result, 42)
+    << "Lazily JIT'd code did not return expected result";
+
+  LLVMOrcRemoveModule(JIT, H);
+
+  LLVMOrcDisposeMangledSymbol(testFuncName);
+  LLVMOrcDisposeInstance(JIT);
+}
+
+TEST_F(OrcCAPIExecutionTest, TestAddObjectFile) {
+  if (!TM)
+    return;
+
+  std::unique_ptr<MemoryBuffer> ObjBuffer;
+  {
+    auto OwningObj = createTestObject();
+    auto ObjAndBuffer = OwningObj->takeBinary();
+    ObjBuffer = std::move(ObjAndBuffer.second);
+  }
+
+  LLVMOrcJITStackRef JIT =
+    LLVMOrcCreateInstance(wrap(TM.get()));
+  LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
+
+  LLVMOrcModuleHandle H;
+  LLVMOrcAddObjectFile(JIT, &H, wrap(ObjBuffer.release()), myResolver, nullptr);
+  LLVMOrcTargetAddress MainAddr;
+  LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
+  MainFnTy MainFn = (MainFnTy)MainAddr;
   int Result = MainFn();
   EXPECT_EQ(Result, 42)
     << "Lazily JIT'd code did not return expected result";




More information about the llvm-commits mailing list