<div dir="ltr">Hi Dave,<div><br></div><div>> <span style="font-size:13px">Will this be another useful generic thing (like the mock base layer?) that should go in a general utility header?</span></div><div><span style="font-size:13px"><br></span></div><div>Yep. The only reason the current versions haven't been moved into OrcTestCommon.h is that they're quick-and-dirty implementations to get this initial unit test going. This answer dovetails into your next question...<div><br></div><div>> <span style="font-size:13px">I think usually when mocking there would be somewhat more verification here...</span></div><br>Yes. I hope to add more tests over time, and will do so as opportunities arise.</div><div><br>- Lang.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 20, 2015 at 2:14 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Mon, Oct 19, 2015 at 9:35 PM, Lang Hames via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: lhames<br>
Date: Mon Oct 19 23:35:02 2015<br>
New Revision: 250796<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=250796&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=250796&view=rev</a><br>
Log:<br>
[Orc] Make CompileOnDemandLayer::findSymbol call BaseLayer::findSymbol if no<br>
symbol definition is found in the logical dylibs.<br>
<br>
<br>
Added:<br>
    llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp<br>
Modified:<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>
    llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
    llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=250796&r1=250795&r2=250796&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=250796&r1=250795&r2=250796&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h Mon Oct 19 23:35:02 2015<br>
@@ -169,7 +169,7 @@ public:<br>
          LDI != LDE; ++LDI)<br>
       if (auto Symbol = findSymbolIn(LDI, Name, ExportedSymbolsOnly))<br>
         return Symbol;<br>
-    return nullptr;<br>
+    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);<br>
   }<br>
<br>
   /// @brief Get the address of a symbol provided by this layer, or some layer<br>
<br>
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt?rev=250796&r1=250795&r2=250796&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt?rev=250796&r1=250795&r2=250796&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt (original)<br>
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt Mon Oct 19 23:35:02 2015<br>
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS<br>
   )<br>
