summaryrefslogtreecommitdiff
path: root/unittests/ExecutionEngine/Orc
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:46:15 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:46:15 +0000
commitdd58ef019b700900793a1eb48b52123db01b654e (patch)
treefcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /unittests/ExecutionEngine/Orc
parent2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff)
Notes
Diffstat (limited to 'unittests/ExecutionEngine/Orc')
-rw-r--r--unittests/ExecutionEngine/Orc/CMakeLists.txt9
-rw-r--r--unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp75
-rw-r--r--unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp55
-rw-r--r--unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp2
-rw-r--r--unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp94
-rw-r--r--unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp27
-rw-r--r--unittests/ExecutionEngine/Orc/OrcCAPITest.cpp160
-rw-r--r--unittests/ExecutionEngine/Orc/OrcTestCommon.cpp2
-rw-r--r--unittests/ExecutionEngine/Orc/OrcTestCommon.h169
9 files changed, 537 insertions, 56 deletions
diff --git a/unittests/ExecutionEngine/Orc/CMakeLists.txt b/unittests/ExecutionEngine/Orc/CMakeLists.txt
index 30bd19fa3d23..74cc5b57015c 100644
--- a/unittests/ExecutionEngine/Orc/CMakeLists.txt
+++ b/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -1,12 +1,21 @@
+
set(LLVM_LINK_COMPONENTS
Core
+ ExecutionEngine
+ Object
OrcJIT
+ RuntimeDyld
Support
+ native
)
add_llvm_unittest(OrcJITTests
+ CompileOnDemandLayerTest.cpp
IndirectionUtilsTest.cpp
+ GlobalMappingLayerTest.cpp
LazyEmittingLayerTest.cpp
+ ObjectLinkingLayerTest.cpp
ObjectTransformLayerTest.cpp
+ OrcCAPITest.cpp
OrcTestCommon.cpp
)
diff --git a/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
new file mode 100644
index 000000000000..a27e649b616f
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
@@ -0,0 +1,75 @@
+//===----- 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::JITCompileCallbackManager {
+public:
+ DummyCallbackManager() : JITCompileCallbackManager(0) { }
+public:
+ void grow() override { llvm_unreachable("not implemented"); }
+};
+
+class DummyStubsManager : public orc::IndirectStubsManager {
+public:
+ std::error_code createStub(StringRef StubName, TargetAddress InitAddr,
+ JITSymbolFlags Flags) override {
+ llvm_unreachable("Not implemented");
+ }
+
+ std::error_code createStubs(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;
+
+ llvm::orc::CompileOnDemandLayer<MockBaseLayerT> COD(
+ MockBaseLayer, [](Function &F) { return std::set<Function *>{&F}; },
+ CallbackMgr, [] { return llvm::make_unique<DummyStubsManager>(); }, 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/GlobalMappingLayerTest.cpp b/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
new file mode 100644
index 000000000000..054fc16cabd4
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
@@ -0,0 +1,55 @@
+//===--- GlobalMappingLayerTest.cpp - Unit test the global mapping layer --===//
+//
+// 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/GlobalMappingLayer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::orc;
+
+namespace {
+
+struct MockBaseLayer {
+
+ typedef int ModuleSetHandleT;
+
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ if (Name == "bar")
+ return llvm::orc::JITSymbol(0x4567, JITSymbolFlags::Exported);
+ return nullptr;
+ }
+
+};
+
+TEST(GlobalMappingLayerTest, Empty) {
+ MockBaseLayer M;
+ GlobalMappingLayer<MockBaseLayer> L(M);
+
+ // Test fall-through for missing symbol.
+ auto FooSym = L.findSymbol("foo", true);
+ EXPECT_FALSE(FooSym) << "Found unexpected symbol.";
+
+ // Test fall-through for symbol in base layer.
+ auto BarSym = L.findSymbol("bar", true);
+ EXPECT_EQ(BarSym.getAddress(), static_cast<TargetAddress>(0x4567))
+ << "Symbol lookup fall-through failed.";
+
+ // Test setup of a global mapping.
+ L.setGlobalMapping("foo", 0x0123);
+ auto FooSym2 = L.findSymbol("foo", true);
+ EXPECT_EQ(FooSym2.getAddress(), static_cast<TargetAddress>(0x0123))
+ << "Symbol mapping setup failed.";
+
+ // Test removal of a global mapping.
+ L.eraseGlobalMapping("foo");
+ auto FooSym3 = L.findSymbol("foo", true);
+ EXPECT_FALSE(FooSym3) << "Symbol mapping removal failed.";
+}
+
+}
diff --git a/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp b/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
index 1a533b05838d..38b60ea7fcd4 100644
--- a/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
+++ b/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
@@ -18,7 +18,7 @@ namespace {
TEST(IndirectionUtilsTest, MakeStub) {
ModuleBuilder MB(getGlobalContext(), "x86_64-apple-macosx10.10", "");
- Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>(MB.getModule(), "");
+ Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>("");
SmallVector<AttributeSet, 4> Attrs;
Attrs.push_back(
AttributeSet::get(MB.getModule()->getContext(), 1U,
diff --git a/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
new file mode 100644
index 000000000000..a37177c5d1db
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
@@ -0,0 +1,94 @@
+//===-- ObjectLinkingLayerTest.cpp - Unit tests for object linking layer --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/LLVMContext.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::orc;
+
+namespace {
+
+TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) {
+
+ class SectionMemoryManagerWrapper : public SectionMemoryManager {
+ public:
+ SectionMemoryManagerWrapper(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;
+ };
+
+ ObjectLinkingLayer<> ObjLayer;
+
+ auto M = llvm::make_unique<Module>("", getGlobalContext());
+ M->setTargetTriple("x86_64-unknown-linux-gnu");
+ Type *Int32Ty = IntegerType::get(getGlobalContext(), 32);
+ GlobalVariable *GV =
+ new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
+ ConstantInt::get(Int32Ty, 42), "foo");
+
+ GV->setSection(".debug_str");
+
+ std::unique_ptr<TargetMachine> TM(
+ EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
+ SmallVector<std::string, 1>()));
+ if (!TM)
+ return;
+
+ auto OwningObj = SimpleCompiler(*TM)(*M);
+ std::vector<object::ObjectFile*> Objs;
+ Objs.push_back(OwningObj.getBinary());
+
+ bool DebugSectionSeen = false;
+ SectionMemoryManagerWrapper SMMW(DebugSectionSeen);
+ auto Resolver =
+ createLambdaResolver(
+ [](const std::string &Name) {
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &Name) {
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ {
+ // Test with ProcessAllSections = false (the default).
+ auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
+ EXPECT_EQ(DebugSectionSeen, false)
+ << "Unexpected debug info section";
+ ObjLayer.removeObjectSet(H);
+ }
+
+ {
+ // Test with ProcessAllSections = true.
+ ObjLayer.setProcessAllSections(true);
+ auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
+ EXPECT_EQ(DebugSectionSeen, true)
+ << "Expected debug info section not seen";
+ ObjLayer.removeObjectSet(H);
+ }
+}
+
+}
diff --git a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
index 41b2307cadd8..c88c94f17b1c 100644
--- a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
+++ b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
@@ -157,21 +157,6 @@ public:
resetExpectations();
}
- template <typename OwningMBSet>
- void takeOwnershipOfBuffers(ObjSetHandleT H, OwningMBSet MBs) {
- EXPECT_EQ(MockObjSetHandle, H);
- EXPECT_EQ(MockBufferSet, *MBs);
- LastCalled = "takeOwnershipOfBuffers";
- }
- void expectTakeOwnershipOfBuffers(ObjSetHandleT H, MockMemoryBufferSet *MBs) {
- MockObjSetHandle = H;
- MockBufferSet = *MBs;
- }
- void verifyTakeOwnershipOfBuffers() {
- EXPECT_EQ("takeOwnershipOfBuffers", LastCalled);
- resetExpectations();
- }
-
private:
// Backing fields for remembering parameter/return values
std::string LastCalled;
@@ -275,18 +260,6 @@ TEST(ObjectTransformLayerTest, Main) {
T1.mapSectionAddress(H, Buffer, MockAddress);
M.verifyMapSectionAddress();
- // Test takeOwnershipOfBuffers, using unique pointer to buffer set
- auto MockBufferSetPtr = llvm::make_unique<MockMemoryBufferSet>(366);
- M.expectTakeOwnershipOfBuffers(H, MockBufferSetPtr.get());
- T2.takeOwnershipOfBuffers(H, std::move(MockBufferSetPtr));
- M.verifyTakeOwnershipOfBuffers();
-
- // Test takeOwnershipOfBuffers, using naked pointer to buffer set
- MockMemoryBufferSet MockBufferSet = 266;
- M.expectTakeOwnershipOfBuffers(H, &MockBufferSet);
- T1.takeOwnershipOfBuffers(H, &MockBufferSet);
- M.verifyTakeOwnershipOfBuffers();
-
// Verify transform getter (non-const)
MockObjectFile Mutatee = 277;
MockObjectFile *Out = T2.getTransform()(&Mutatee);
diff --git a/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
new file mode 100644
index 000000000000..776d26970a31
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
@@ -0,0 +1,160 @@
+//===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
+//
+// 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 "gtest/gtest.h"
+#include "llvm-c/Core.h"
+#include "llvm-c/OrcBindings.h"
+#include "llvm-c/Target.h"
+#include "llvm-c/TargetMachine.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace llvm {
+
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
+
+class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
+protected:
+ std::unique_ptr<Module> createTestModule(const Triple &TT) {
+ ModuleBuilder MB(getGlobalContext(), TT.str(), "");
+ Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
+ Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
+
+ Main->getBasicBlockList().push_back(BasicBlock::Create(getGlobalContext()));
+ IRBuilder<> B(&Main->back());
+ Value* Result = B.CreateCall(TestFunc);
+ B.CreateRet(Result);
+
+ return MB.takeModule();
+ }
+
+ typedef int (*MainFnTy)();
+
+ static int myTestFuncImpl() {
+ return 42;
+ }
+
+ static char *testFuncName;
+
+ static uint64_t myResolver(const char *Name, void *Ctx) {
+ if (!strncmp(Name, testFuncName, 8))
+ return (uint64_t)&myTestFuncImpl;
+ return 0;
+ }
+
+ struct CompileContext {
+ CompileContext() : Compiled(false) { }
+
+ OrcCAPIExecutionTest* APIExecTest;
+ std::unique_ptr<Module> M;
+ LLVMOrcModuleHandle H;
+ bool Compiled;
+ };
+
+ static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
+ void *Ctx) {
+ CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
+ auto *ET = CCtx->APIExecTest;
+ CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
+ CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()),
+ myResolver, nullptr);
+ CCtx->Compiled = true;
+ LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
+ LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
+ return MainAddr;
+ }
+};
+
+char *OrcCAPIExecutionTest::testFuncName = nullptr;
+
+TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
+ if (!TM)
+ return;
+
+ LLVMOrcJITStackRef JIT =
+ LLVMOrcCreateInstance(wrap(TM.get()));
+
+ std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
+
+ LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
+
+ LLVMOrcModuleHandle H =
+ LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
+ MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
+ int Result = MainFn();
+ EXPECT_EQ(Result, 42)
+ << "Eagerly JIT'd code did not return expected result";
+
+ LLVMOrcRemoveModule(JIT, H);
+
+ LLVMOrcDisposeMangledSymbol(testFuncName);
+ LLVMOrcDisposeInstance(JIT);
+}
+
+TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
+ if (!TM)
+ return;
+
+ LLVMOrcJITStackRef JIT =
+ LLVMOrcCreateInstance(wrap(TM.get()));
+
+ std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
+
+ LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
+
+ LLVMOrcModuleHandle H =
+ LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
+ MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
+ int Result = MainFn();
+ EXPECT_EQ(Result, 42)
+ << "Lazily JIT'd code did not return expected result";
+
+ LLVMOrcRemoveModule(JIT, H);
+
+ LLVMOrcDisposeMangledSymbol(testFuncName);
+ LLVMOrcDisposeInstance(JIT);
+}
+
+TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
+ if (!TM)
+ return;
+
+ LLVMOrcJITStackRef JIT =
+ LLVMOrcCreateInstance(wrap(TM.get()));
+
+ LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
+
+ CompileContext C;
+ C.APIExecTest = this;
+ LLVMOrcCreateIndirectStub(JIT, "foo",
+ LLVMOrcCreateLazyCompileCallback(JIT,
+ myCompileCallback,
+ &C));
+ MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo");
+ int Result = FooFn();
+ EXPECT_TRUE(C.Compiled)
+ << "Function wasn't lazily compiled";
+ EXPECT_EQ(Result, 42)
+ << "Direct-callback JIT'd code did not return expected result";
+
+ C.Compiled = false;
+ FooFn();
+ EXPECT_FALSE(C.Compiled)
+ << "Direct-callback JIT'd code was JIT'd twice";
+
+ LLVMOrcRemoveModule(JIT, C.H);
+
+ LLVMOrcDisposeMangledSymbol(testFuncName);
+ LLVMOrcDisposeInstance(JIT);
+}
+
+} // namespace llvm
diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp b/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
index 5fea3c89f86c..1b5485d3b33b 100644
--- a/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
+++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
@@ -15,6 +15,8 @@
using namespace llvm;
+bool OrcExecutionTest::NativeTargetInitialized = false;
+
ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,
StringRef Name)
: M(new Module(Name, Context)),
diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/unittests/ExecutionEngine/Orc/OrcTestCommon.h
index 1b2859b51d09..15d9f54a37fc 100644
--- a/unittests/ExecutionEngine/Orc/OrcTestCommon.h
+++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -20,46 +20,159 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/TypeBuilder.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
+#include "llvm/Support/TargetSelect.h"
#include <memory>
namespace llvm {
- class ModuleBuilder {
- public:
- ModuleBuilder(LLVMContext &Context, StringRef Triple,
- StringRef Name);
+// Base class for Orc tests that will execute code.
+class OrcExecutionTest {
+public:
- template <typename FuncType>
- Function* createFunctionDecl(Module *M, StringRef Name) {
- return Function::Create(
- TypeBuilder<FuncType, false>::get(M->getContext()),
- GlobalValue::ExternalLinkage, Name, M);
+ OrcExecutionTest() {
+ if (!NativeTargetInitialized) {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmParser();
+ InitializeNativeTargetAsmPrinter();
+ NativeTargetInitialized = true;
}
- Module* getModule() { return M.get(); }
- const Module* getModule() const { return M.get(); }
- std::unique_ptr<Module> takeModule() { return std::move(M); }
+ // Try to select a TargetMachine for the host.
+ TM.reset(EngineBuilder().selectTarget());
- private:
- std::unique_ptr<Module> M;
- IRBuilder<> Builder;
+ if (TM) {
+ // If we found a TargetMachine, check that it's one that Orc supports.
+ const Triple& TT = TM->getTargetTriple();
+ if (TT.getArch() != Triple::x86_64 || !TT.isOSDarwin())
+ TM = nullptr;
+ }
};
- // Dummy struct type.
- struct DummyStruct {
- int X[256];
- };
+protected:
+ std::unique_ptr<TargetMachine> TM;
+private:
+ static bool NativeTargetInitialized;
+};
- // TypeBuilder specialization for DummyStruct.
- template <bool XCompile>
- class TypeBuilder<DummyStruct, XCompile> {
- public:
- static StructType *get(LLVMContext &Context) {
- return StructType::get(
- TypeBuilder<types::i<32>[256], XCompile>::get(Context), nullptr);
- }
- };
+class ModuleBuilder {
+public:
+ ModuleBuilder(LLVMContext &Context, StringRef Triple,
+ StringRef Name);
+
+ template <typename FuncType>
+ Function* createFunctionDecl(StringRef Name) {
+ return Function::Create(
+ TypeBuilder<FuncType, false>::get(M->getContext()),
+ GlobalValue::ExternalLinkage, Name, M.get());
+ }
+
+ Module* getModule() { return M.get(); }
+ const Module* getModule() const { return M.get(); }
+ std::unique_ptr<Module> takeModule() { return std::move(M); }
+
+private:
+ std::unique_ptr<Module> M;
+ IRBuilder<> Builder;
+};
+
+// Dummy struct type.
+struct DummyStruct {
+ int X[256];
+};
+
+// TypeBuilder specialization for DummyStruct.
+template <bool XCompile>
+class TypeBuilder<DummyStruct, XCompile> {
+public:
+ static StructType *get(LLVMContext &Context) {
+ return StructType::get(
+ TypeBuilder<types::i<32>[256], XCompile>::get(Context), nullptr);
+ }
+};
+
+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