From 7233876104013680a0f3c7a75228ecb0cc3c27dc Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 20 Oct 2015 04:35:02 +0000 Subject: [PATCH] [Orc] Make CompileOnDemandLayer::findSymbol call BaseLayer::findSymbol if no 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 --- .../Orc/CompileOnDemandLayer.h | 2 +- unittests/ExecutionEngine/Orc/CMakeLists.txt | 1 + .../Orc/CompileOnDemandLayerTest.cpp | 82 +++++++++++++++++++ unittests/ExecutionEngine/Orc/OrcTestCommon.h | 82 +++++++++++++++++++ 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index e71e66e2127..78023b22353 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -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 diff --git a/unittests/ExecutionEngine/Orc/CMakeLists.txt b/unittests/ExecutionEngine/Orc/CMakeLists.txt index 41088ac3a9c..031eea5f5af 100644 --- a/unittests/ExecutionEngine/Orc/CMakeLists.txt +++ b/unittests/ExecutionEngine/Orc/CMakeLists.txt @@ -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 index 00000000000..dfd21a7d9ce --- /dev/null +++ b/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp @@ -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(DoNothingAndReturn(0), + DoNothingAndReturn(), + [](const std::string &Name, bool) { + if (Name == "foo") + return JITSymbol(1, JITSymbolFlags::Exported); + return JITSymbol(nullptr); + }, + DoNothingAndReturn(nullptr)); + + typedef decltype(MockBaseLayer) MockBaseLayerT; + DummyCallbackManager CallbackMgr; + auto StubsMgrBuilder = + []() { + return llvm::make_unique(); + }; + + llvm::orc::CompileOnDemandLayer + COD(MockBaseLayer, + [](Function &F) { std::set 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."; +} + +} diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/unittests/ExecutionEngine/Orc/OrcTestCommon.h index 1b2859b51d0..99bae55815d 100644 --- a/unittests/ExecutionEngine/Orc/OrcTestCommon.h +++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.h @@ -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 namespace llvm { @@ -60,6 +61,87 @@ namespace llvm { } }; +template +class MockBaseLayer { +public: + + typedef HandleT ModuleSetHandleT; + + MockBaseLayer(AddModuleSetFtor &&AddModuleSet, + RemoveModuleSetFtor &&RemoveModuleSet, + FindSymbolFtor &&FindSymbol, + FindSymbolInFtor &&FindSymbolIn) + : AddModuleSet(AddModuleSet), RemoveModuleSet(RemoveModuleSet), + FindSymbol(FindSymbol), FindSymbolIn(FindSymbolIn) + {} + + template + 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 +MockBaseLayer +createMockBaseLayer(AddModuleSetFtor &&AddModuleSet, + RemoveModuleSetFtor &&RemoveModuleSet, + FindSymbolFtor &&FindSymbol, + FindSymbolInFtor &&FindSymbolIn) { + return MockBaseLayer( + std::forward(AddModuleSet), + std::forward(RemoveModuleSet), + std::forward(FindSymbol), + std::forward(FindSymbolIn)); +} + +template +class DoNothingAndReturn { +public: + DoNothingAndReturn(ReturnT Val) : Val(Val) {} + + template + ReturnT operator()(Args...) const { return Val; } +private: + ReturnT Val; +}; + +template <> +class DoNothingAndReturn { +public: + template + void operator()(Args...) const { } +}; } // namespace llvm -- 2.34.1