diff options
Diffstat (limited to 'llvm/unittests/ExecutionEngine/Orc')
5 files changed, 150 insertions, 3 deletions
diff --git a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt index 031eea5f5af..dc401c9743e 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt +++ b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt @@ -1,7 +1,11 @@ + set(LLVM_LINK_COMPONENTS Core OrcJIT + MC Support + Target + native ) add_llvm_unittest(OrcJITTests @@ -10,5 +14,6 @@ add_llvm_unittest(OrcJITTests GlobalMappingLayerTest.cpp LazyEmittingLayerTest.cpp ObjectTransformLayerTest.cpp + OrcCAPITest.cpp OrcTestCommon.cpp ) diff --git a/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp index 1a533b05838..38b60ea7fcd 100644 --- a/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp +++ b/llvm/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/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp new file mode 100644 index 00000000000..bddb6a76bbf --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp @@ -0,0 +1,109 @@ +//===--------------- 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/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)(void); + + static int myTestFuncImpl(void) { + 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; + } + +}; + +char *OrcCAPIExecutionTest::testFuncName = 0; + +TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) { + auto TM = getHostTargetMachineIfSupported(); + + if (!TM) + return; + + std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple()); + + LLVMOrcJITStackRef JIT = + LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext()); + + LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); + + LLVMOrcModuleHandle H = + LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, 0); + 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) { + auto TM = getHostTargetMachineIfSupported(); + + if (!TM) + return; + + std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple()); + + LLVMOrcJITStackRef JIT = + LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext()); + + LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); + LLVMOrcModuleHandle H = + LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, 0); + 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); +} + +} diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp index 5fea3c89f86..1b5485d3b33 100644 --- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp +++ b/llvm/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/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h index 4be2e196707..18e3874acaf 100644 --- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h +++ b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h @@ -20,21 +20,52 @@ #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 { +// Base class for Orc tests that will execute code. +class OrcExecutionTest { +public: + + OrcExecutionTest() { + if (!NativeTargetInitialized) { + InitializeNativeTarget(); + InitializeNativeTargetAsmParser(); + InitializeNativeTargetAsmPrinter(); + NativeTargetInitialized = true; + } + }; + + // Get a target machine for the host if it supports JIT execution. + std::unique_ptr<TargetMachine> getHostTargetMachineIfSupported() { + std::unique_ptr<TargetMachine> TM(EngineBuilder().selectTarget()); + + const Triple& TT = TM->getTargetTriple(); + + if (TT.getArch() == Triple::x86_64) + return std::move(TM); + + return nullptr; + } + +private: + static bool NativeTargetInitialized; +}; + class ModuleBuilder { public: ModuleBuilder(LLVMContext &Context, StringRef Triple, StringRef Name); template <typename FuncType> - Function* createFunctionDecl(Module *M, StringRef Name) { + Function* createFunctionDecl(StringRef Name) { return Function::Create( TypeBuilder<FuncType, false>::get(M->getContext()), - GlobalValue::ExternalLinkage, Name, M); + GlobalValue::ExternalLinkage, Name, M.get()); } Module* getModule() { return M.get(); } |