]> granicus.if.org Git - llvm/commitdiff
[ORC] Hook up the LLVMOrcAddObjectFile function in the Orc C Bindings.
authorLang Hames <lhames@gmail.com>
Sun, 17 Sep 2017 03:25:03 +0000 (03:25 +0000)
committerLang Hames <lhames@gmail.com>
Sun, 17 Sep 2017 03:25:03 +0000 (03:25 +0000)
This can be used to add a relocatable object to the JIT session.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313474 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 7ee395431358400dcb6390335b61083ff55730fa..abb3ac6a7f03091a7d371691926428ea8ecf8f38 100644 (file)
@@ -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;
@@ -67,18 +66,6 @@ LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod);
 
 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.
  *
@@ -155,10 +142,15 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
 
 /**
  * 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);
 
index de80cb1d0dd4c4a55f3af717b15c9a6a9f94303b..f945acaf95ee68e4a532114f0289b507803dcf3a 100644 (file)
@@ -20,16 +20,6 @@ void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod) {
   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(LLVMOrcJITStackRef JITStack,
   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);
index ecb4c207b5df2cb64f08721b4f0296388928c227..405970e063d8977a423f7c7485b4cf6ca9996aa9 100644 (file)
@@ -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:
+namespace detail {
 
-  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:
   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;
index 5a4d6b4a2252b3c08c16dd4b10ca1247043c4128..d9448d47667f5d782940a3c6946ca863b3ed284a 100644 (file)
@@ -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() {
@@ -134,6 +144,36 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
   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";
+
+  LLVMOrcRemoveModule(JIT, H);
+
+  LLVMOrcDisposeMangledSymbol(testFuncName);
+  LLVMOrcDisposeInstance(JIT);
+}
+
 TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
   if (!TM)
     return;