[llvm] r250796 - [Orc] Make CompileOnDemandLayer::findSymbol call BaseLayer::findSymbol if no

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 20 14:14:07 PDT 2015


On Mon, Oct 19, 2015 at 9:35 PM, Lang Hames via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: lhames
> Date: Mon Oct 19 23:35:02 2015
> New Revision: 250796
>
> URL: http://llvm.org/viewvc/llvm-project?rev=250796&view=rev
> Log:
> [Orc] Make CompileOnDemandLayer::findSymbol call BaseLayer::findSymbol if
> no
> symbol definition is found in the logical dylibs.
>
>
> Added:
>     llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
> Modified:
>     llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
>     llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt
>     llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h
>
> Modified:
> llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=250796&r1=250795&r2=250796&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
> (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h Mon
> Oct 19 23:35:02 2015
> @@ -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
>
> Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt?rev=250796&r1=250795&r2=250796&view=diff
>
> ==============================================================================
> --- llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt (original)
> +++ llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt Mon Oct 19
> 23:35:02 2015
> @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
>    )
>
>  add_llvm_unittest(OrcJITTests
> +  CompileOnDemandLayerTest.cpp
>    IndirectionUtilsTest.cpp
>    GlobalMappingLayerTest.cpp
>    LazyEmittingLayerTest.cpp
>
> Added:
> llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp?rev=250796&view=auto
>
> ==============================================================================
> --- llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
> (added)
> +++ llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
> Mon Oct 19 23:35:02 2015
>

Awesome - great to see some unit testing here. The architecture's pretty
ideal for it.


> @@ -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 {
>

Will this be another useful generic thing (like the mock base layer?) that
should go in a general utility header?


> +public:
> +  DummyCallbackManager()
> +      : JITCompileCallbackManagerBase(0, 0), NextStubAddress(0),
> +        UniversalCompile([]() { return 0; }) {
>

You could initialize NextStubAddress and UniversalCompile with non-static
data member initializers if you like.


> +  }
> +
> +  CompileCallbackInfo getCompileCallback(LLVMContext &Context) override {
> +    return CompileCallbackInfo(++NextStubAddress, UniversalCompile);
> +  }
> +public:
> +  TargetAddress NextStubAddress;
> +  CompileFtor UniversalCompile;
> +};
> +
> +class DummyStubsManager : public orc::IndirectStubsManagerBase {
>

Another generic utility? Or I guess these might be fleshed out with functor
callback implementations for other test cases.


> +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.";
>

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:

int calls = 0;
DummyStubsManager *ptr = nullptr;
auto StubsMgrBuilder = [&]() { ++calls; auto r =
make_unique<DummyStubsManager>(); ptr = r.get(); return r; };
...
EXPECT_EQ(0, calls);
auto Sym = findSymbol
EXPECT_EQ(1, calls);
EXPECT_EQ(ptr, Sym.get());

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)


> +}
> +
> +}
>
> Modified: llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h?rev=250796&r1=250795&r2=250796&view=diff
>
> ==============================================================================
> --- llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h (original)
> +++ llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h Mon Oct 19
> 23:35:02 2015
> @@ -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
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151020/a65fb104/attachment.html>


More information about the llvm-commits mailing list