[Orc] Make CompileOnDemandLayer::findSymbol call BaseLayer::findSymbol if no
authorLang Hames <lhames@gmail.com>
Tue, 20 Oct 2015 04:35:02 +0000 (04:35 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 20 Oct 2015 04:35:02 +0000 (04:35 +0000)
symbol definition is found in the logical dylibs.

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

include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
unittests/ExecutionEngine/Orc/CMakeLists.txt
unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp [new file with mode: 0644]
unittests/ExecutionEngine/Orc/OrcTestCommon.h

index e71e66e212755ba88d3d886d72e25bf7f705ee97..78023b22353a8cb3b5779f3ed1317ac69b577794 100644 (file)
@@ -169,7 +169,7 @@ public:
          LDI != LDE; ++LDI)
       if (auto Symbol = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
         return Symbol;
-    return nullptr;
+    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
   }
 
   /// @brief Get the address of a symbol provided by this layer, or some layer
index 41088ac3a9c806e6f9a647238dc77c8ed70acbce..031eea5f5af6e1e7ea81f5b9f96a45ae963702f4 100644 (file)
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_llvm_unittest(OrcJITTests
+  CompileOnDemandLayerTest.cpp
   IndirectionUtilsTest.cpp
   GlobalMappingLayerTest.cpp
   LazyEmittingLayerTest.cpp
diff --git a/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
new file mode 100644 (file)
index 0000000..dfd21a7
--- /dev/null
@@ -0,0 +1,82 @@
+//===----- CompileOnDemandLayerTest.cpp - Unit tests for the COD layer ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcTestCommon.h"
+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::orc;
+
+namespace {
+
+class DummyCallbackManager : public orc::JITCompileCallbackManagerBase {
+public:
+  DummyCallbackManager()
+      : JITCompileCallbackManagerBase(0, 0), NextStubAddress(0),
+        UniversalCompile([]() { return 0; }) {
+  }
+
+  CompileCallbackInfo getCompileCallback(LLVMContext &Context) override {
+    return CompileCallbackInfo(++NextStubAddress, UniversalCompile);
+  }
+public:
+  TargetAddress NextStubAddress;
+  CompileFtor UniversalCompile;
+};
+
+class DummyStubsManager : public orc::IndirectStubsManagerBase {
+public:
+  std::error_code init(const StubInitsMap &StubInits) override {
+    llvm_unreachable("Not implemented");
+  }
+
+  JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override {
+    llvm_unreachable("Not implemented");
+  }
+
+  JITSymbol findPointer(StringRef Name) override {
+    llvm_unreachable("Not implemented");
+  }
+
+  std::error_code updatePointer(StringRef Name,
+                                TargetAddress NewAddr) override {
+    llvm_unreachable("Not implemented");
+  }
+};
+
+TEST(CompileOnDemandLayerTest, FindSymbol) {
+  auto MockBaseLayer =
+    createMockBaseLayer<int>(DoNothingAndReturn<int>(0),
+                             DoNothingAndReturn<void>(),
+                             [](const std::string &Name, bool) {
+                               if (Name == "foo")
+                                 return JITSymbol(1, JITSymbolFlags::Exported);
+                               return JITSymbol(nullptr);
+                             },
+                             DoNothingAndReturn<JITSymbol>(nullptr));
+
+  typedef decltype(MockBaseLayer) MockBaseLayerT;
+  DummyCallbackManager CallbackMgr;
+  auto StubsMgrBuilder =
+    []() {
+      return llvm::make_unique<DummyStubsManager>();
+    };
+
+  llvm::orc::CompileOnDemandLayer<MockBaseLayerT>
+    COD(MockBaseLayer,
+        [](Function &F) { std::set<Function*> S; S.insert(&F); return S; },
+        CallbackMgr, StubsMgrBuilder, true);
+  auto Sym = COD.findSymbol("foo", true);
+
+  EXPECT_TRUE(!!Sym)
+    << "CompileOnDemand::findSymbol should call findSymbol in the base layer.";
+}
+
+}
index 1b2859b51d094e30a1f0fa6d7e6e8c80f4d2484a..99bae55815ddd757b3386680af36602003a0fd9f 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/TypeBuilder.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
 #include <memory>
 
 namespace llvm {
@@ -60,6 +61,87 @@ namespace llvm {
     }
   };
 
+template <typename HandleT,
+          typename AddModuleSetFtor,
+          typename RemoveModuleSetFtor,
+          typename FindSymbolFtor,
+          typename FindSymbolInFtor>
+class MockBaseLayer {
+public:
+
+  typedef HandleT ModuleSetHandleT;
+
+  MockBaseLayer(AddModuleSetFtor &&AddModuleSet,
+                RemoveModuleSetFtor &&RemoveModuleSet,
+                FindSymbolFtor &&FindSymbol,
+                FindSymbolInFtor &&FindSymbolIn)
+      : AddModuleSet(AddModuleSet), RemoveModuleSet(RemoveModuleSet),
+        FindSymbol(FindSymbol), FindSymbolIn(FindSymbolIn)
+  {}
+
+  template <typename ModuleSetT, typename MemoryManagerPtrT,
+            typename SymbolResolverPtrT>
+  ModuleSetHandleT addModuleSet(ModuleSetT Ms, MemoryManagerPtrT MemMgr,
+                                SymbolResolverPtrT Resolver) {
+    return AddModuleSet(std::move(Ms), std::move(MemMgr), std::move(Resolver));
+  }
+
+  void removeModuleSet(ModuleSetHandleT H) {
+    RemoveModuleSet(H);
+  }
+
+  orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+    return FindSymbol(Name, ExportedSymbolsOnly);
+  }
+
+  orc::JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+                         bool ExportedSymbolsOnly) {
+    return FindSymbolIn(H, Name, ExportedSymbolsOnly);
+  }
+
+private:
+  AddModuleSetFtor AddModuleSet;
+  RemoveModuleSetFtor RemoveModuleSet;
+  FindSymbolFtor FindSymbol;
+  FindSymbolInFtor FindSymbolIn;
+};
+
+template <typename ModuleSetHandleT,
+          typename AddModuleSetFtor,
+          typename RemoveModuleSetFtor,
+          typename FindSymbolFtor,
+          typename FindSymbolInFtor>
+MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor,
+              FindSymbolFtor, FindSymbolInFtor>
+createMockBaseLayer(AddModuleSetFtor &&AddModuleSet,
+                    RemoveModuleSetFtor &&RemoveModuleSet,
+                    FindSymbolFtor &&FindSymbol,
+                    FindSymbolInFtor &&FindSymbolIn) {
+  return MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor,
+                       FindSymbolFtor, FindSymbolInFtor>(
+                         std::forward<AddModuleSetFtor>(AddModuleSet),
+                         std::forward<RemoveModuleSetFtor>(RemoveModuleSet),
+                         std::forward<FindSymbolFtor>(FindSymbol),
+                         std::forward<FindSymbolInFtor>(FindSymbolIn));
+}
+
+template <typename ReturnT>
+class DoNothingAndReturn {
+public:
+  DoNothingAndReturn(ReturnT Val) : Val(Val) {}
+
+  template <typename... Args>
+  ReturnT operator()(Args...) const { return Val; }
+private:
+  ReturnT Val;
+};
+
+template <>
+class DoNothingAndReturn<void> {
+public:
+  template <typename... Args>
+  void operator()(Args...) const { }
+};
 
 } // namespace llvm