summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/ExecutionEngine/Orc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/ExecutionEngine/Orc')
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt4
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp (renamed from llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp)4
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp282
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp24
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp228
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp332
6 files changed, 437 insertions, 437 deletions
diff --git a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
index 8b0d5fc2435..019437d4ad5 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -10,7 +10,6 @@ set(LLVM_LINK_COMPONENTS
)
add_llvm_unittest(OrcJITTests
- CompileOnDemandLayerTest.cpp
CoreAPIsTest.cpp
IndirectionUtilsTest.cpp
GlobalMappingLayerTest.cpp
@@ -18,6 +17,8 @@ add_llvm_unittest(OrcJITTests
LazyCallThroughAndReexportsTest.cpp
LazyEmittingLayerTest.cpp
LegacyAPIInteropTest.cpp
+ LegacyCompileOnDemandLayerTest.cpp
+ LegacyRTDyldObjectLinkingLayerTest.cpp
ObjectTransformLayerTest.cpp
OrcCAPITest.cpp
OrcTestCommon.cpp
@@ -25,7 +26,6 @@ add_llvm_unittest(OrcJITTests
RemoteObjectLayerTest.cpp
RPCUtilsTest.cpp
RTDyldObjectLinkingLayerTest.cpp
- RTDyldObjectLinkingLayer2Test.cpp
SymbolStringPoolTest.cpp
ThreadSafeModuleTest.cpp
)
diff --git a/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
index 9aa4437550b..38f7a654571 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
@@ -54,7 +54,7 @@ public:
}
};
-TEST(CompileOnDemandLayerTest, FindSymbol) {
+TEST(LegacyCompileOnDemandLayerTest, FindSymbol) {
MockBaseLayer<int, std::shared_ptr<Module>> TestBaseLayer;
TestBaseLayer.findSymbolImpl =
[](const std::string &Name, bool) {
@@ -76,7 +76,7 @@ TEST(CompileOnDemandLayerTest, FindSymbol) {
llvm_unreachable("Should never be called");
};
- llvm::orc::CompileOnDemandLayer<decltype(TestBaseLayer)> COD(
+ llvm::orc::LegacyCompileOnDemandLayer<decltype(TestBaseLayer)> COD(
ES, TestBaseLayer, GetResolver, SetResolver,
[](Function &F) { return std::set<Function *>{&F}; }, CallbackMgr,
[] { return llvm::make_unique<DummyStubsManager>(); }, true);
diff --git a/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
new file mode 100644
index 00000000000..8c9c958cc42
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
@@ -0,0 +1,282 @@
+//===- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
+#include "OrcTestCommon.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/Legacy.h"
+#include "llvm/ExecutionEngine/Orc/NullResolver.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/LLVMContext.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::orc;
+
+namespace {
+
+class LegacyRTDyldObjectLinkingLayerExecutionTest : public testing::Test,
+ public OrcExecutionTest {
+
+};
+
+class SectionMemoryManagerWrapper : public SectionMemoryManager {
+public:
+ int FinalizationCount = 0;
+ int NeedsToReserveAllocationSpaceCount = 0;
+
+ bool needsToReserveAllocationSpace() override {
+ ++NeedsToReserveAllocationSpaceCount;
+ return SectionMemoryManager::needsToReserveAllocationSpace();
+ }
+
+ bool finalizeMemory(std::string *ErrMsg = nullptr) override {
+ ++FinalizationCount;
+ return SectionMemoryManager::finalizeMemory(ErrMsg);
+ }
+};
+
+TEST(LegacyRTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
+ class MemoryManagerWrapper : public SectionMemoryManager {
+ public:
+ MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
+ uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName,
+ bool IsReadOnly) override {
+ if (SectionName == ".debug_str")
+ DebugSeen = true;
+ return SectionMemoryManager::allocateDataSection(Size, Alignment,
+ SectionID,
+ SectionName,
+ IsReadOnly);
+ }
+ private:
+ bool &DebugSeen;
+ };
+
+ bool DebugSectionSeen = false;
+ auto MM = std::make_shared<MemoryManagerWrapper>(DebugSectionSeen);
+
+ ExecutionSession ES;
+
+ LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey) {
+ return LegacyRTDyldObjectLinkingLayer::Resources{
+ MM, std::make_shared<NullResolver>()};
+ });
+
+ LLVMContext Context;
+ auto M = llvm::make_unique<Module>("", Context);
+ M->setTargetTriple("x86_64-unknown-linux-gnu");
+ Type *Int32Ty = IntegerType::get(Context, 32);
+ GlobalVariable *GV =
+ new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
+ ConstantInt::get(Int32Ty, 42), "foo");
+
+ GV->setSection(".debug_str");
+
+
+ // Initialize the native target in case this is the first unit test
+ // to try to build a TM.
+ OrcNativeTarget::initialize();
+ std::unique_ptr<TargetMachine> TM(
+ EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
+ SmallVector<std::string, 1>()));
+ if (!TM)
+ return;
+
+ auto Obj = SimpleCompiler(*TM)(*M);
+
+ {
+ // Test with ProcessAllSections = false (the default).
+ auto K = ES.allocateVModule();
+ cantFail(ObjLayer.addObject(
+ K, MemoryBuffer::getMemBufferCopy(Obj->getBuffer())));
+ cantFail(ObjLayer.emitAndFinalize(K));
+ EXPECT_EQ(DebugSectionSeen, false)
+ << "Unexpected debug info section";
+ cantFail(ObjLayer.removeObject(K));
+ }
+
+ {
+ // Test with ProcessAllSections = true.
+ ObjLayer.setProcessAllSections(true);
+ auto K = ES.allocateVModule();
+ cantFail(ObjLayer.addObject(K, std::move(Obj)));
+ cantFail(ObjLayer.emitAndFinalize(K));
+ EXPECT_EQ(DebugSectionSeen, true)
+ << "Expected debug info section not seen";
+ cantFail(ObjLayer.removeObject(K));
+ }
+}
+
+TEST_F(LegacyRTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
+ if (!SupportsJIT)
+ return;
+
+ ExecutionSession ES;
+
+ auto MM = std::make_shared<SectionMemoryManagerWrapper>();
+
+ std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
+
+ LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&](VModuleKey K) {
+ auto I = Resolvers.find(K);
+ assert(I != Resolvers.end() && "Missing resolver");
+ auto R = std::move(I->second);
+ Resolvers.erase(I);
+ return LegacyRTDyldObjectLinkingLayer::Resources{MM, std::move(R)};
+ });
+ SimpleCompiler Compile(*TM);
+
+ // Create a pair of modules that will trigger recursive finalization:
+ // Module 1:
+ // int bar() { return 42; }
+ // Module 2:
+ // int bar();
+ // int foo() { return bar(); }
+ //
+ // Verify that the memory manager is only finalized once (for Module 2).
+ // Failure suggests that finalize is being called on the inner RTDyld
+ // instance (for Module 1) which is unsafe, as it will prevent relocation of
+ // Module 2.
+
+ ModuleBuilder MB1(Context, "", "dummy");
+ {
+ MB1.getModule()->setDataLayout(TM->createDataLayout());
+ Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
+ BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
+ IRBuilder<> Builder(BarEntry);
+ IntegerType *Int32Ty = IntegerType::get(Context, 32);
+ Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
+ Builder.CreateRet(FourtyTwo);
+ }
+
+ auto Obj1 = Compile(*MB1.getModule());
+
+ ModuleBuilder MB2(Context, "", "dummy");
+ {
+ MB2.getModule()->setDataLayout(TM->createDataLayout());
+ Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
+ Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
+ BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl);
+ IRBuilder<> Builder(FooEntry);
+ Builder.CreateRet(Builder.CreateCall(BarDecl));
+ }
+ auto Obj2 = Compile(*MB2.getModule());
+
+ auto K1 = ES.allocateVModule();
+ Resolvers[K1] = std::make_shared<NullResolver>();
+ cantFail(ObjLayer.addObject(K1, std::move(Obj1)));
+
+ auto K2 = ES.allocateVModule();
+ auto LegacyLookup = [&](const std::string &Name) {
+ return ObjLayer.findSymbol(Name, true);
+ };
+
+ Resolvers[K2] = createSymbolResolver(
+ [&](const SymbolNameSet &Symbols) {
+ return cantFail(
+ getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup));
+ },
+ [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
+ const SymbolNameSet &Symbols) {
+ return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
+ });
+
+ cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
+ cantFail(ObjLayer.emitAndFinalize(K2));
+ cantFail(ObjLayer.removeObject(K2));
+
+ // Finalization of module 2 should trigger finalization of module 1.
+ // Verify that finalize on SMMW is only called once.
+ EXPECT_EQ(MM->FinalizationCount, 1)
+ << "Extra call to finalize";
+}
+
+TEST_F(LegacyRTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
+ if (!SupportsJIT)
+ return;
+
+ ExecutionSession ES;
+
+ auto MM = std::make_shared<SectionMemoryManagerWrapper>();
+
+ LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey K) {
+ return LegacyRTDyldObjectLinkingLayer::Resources{
+ MM, std::make_shared<NullResolver>()};
+ });
+ SimpleCompiler Compile(*TM);
+
+ // Create a pair of unrelated modules:
+ //
+ // Module 1:
+ // int foo() { return 42; }
+ // Module 2:
+ // int bar() { return 7; }
+ //
+ // Both modules will share a memory manager. We want to verify that the
+ // second object is not loaded before the first one is finalized. To do this
+ // in a portable way, we abuse the
+ // RuntimeDyld::MemoryManager::needsToReserveAllocationSpace hook, which is
+ // called once per object before any sections are allocated.
+
+ ModuleBuilder MB1(Context, "", "dummy");
+ {
+ MB1.getModule()->setDataLayout(TM->createDataLayout());
+ Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo");
+ BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
+ IRBuilder<> Builder(BarEntry);
+ IntegerType *Int32Ty = IntegerType::get(Context, 32);
+ Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
+ Builder.CreateRet(FourtyTwo);
+ }
+
+ auto Obj1 = Compile(*MB1.getModule());
+
+ ModuleBuilder MB2(Context, "", "dummy");
+ {
+ MB2.getModule()->setDataLayout(TM->createDataLayout());
+ Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar");
+ BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
+ IRBuilder<> Builder(BarEntry);
+ IntegerType *Int32Ty = IntegerType::get(Context, 32);
+ Value *Seven = ConstantInt::getSigned(Int32Ty, 7);
+ Builder.CreateRet(Seven);
+ }
+ auto Obj2 = Compile(*MB2.getModule());
+
+ auto K = ES.allocateVModule();
+ cantFail(ObjLayer.addObject(K, std::move(Obj1)));
+ cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj2)));
+ cantFail(ObjLayer.emitAndFinalize(K));
+ cantFail(ObjLayer.removeObject(K));
+
+ // Only one call to needsToReserveAllocationSpace should have been made.
+ EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1)
+ << "More than one call to needsToReserveAllocationSpace "
+ "(multiple unrelated objects loaded prior to finalization)";
+}
+
+TEST_F(LegacyRTDyldObjectLinkingLayerExecutionTest, TestNotifyLoadedSignature) {
+ ExecutionSession ES;
+ LegacyRTDyldObjectLinkingLayer ObjLayer(
+ ES,
+ [](VModuleKey) {
+ return LegacyRTDyldObjectLinkingLayer::Resources{
+ nullptr, std::make_shared<NullResolver>()};
+ },
+ [](VModuleKey, const object::ObjectFile &obj,
+ const RuntimeDyld::LoadedObjectInfo &info) {});
+}
+
+} // end anonymous namespace
diff --git a/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
index 6ad3c19ada9..1c530247a7c 100644
--- a/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
@@ -175,19 +175,19 @@ private:
}
};
-// Test each operation on ObjectTransformLayer.
-TEST(ObjectTransformLayerTest, Main) {
+// Test each operation on LegacyObjectTransformLayer.
+TEST(LegacyObjectTransformLayerTest, Main) {
MockBaseLayer M;
ExecutionSession ES(std::make_shared<SymbolStringPool>());
// Create one object transform layer using a transform (as a functor)
// that allocates new objects, and deals in unique pointers.
- ObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
+ LegacyObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
// Create a second object transform layer using a transform (as a lambda)
// that mutates objects in place, and deals in naked pointers
- ObjectTransformLayer<MockBaseLayer,
+ LegacyObjectTransformLayer<MockBaseLayer,
std::function<std::shared_ptr<MockObjectFile>(
std::shared_ptr<MockObjectFile>)>>
T2(M, [](std::shared_ptr<MockObjectFile> Obj) {
@@ -257,9 +257,9 @@ TEST(ObjectTransformLayerTest, Main) {
if (!RunStaticChecks)
return;
- // Make sure that ObjectTransformLayer implements the object layer concept
+ // Make sure that LegacyObjectTransformLayer implements the object layer concept
// correctly by sandwitching one between an ObjectLinkingLayer and an
- // IRCompileLayer, verifying that it compiles if we have a call to the
+ // LegacyIRCompileLayer, verifying that it compiles if we have a call to the
// IRComileLayer's addModule that should call the transform layer's
// addObject, and also calling the other public transform layer methods
// directly to make sure the methods they intend to forward to exist on
@@ -282,8 +282,8 @@ TEST(ObjectTransformLayerTest, Main) {
};
// Construct the jit layers.
- RTDyldObjectLinkingLayer BaseLayer(ES, [](VModuleKey) {
- return RTDyldObjectLinkingLayer::Resources{
+ LegacyRTDyldObjectLinkingLayer BaseLayer(ES, [](VModuleKey) {
+ return LegacyRTDyldObjectLinkingLayer::Resources{
std::make_shared<llvm::SectionMemoryManager>(),
std::make_shared<NullResolver>()};
});
@@ -291,20 +291,20 @@ TEST(ObjectTransformLayerTest, Main) {
auto IdentityTransform = [](std::unique_ptr<llvm::MemoryBuffer> Obj) {
return Obj;
};
- ObjectTransformLayer<decltype(BaseLayer), decltype(IdentityTransform)>
+ LegacyObjectTransformLayer<decltype(BaseLayer), decltype(IdentityTransform)>
TransformLayer(BaseLayer, IdentityTransform);
auto NullCompiler = [](llvm::Module &) {
return std::unique_ptr<llvm::MemoryBuffer>(nullptr);
};
- IRCompileLayer<decltype(TransformLayer), decltype(NullCompiler)>
+ LegacyIRCompileLayer<decltype(TransformLayer), decltype(NullCompiler)>
CompileLayer(TransformLayer, NullCompiler);
- // Make sure that the calls from IRCompileLayer to ObjectTransformLayer
+ // Make sure that the calls from LegacyIRCompileLayer to LegacyObjectTransformLayer
// compile.
cantFail(CompileLayer.addModule(ES.allocateVModule(),
std::unique_ptr<llvm::Module>()));
- // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
+ // Make sure that the calls from LegacyObjectTransformLayer to ObjectLinkingLayer
// compile.
VModuleKey DummyKey = ES.allocateVModule();
cantFail(TransformLayer.emitAndFinalize(DummyKey));
diff --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp
deleted file mode 100644
index 1dbd48b5972..00000000000
--- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-//===--- RTDyldObjectLinkingLayer2Test.cpp - RTDyld linking layer tests ---===//
-//
-// 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/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
-#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#include "llvm/ExecutionEngine/Orc/Legacy.h"
-#include "llvm/ExecutionEngine/Orc/NullResolver.h"
-#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
-#include "llvm/ExecutionEngine/SectionMemoryManager.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/LLVMContext.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-using namespace llvm::orc;
-
-namespace {
-
-class RTDyldObjectLinkingLayer2ExecutionTest : public testing::Test,
- public OrcExecutionTest {};
-
-// Adds an object with a debug section to RuntimeDyld and then returns whether
-// the debug section was passed to the memory manager.
-static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
- bool ProcessAllSections) {
- class MemoryManagerWrapper : public SectionMemoryManager {
- public:
- MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID, StringRef SectionName,
- bool IsReadOnly) override {
- if (SectionName == ".debug_str")
- DebugSeen = true;
- return SectionMemoryManager::allocateDataSection(
- Size, Alignment, SectionID, SectionName, IsReadOnly);
- }
-
- private:
- bool &DebugSeen;
- };
-
- bool DebugSectionSeen = false;
-
- ExecutionSession ES;
- auto &JD = ES.createJITDylib("main");
- auto Foo = ES.intern("foo");
-
- RTDyldObjectLinkingLayer2 ObjLayer(ES, [&DebugSectionSeen](VModuleKey) {
- return llvm::make_unique<MemoryManagerWrapper>(DebugSectionSeen);
- });
-
- auto OnResolveDoNothing = [](Expected<SymbolMap> R) {
- cantFail(std::move(R));
- };
-
- auto OnReadyDoNothing = [](Error Err) { cantFail(std::move(Err)); };
-
- ObjLayer.setProcessAllSections(ProcessAllSections);
- auto K = ES.allocateVModule();
- cantFail(ObjLayer.add(JD, K, std::move(Obj)));
- ES.lookup({&JD}, {Foo}, OnResolveDoNothing, OnReadyDoNothing,
- NoDependenciesToRegister);
- return DebugSectionSeen;
-}
-
-TEST(RTDyldObjectLinkingLayer2Test, TestSetProcessAllSections) {
- LLVMContext Context;
- auto M = llvm::make_unique<Module>("", Context);
- M->setTargetTriple("x86_64-unknown-linux-gnu");
- Type *Int32Ty = IntegerType::get(Context, 32);
- GlobalVariable *GV =
- new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
- ConstantInt::get(Int32Ty, 42), "foo");
-
- GV->setSection(".debug_str");
-
- // Initialize the native target in case this is the first unit test
- // to try to build a TM.
- OrcNativeTarget::initialize();
- std::unique_ptr<TargetMachine> TM(EngineBuilder().selectTarget(
- Triple(M->getTargetTriple()), "", "", SmallVector<std::string, 1>()));
- if (!TM)
- return;
-
- auto Obj = SimpleCompiler(*TM)(*M);
-
- EXPECT_FALSE(testSetProcessAllSections(
- MemoryBuffer::getMemBufferCopy(Obj->getBuffer()), false))
- << "Debug section seen despite ProcessAllSections being false";
- EXPECT_TRUE(testSetProcessAllSections(std::move(Obj), true))
- << "Expected to see debug section when ProcessAllSections is true";
-}
-
-TEST(RTDyldObjectLinkingLayer2Test, TestOverrideObjectFlags) {
-
- OrcNativeTarget::initialize();
-
- std::unique_ptr<TargetMachine> TM(
- EngineBuilder().selectTarget(Triple("x86_64-unknown-linux-gnu"), "", "",
- SmallVector<std::string, 1>()));
-
- if (!TM)
- return;
-
- // Our compiler is going to modify symbol visibility settings without telling
- // ORC. This will test our ability to override the flags later.
- class FunkySimpleCompiler : public SimpleCompiler {
- public:
- FunkySimpleCompiler(TargetMachine &TM) : SimpleCompiler(TM) {}
-
- CompileResult operator()(Module &M) {
- auto *Foo = M.getFunction("foo");
- assert(Foo && "Expected function Foo not found");
- Foo->setVisibility(GlobalValue::HiddenVisibility);
- return SimpleCompiler::operator()(M);
- }
- };
-
- // Create a module with two void() functions: foo and bar.
- ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
- ThreadSafeModule M;
- {
- ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
- MB.getModule()->setDataLayout(TM->createDataLayout());
-
- Function *FooImpl = MB.createFunctionDecl<void()>("foo");
- BasicBlock *FooEntry =
- BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
- IRBuilder<> B1(FooEntry);
- B1.CreateRetVoid();
-
- Function *BarImpl = MB.createFunctionDecl<void()>("bar");
- BasicBlock *BarEntry =
- BasicBlock::Create(*TSCtx.getContext(), "entry", BarImpl);
- IRBuilder<> B2(BarEntry);
- B2.CreateRetVoid();
-
- M = ThreadSafeModule(MB.takeModule(), std::move(TSCtx));
- }
-
- // Create a simple stack and set the override flags option.
- ExecutionSession ES;
- auto &JD = ES.createJITDylib("main");
- auto Foo = ES.intern("foo");
- RTDyldObjectLinkingLayer2 ObjLayer(
- ES, [](VModuleKey) { return llvm::make_unique<SectionMemoryManager>(); });
- IRCompileLayer2 CompileLayer(ES, ObjLayer, FunkySimpleCompiler(*TM));
-
- ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
-
- cantFail(CompileLayer.add(JD, ES.allocateVModule(), std::move(M)));
- ES.lookup({&JD}, {Foo}, [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
- [](Error Err) { cantFail(std::move(Err)); },
- NoDependenciesToRegister);
-}
-
-TEST(RTDyldObjectLinkingLayer2Test, TestAutoClaimResponsibilityForSymbols) {
-
- OrcNativeTarget::initialize();
-
- std::unique_ptr<TargetMachine> TM(
- EngineBuilder().selectTarget(Triple("x86_64-unknown-linux-gnu"), "", "",
- SmallVector<std::string, 1>()));
-
- if (!TM)
- return;
-
- // Our compiler is going to add a new symbol without telling ORC.
- // This will test our ability to auto-claim responsibility later.
- class FunkySimpleCompiler : public SimpleCompiler {
- public:
- FunkySimpleCompiler(TargetMachine &TM) : SimpleCompiler(TM) {}
-
- CompileResult operator()(Module &M) {
- Function *BarImpl =
- Function::Create(TypeBuilder<void(), false>::get(M.getContext()),
- GlobalValue::ExternalLinkage, "bar", &M);
- BasicBlock *BarEntry =
- BasicBlock::Create(M.getContext(), "entry", BarImpl);
- IRBuilder<> B(BarEntry);
- B.CreateRetVoid();
-
- return SimpleCompiler::operator()(M);
- }
- };
-
- // Create a module with two void() functions: foo and bar.
- ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
- ThreadSafeModule M;
- {
- ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
- MB.getModule()->setDataLayout(TM->createDataLayout());
-
- Function *FooImpl = MB.createFunctionDecl<void()>("foo");
- BasicBlock *FooEntry =
- BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
- IRBuilder<> B(FooEntry);
- B.CreateRetVoid();
-
- M = ThreadSafeModule(MB.takeModule(), std::move(TSCtx));
- }
-
- // Create a simple stack and set the override flags option.
- ExecutionSession ES;
- auto &JD = ES.createJITDylib("main");
- auto Foo = ES.intern("foo");
- RTDyldObjectLinkingLayer2 ObjLayer(
- ES, [](VModuleKey) { return llvm::make_unique<SectionMemoryManager>(); });
- IRCompileLayer2 CompileLayer(ES, ObjLayer, FunkySimpleCompiler(*TM));
-
- ObjLayer.setAutoClaimResponsibilityForObjectSymbols(true);
-
- cantFail(CompileLayer.add(JD, ES.allocateVModule(), std::move(M)));
- ES.lookup({&JD}, {Foo}, [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
- [](Error Err) { cantFail(std::move(Err)); },
- NoDependenciesToRegister);
-}
-
-} // end anonymous namespace
diff --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
index 62c6b7dfa31..75ccfc9ab0d 100644
--- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
@@ -1,4 +1,4 @@
-//===- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer unit tests -===//
+//===--- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer tests ---===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "OrcTestCommon.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/Legacy.h"
#include "llvm/ExecutionEngine/Orc/NullResolver.h"
+#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
@@ -25,258 +26,203 @@ using namespace llvm::orc;
namespace {
class RTDyldObjectLinkingLayerExecutionTest : public testing::Test,
- public OrcExecutionTest {
-
-};
-
-class SectionMemoryManagerWrapper : public SectionMemoryManager {
-public:
- int FinalizationCount = 0;
- int NeedsToReserveAllocationSpaceCount = 0;
-
- bool needsToReserveAllocationSpace() override {
- ++NeedsToReserveAllocationSpaceCount;
- return SectionMemoryManager::needsToReserveAllocationSpace();
- }
-
- bool finalizeMemory(std::string *ErrMsg = nullptr) override {
- ++FinalizationCount;
- return SectionMemoryManager::finalizeMemory(ErrMsg);
- }
-};
+ public OrcExecutionTest {};
-TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
+// Adds an object with a debug section to RuntimeDyld and then returns whether
+// the debug section was passed to the memory manager.
+static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
+ bool ProcessAllSections) {
class MemoryManagerWrapper : public SectionMemoryManager {
public:
MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- StringRef SectionName,
+ unsigned SectionID, StringRef SectionName,
bool IsReadOnly) override {
if (SectionName == ".debug_str")
DebugSeen = true;
- return SectionMemoryManager::allocateDataSection(Size, Alignment,
- SectionID,
- SectionName,
- IsReadOnly);
+ return SectionMemoryManager::allocateDataSection(
+ Size, Alignment, SectionID, SectionName, IsReadOnly);
}
+
private:
bool &DebugSeen;
};
bool DebugSectionSeen = false;
- auto MM = std::make_shared<MemoryManagerWrapper>(DebugSectionSeen);
ExecutionSession ES;
+ auto &JD = ES.createJITDylib("main");
+ auto Foo = ES.intern("foo");
- RTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey) {
- return RTDyldObjectLinkingLayer::Resources{
- MM, std::make_shared<NullResolver>()};
+ RTDyldObjectLinkingLayer ObjLayer(ES, [&DebugSectionSeen](VModuleKey) {
+ return llvm::make_unique<MemoryManagerWrapper>(DebugSectionSeen);
});
+ auto OnResolveDoNothing = [](Expected<SymbolMap> R) {
+ cantFail(std::move(R));
+ };
+
+ auto OnReadyDoNothing = [](Error Err) { cantFail(std::move(Err)); };
+
+ ObjLayer.setProcessAllSections(ProcessAllSections);
+ auto K = ES.allocateVModule();
+ cantFail(ObjLayer.add(JD, K, std::move(Obj)));
+ ES.lookup({&JD}, {Foo}, OnResolveDoNothing, OnReadyDoNothing,
+ NoDependenciesToRegister);
+ return DebugSectionSeen;
+}
+
+TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
LLVMContext Context;
auto M = llvm::make_unique<Module>("", Context);
M->setTargetTriple("x86_64-unknown-linux-gnu");
Type *Int32Ty = IntegerType::get(Context, 32);
GlobalVariable *GV =
- new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
+ new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
ConstantInt::get(Int32Ty, 42), "foo");
GV->setSection(".debug_str");
-
// Initialize the native target in case this is the first unit test
// to try to build a TM.
OrcNativeTarget::initialize();
- std::unique_ptr<TargetMachine> TM(
- EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
- SmallVector<std::string, 1>()));
+ std::unique_ptr<TargetMachine> TM(EngineBuilder().selectTarget(
+ Triple(M->getTargetTriple()), "", "", SmallVector<std::string, 1>()));
if (!TM)
return;
auto Obj = SimpleCompiler(*TM)(*M);
- {
- // Test with ProcessAllSections = false (the default).
- auto K = ES.allocateVModule();
- cantFail(ObjLayer.addObject(
- K, MemoryBuffer::getMemBufferCopy(Obj->getBuffer())));
- cantFail(ObjLayer.emitAndFinalize(K));
- EXPECT_EQ(DebugSectionSeen, false)
- << "Unexpected debug info section";
- cantFail(ObjLayer.removeObject(K));
- }
-
- {
- // Test with ProcessAllSections = true.
- ObjLayer.setProcessAllSections(true);
- auto K = ES.allocateVModule();
- cantFail(ObjLayer.addObject(K, std::move(Obj)));
- cantFail(ObjLayer.emitAndFinalize(K));
- EXPECT_EQ(DebugSectionSeen, true)
- << "Expected debug info section not seen";
- cantFail(ObjLayer.removeObject(K));
- }
+ EXPECT_FALSE(testSetProcessAllSections(
+ MemoryBuffer::getMemBufferCopy(Obj->getBuffer()), false))
+ << "Debug section seen despite ProcessAllSections being false";
+ EXPECT_TRUE(testSetProcessAllSections(std::move(Obj), true))
+ << "Expected to see debug section when ProcessAllSections is true";
}
-TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
- if (!SupportsJIT)
- return;
+TEST(RTDyldObjectLinkingLayerTest, TestOverrideObjectFlags) {
- ExecutionSession ES;
+ OrcNativeTarget::initialize();
- auto MM = std::make_shared<SectionMemoryManagerWrapper>();
+ std::unique_ptr<TargetMachine> TM(
+ EngineBuilder().selectTarget(Triple("x86_64-unknown-linux-gnu"), "", "",
+ SmallVector<std::string, 1>()));
- std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
+ if (!TM)
+ return;
- RTDyldObjectLinkingLayer ObjLayer(ES, [&](VModuleKey K) {
- auto I = Resolvers.find(K);
- assert(I != Resolvers.end() && "Missing resolver");
- auto R = std::move(I->second);
- Resolvers.erase(I);
- return RTDyldObjectLinkingLayer::Resources{MM, std::move(R)};
- });
- SimpleCompiler Compile(*TM);
-
- // Create a pair of modules that will trigger recursive finalization:
- // Module 1:
- // int bar() { return 42; }
- // Module 2:
- // int bar();
- // int foo() { return bar(); }
- //
- // Verify that the memory manager is only finalized once (for Module 2).
- // Failure suggests that finalize is being called on the inner RTDyld
- // instance (for Module 1) which is unsafe, as it will prevent relocation of
- // Module 2.
-
- ModuleBuilder MB1(Context, "", "dummy");
- {
- MB1.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
- BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
- IRBuilder<> Builder(BarEntry);
- IntegerType *Int32Ty = IntegerType::get(Context, 32);
- Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
- Builder.CreateRet(FourtyTwo);
- }
+ // Our compiler is going to modify symbol visibility settings without telling
+ // ORC. This will test our ability to override the flags later.
+ class FunkySimpleCompiler : public SimpleCompiler {
+ public:
+ FunkySimpleCompiler(TargetMachine &TM) : SimpleCompiler(TM) {}
- auto Obj1 = Compile(*MB1.getModule());
+ CompileResult operator()(Module &M) {
+ auto *Foo = M.getFunction("foo");
+ assert(Foo && "Expected function Foo not found");
+ Foo->setVisibility(GlobalValue::HiddenVisibility);
+ return SimpleCompiler::operator()(M);
+ }
+ };
- ModuleBuilder MB2(Context, "", "dummy");
+ // Create a module with two void() functions: foo and bar.
+ ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
+ ThreadSafeModule M;
{
- MB2.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
- Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
- BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl);
- IRBuilder<> Builder(FooEntry);
- Builder.CreateRet(Builder.CreateCall(BarDecl));
+ ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
+ MB.getModule()->setDataLayout(TM->createDataLayout());
+
+ Function *FooImpl = MB.createFunctionDecl<void()>("foo");
+ BasicBlock *FooEntry =
+ BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
+ IRBuilder<> B1(FooEntry);
+ B1.CreateRetVoid();
+
+ Function *BarImpl = MB.createFunctionDecl<void()>("bar");
+ BasicBlock *BarEntry =
+ BasicBlock::Create(*TSCtx.getContext(), "entry", BarImpl);
+ IRBuilder<> B2(BarEntry);
+ B2.CreateRetVoid();
+
+ M = ThreadSafeModule(MB.takeModule(), std::move(TSCtx));
}
- auto Obj2 = Compile(*MB2.getModule());
- auto K1 = ES.allocateVModule();
- Resolvers[K1] = std::make_shared<NullResolver>();
- cantFail(ObjLayer.addObject(K1, std::move(Obj1)));
+ // Create a simple stack and set the override flags option.
+ ExecutionSession ES;
+ auto &JD = ES.createJITDylib("main");
+ auto Foo = ES.intern("foo");
+ RTDyldObjectLinkingLayer ObjLayer(
+ ES, [](VModuleKey) { return llvm::make_unique<SectionMemoryManager>(); });
+ IRCompileLayer CompileLayer(ES, ObjLayer, FunkySimpleCompiler(*TM));
- auto K2 = ES.allocateVModule();
- auto LegacyLookup = [&](const std::string &Name) {
- return ObjLayer.findSymbol(Name, true);
- };
+ ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
- Resolvers[K2] = createSymbolResolver(
- [&](const SymbolNameSet &Symbols) {
- return cantFail(
- getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup));
- },
- [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
- const SymbolNameSet &Symbols) {
- return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
- });
-
- cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
- cantFail(ObjLayer.emitAndFinalize(K2));
- cantFail(ObjLayer.removeObject(K2));
-
- // Finalization of module 2 should trigger finalization of module 1.
- // Verify that finalize on SMMW is only called once.
- EXPECT_EQ(MM->FinalizationCount, 1)
- << "Extra call to finalize";
+ cantFail(CompileLayer.add(JD, ES.allocateVModule(), std::move(M)));
+ ES.lookup({&JD}, {Foo}, [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
+ [](Error Err) { cantFail(std::move(Err)); },
+ NoDependenciesToRegister);
}
-TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
- if (!SupportsJIT)
- return;
+TEST(RTDyldObjectLinkingLayerTest, TestAutoClaimResponsibilityForSymbols) {
- ExecutionSession ES;
+ OrcNativeTarget::initialize();
- auto MM = std::make_shared<SectionMemoryManagerWrapper>();
+ std::unique_ptr<TargetMachine> TM(
+ EngineBuilder().selectTarget(Triple("x86_64-unknown-linux-gnu"), "", "",
+ SmallVector<std::string, 1>()));
- RTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey K) {
- return RTDyldObjectLinkingLayer::Resources{
- MM, std::make_shared<NullResolver>()};
- });
- SimpleCompiler Compile(*TM);
-
- // Create a pair of unrelated modules:
- //
- // Module 1:
- // int foo() { return 42; }
- // Module 2:
- // int bar() { return 7; }
- //
- // Both modules will share a memory manager. We want to verify that the
- // second object is not loaded before the first one is finalized. To do this
- // in a portable way, we abuse the
- // RuntimeDyld::MemoryManager::needsToReserveAllocationSpace hook, which is
- // called once per object before any sections are allocated.
-
- ModuleBuilder MB1(Context, "", "dummy");
- {
- MB1.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo");
- BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
- IRBuilder<> Builder(BarEntry);
- IntegerType *Int32Ty = IntegerType::get(Context, 32);
- Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
- Builder.CreateRet(FourtyTwo);
- }
+ if (!TM)
+ return;
- auto Obj1 = Compile(*MB1.getModule());
+ // Our compiler is going to add a new symbol without telling ORC.
+ // This will test our ability to auto-claim responsibility later.
+ class FunkySimpleCompiler : public SimpleCompiler {
+ public:
+ FunkySimpleCompiler(TargetMachine &TM) : SimpleCompiler(TM) {}
+
+ CompileResult operator()(Module &M) {
+ Function *BarImpl =
+ Function::Create(TypeBuilder<void(), false>::get(M.getContext()),
+ GlobalValue::ExternalLinkage, "bar", &M);
+ BasicBlock *BarEntry =
+ BasicBlock::Create(M.getContext(), "entry", BarImpl);
+ IRBuilder<> B(BarEntry);
+ B.CreateRetVoid();
+
+ return SimpleCompiler::operator()(M);
+ }
+ };
- ModuleBuilder MB2(Context, "", "dummy");
+ // Create a module with two void() functions: foo and bar.
+ ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
+ ThreadSafeModule M;
{
- MB2.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar");
- BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
- IRBuilder<> Builder(BarEntry);
- IntegerType *Int32Ty = IntegerType::get(Context, 32);
- Value *Seven = ConstantInt::getSigned(Int32Ty, 7);
- Builder.CreateRet(Seven);
- }
- auto Obj2 = Compile(*MB2.getModule());
+ ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
+ MB.getModule()->setDataLayout(TM->createDataLayout());
- auto K = ES.allocateVModule();
- cantFail(ObjLayer.addObject(K, std::move(Obj1)));
- cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj2)));
- cantFail(ObjLayer.emitAndFinalize(K));
- cantFail(ObjLayer.removeObject(K));
-
- // Only one call to needsToReserveAllocationSpace should have been made.
- EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1)
- << "More than one call to needsToReserveAllocationSpace "
- "(multiple unrelated objects loaded prior to finalization)";
-}
+ Function *FooImpl = MB.createFunctionDecl<void()>("foo");
+ BasicBlock *FooEntry =
+ BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
+ IRBuilder<> B(FooEntry);
+ B.CreateRetVoid();
-TEST_F(RTDyldObjectLinkingLayerExecutionTest, TestNotifyLoadedSignature) {
+ M = ThreadSafeModule(MB.takeModule(), std::move(TSCtx));
+ }
+
+ // Create a simple stack and set the override flags option.
ExecutionSession ES;
+ auto &JD = ES.createJITDylib("main");
+ auto Foo = ES.intern("foo");
RTDyldObjectLinkingLayer ObjLayer(
- ES,
- [](VModuleKey) {
- return RTDyldObjectLinkingLayer::Resources{
- nullptr, std::make_shared<NullResolver>()};
- },
- [](VModuleKey, const object::ObjectFile &obj,
- const RuntimeDyld::LoadedObjectInfo &info) {});
+ ES, [](VModuleKey) { return llvm::make_unique<SectionMemoryManager>(); });
+ IRCompileLayer CompileLayer(ES, ObjLayer, FunkySimpleCompiler(*TM));
+
+ ObjLayer.setAutoClaimResponsibilityForObjectSymbols(true);
+
+ cantFail(CompileLayer.add(JD, ES.allocateVModule(), std::move(M)));
+ ES.lookup({&JD}, {Foo}, [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
+ [](Error Err) { cantFail(std::move(Err)); },
+ NoDependenciesToRegister);
}
} // end anonymous namespace
OpenPOWER on IntegriCloud