<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">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>Awesome - great to see some unit testing here. The architecture's pretty ideal for it.</div><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><div>Will this be another useful generic thing (like the mock base layer?) that should go in a general utility header?</div><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><div>You could initialize NextStubAddress and UniversalCompile with non-static data member initializers if you like.</div><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><div>Another generic utility? Or I guess these might be fleshed out with functor callback implementations for other test cases.</div><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>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><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">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><br></div></div>