<br>
 add_llvm_unittest(OrcJITTests<br>
+  CompileOnDemandLayerTest.cpp<br>
   IndirectionUtilsTest.cpp<br>
   GlobalMappingLayerTest.cpp<br>
   LazyEmittingLayerTest.cpp<br>
<br>
Added: llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp?rev=250796&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp?rev=250796&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp (added)<br>
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp Mon Oct 19 23:35:02 2015<br></blockquote><div><br></div></div></div><div>Awesome - great to see some unit testing here. The architecture's pretty ideal for it.</div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
@@ -0,0 +1,82 @@<br>
+//===----- CompileOnDemandLayerTest.cpp - Unit tests for the COD layer ----===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "OrcTestCommon.h"<br>
+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+using namespace llvm;<br>
+using namespace llvm::orc;<br>
+<br>
+namespace {<br>
+<br>
+class DummyCallbackManager : public orc::JITCompileCallbackManagerBase {<br></blockquote><div><br></div></span><div>Will this be another useful generic thing (like the mock base layer?) that should go in a general utility header?</div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+public:<br>
+  DummyCallbackManager()<br>
+      : JITCompileCallbackManagerBase(0, 0), NextStubAddress(0),<br>
+        UniversalCompile([]() { return 0; }) {<br></blockquote><div><br></div></span><div>You could initialize NextStubAddress and UniversalCompile with non-static data member initializers if you like.</div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  }<br>
+<br>
+  CompileCallbackInfo getCompileCallback(LLVMContext &Context) override {<br>
+    return CompileCallbackInfo(++NextStubAddress, UniversalCompile);<br>
+  }<br>
+public:<br>
+  TargetAddress NextStubAddress;<br>
+  CompileFtor UniversalCompile;<br>
+};<br>
+<br>
+class DummyStubsManager : public orc::IndirectStubsManagerBase {<br></blockquote><div><br></div></span><div>Another generic utility? Or I guess these might be fleshed out with functor callback implementations for other test cases.</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+public:<br>
+  std::error_code init(const StubInitsMap &StubInits) override {<br>
+    llvm_unreachable("Not implemented");<br>
+  }<br>
+<br>
+  JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override {<br>
+    llvm_unreachable("Not implemented");<br>
+  }<br>
+<br>
+  JITSymbol findPointer(StringRef Name) override {<br>
+    llvm_unreachable("Not implemented");<br>
+  }<br>
+<br>
+  std::error_code updatePointer(StringRef Name,<br>
+                                TargetAddress NewAddr) override {<br>
+    llvm_unreachable("Not implemented");<br>
+  }<br>
+};<br>
+<br>
+TEST(CompileOnDemandLayerTest, FindSymbol) {<br>
+  auto MockBaseLayer =<br>
+    createMockBaseLayer<int>(DoNothingAndReturn<int>(0),<br>
+                             DoNothingAndReturn<void>(),<br>
+                             [](const std::string &Name, bool) {<br>
+                               if (Name == "foo")<br>
+                                 return JITSymbol(1, JITSymbolFlags::Exported);<br>
+                               return JITSymbol(nullptr);<br>
+                             },<br>
+                             DoNothingAndReturn<JITSymbol>(nullptr));<br>
+<br>
+  typedef decltype(MockBaseLayer) MockBaseLayerT;<br>
+  DummyCallbackManager CallbackMgr;<br>
+  auto StubsMgrBuilder =<br>
+    []() {<br>
+      return llvm::make_unique<DummyStubsManager>();<br>
+    };<br>
+<br>
+  llvm::orc::CompileOnDemandLayer<MockBaseLayerT><br>
+    COD(MockBaseLayer,<br>
+        [](Function &F) { std::set<Function*> S; S.insert(&F); return S; },<br>
+        CallbackMgr, StubsMgrBuilder, true);<br>
+  auto Sym = COD.findSymbol("foo", true);<br>
+<br>
+  EXPECT_TRUE(!!Sym)<br>
+    << "CompileOnDemand::findSymbol should call findSymbol in the base layer.";<br></blockquote><div><br></div></div></div><div>I think usually when mocking there would be somewhat more verification here - for example checking that StubsMgrBuilder was called exactly once and the thing it returned was the thing findSymbol returned, eg:<br><br>int calls = 0;<br>DummyStubsManager *ptr = nullptr;<br>auto StubsMgrBuilder = [&]() { ++calls; auto r = make_unique<DummyStubsManager>(); ptr = r.get(); return r; };<br>...<br>EXPECT_EQ(0, calls);<br>auto Sym = findSymbol<br>EXPECT_EQ(1, calls);<br>EXPECT_EQ(ptr, Sym.get());<br><br>perhaps. Though I haven't dealt with mocking libraries very much (eg: gmock, etc) to know really well what the common idioms are. (& they have higher level ways to describe what the mock should observe)</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+}<br>
+<br>
+}<br>
<br>
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h?rev=250796&r1=250795&r2=250796&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h?rev=250796&r1=250795&r2=250796&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h (original)<br>
+++ llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h Mon Oct 19 23:35:02 2015<br>
@@ -20,6 +20,7 @@<br>
 #include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/IR/Module.h"<br>
 #include "llvm/IR/TypeBuilder.h"<br>
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"<br>
 #include <memory><br>
<br>
 namespace llvm {<br>
@@ -60,6 +61,87 @@ namespace llvm {<br>
     }<br>
   };<br>
<br>
+template <typename HandleT,<br>
+          typename AddModuleSetFtor,<br>
+          typename RemoveModuleSetFtor,<br>
+          typename FindSymbolFtor,<br>
+          typename FindSymbolInFtor><br>
+class MockBaseLayer {<br>
+public:<br>
+<br>
+  typedef HandleT ModuleSetHandleT;<br>
+<br>
+  MockBaseLayer(AddModuleSetFtor &&AddModuleSet,<br>
+                RemoveModuleSetFtor &&RemoveModuleSet,<br>
+                FindSymbolFtor &&FindSymbol,<br>
+                FindSymbolInFtor &&FindSymbolIn)<br>
+      : AddModuleSet(AddModuleSet), RemoveModuleSet(RemoveModuleSet),<br>
+        FindSymbol(FindSymbol), FindSymbolIn(FindSymbolIn)<br>
+  {}<br>
+<br>
+  template <typename ModuleSetT, typename MemoryManagerPtrT,<br>
+            typename SymbolResolverPtrT><br>
+  ModuleSetHandleT addModuleSet(ModuleSetT Ms, MemoryManagerPtrT MemMgr,<br>
+                                SymbolResolverPtrT Resolver) {<br>
+    return AddModuleSet(std::move(Ms), std::move(MemMgr), std::move(Resolver));<br>
+  }<br>
+<br>
+  void removeModuleSet(ModuleSetHandleT H) {<br>
+    RemoveModuleSet(H);<br>
+  }<br>
+<br>
+  orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {<br>
+    return FindSymbol(Name, ExportedSymbolsOnly);<br>
+  }<br>
+<br>
+  orc::JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,<br>
+                         bool ExportedSymbolsOnly) {<br>
+    return FindSymbolIn(H, Name, ExportedSymbolsOnly);<br>
+  }<br>
+<br>
+private:<br>
+  AddModuleSetFtor AddModuleSet;<br>
+  RemoveModuleSetFtor RemoveModuleSet;<br>
+  FindSymbolFtor FindSymbol;<br>
+  FindSymbolInFtor FindSymbolIn;<br>
+};<br>
+<br>
+template <typename ModuleSetHandleT,<br>
+          typename AddModuleSetFtor,<br>
+          typename RemoveModuleSetFtor,<br>
+          typename FindSymbolFtor,<br>
+          typename FindSymbolInFtor><br>
+MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor,<br>
+              FindSymbolFtor, FindSymbolInFtor><br>
+createMockBaseLayer(AddModuleSetFtor &&AddModuleSet,<br>
+                    RemoveModuleSetFtor &&RemoveModuleSet,<br>
+                    FindSymbolFtor &&FindSymbol,<br>
+                    FindSymbolInFtor &&FindSymbolIn) {<br>
+  return MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor,<br>
+                       FindSymbolFtor, FindSymbolInFtor>(<br>
+                         std::forward<AddModuleSetFtor>(AddModuleSet),<br>
+                         std::forward<RemoveModuleSetFtor>(RemoveModuleSet),<br>
+                         std::forward<FindSymbolFtor>(FindSymbol),<br>
+                         std::forward<FindSymbolInFtor>(FindSymbolIn));<br>
+}<br>
+<br>
+template <typename ReturnT><br>
+class DoNothingAndReturn {<br>
+public:<br>
+  DoNothingAndReturn(ReturnT Val) : Val(Val) {}<br>
+<br>
+  template <typename... Args><br>
+  ReturnT operator()(Args...) const { return Val; }<br>
+private:<br>
+  ReturnT Val;<br>
+};<br>
+<br>
+template <><br>
+class DoNothingAndReturn<void> {<br>
+public:<br>
+  template <typename... Args><br>
+  void operator()(Args...) const { }<br>
+};<br>
<br>
 } // namespace llvm<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>