diff options
Diffstat (limited to 'gnu/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp')
| -rw-r--r-- | gnu/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp new file mode 100644 index 00000000000..776d26970a3 --- /dev/null +++ b/gnu/llvm/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 |
