123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- //===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "OrcTestCommon.h"
- #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
- #include "llvm-c/Core.h"
- #include "llvm-c/OrcBindings.h"
- #include "llvm-c/Target.h"
- #include "llvm-c/TargetMachine.h"
- #include "gtest/gtest.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(Context, TT.str(), "");
- Type *IntTy = Type::getScalarTy<int>(Context);
- Function *TestFunc =
- MB.createFunctionDecl(FunctionType::get(IntTy, {}, false), "testFunc");
- Function *Main = MB.createFunctionDecl(
- FunctionType::get(
- IntTy,
- {IntTy, Type::getInt8PtrTy(Context)->getPointerTo()},
- false),
- "main");
- Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
- IRBuilder<> B(&Main->back());
- Value* Result = B.CreateCall(TestFunc);
- B.CreateRet(Result);
- return MB.takeModule();
- }
- std::unique_ptr<MemoryBuffer> createTestObject() {
- orc::SimpleCompiler IRCompiler(*TM);
- auto M = createTestModule(TM->getTargetTriple());
- M->setDataLayout(TM->createDataLayout());
- return IRCompiler(*M);
- }
- 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());
- LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, wrap(CCtx->M.release()),
- myResolver, nullptr);
- CCtx->Compiled = true;
- LLVMOrcTargetAddress MainAddr;
- LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main");
- LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
- return MainAddr;
- }
- };
- char *OrcCAPIExecutionTest::testFuncName = nullptr;
- TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
- if (!SupportsJIT)
- return;
- LLVMOrcJITStackRef JIT =
- LLVMOrcCreateInstance(wrap(TM.get()));
- std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
- LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
- LLVMOrcModuleHandle H;
- LLVMOrcAddEagerlyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr);
- // get symbol address searching the entire stack
- {
- LLVMOrcTargetAddress MainAddr;
- LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
- MainFnTy MainFn = (MainFnTy)MainAddr;
- int Result = MainFn();
- EXPECT_EQ(Result, 42)
- << "Eagerly JIT'd code did not return expected result";
- }
- // and then just searching a single handle
- {
- LLVMOrcTargetAddress MainAddr;
- LLVMOrcGetSymbolAddressIn(JIT, &MainAddr, H, "main");
- MainFnTy MainFn = (MainFnTy)MainAddr;
- 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 (!SupportsIndirection)
- return;
- LLVMOrcJITStackRef JIT =
- LLVMOrcCreateInstance(wrap(TM.get()));
- std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
- LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
- LLVMOrcModuleHandle H;
- LLVMOrcAddLazilyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr);
- LLVMOrcTargetAddress MainAddr;
- LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
- MainFnTy MainFn = (MainFnTy)MainAddr;
- 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, TestAddObjectFile) {
- if (!SupportsJIT)
- return;
- auto ObjBuffer = createTestObject();
- LLVMOrcJITStackRef JIT =
- LLVMOrcCreateInstance(wrap(TM.get()));
- LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
- LLVMOrcModuleHandle H;
- LLVMOrcAddObjectFile(JIT, &H, wrap(ObjBuffer.release()), myResolver, nullptr);
- LLVMOrcTargetAddress MainAddr;
- LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
- MainFnTy MainFn = (MainFnTy)MainAddr;
- 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 (!SupportsIndirection)
- return;
- LLVMOrcJITStackRef JIT =
- LLVMOrcCreateInstance(wrap(TM.get()));
- LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
- CompileContext C;
- C.APIExecTest = this;
- LLVMOrcTargetAddress CCAddr;
- LLVMOrcCreateLazyCompileCallback(JIT, &CCAddr, myCompileCallback, &C);
- LLVMOrcCreateIndirectStub(JIT, "foo", CCAddr);
- LLVMOrcTargetAddress MainAddr;
- LLVMOrcGetSymbolAddress(JIT, &MainAddr, "foo");
- MainFnTy FooFn = (MainFnTy)MainAddr;
- 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
|