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

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 20 15:05:01 PDT 2015


Hi Dave,

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

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...

> I think usually when mocking there would be somewhat more verification
here...

Yes. I hope to add more tests over time, and will do so as opportunities
arise.

- Lang.

On Tue, Oct 20, 2015 at 2:14 PM, David Blaikie <dblaikie at gmail.com> wrote:

>
>
> 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/ad25803d/attachment.html>


More information about the llvm-commits mailing list