2015-10-28 10:40:04 +08:00
|
|
|
//===--------------- 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 {
|
|
|
|
|
2015-11-04 22:40:54 +08:00
|
|
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
2015-10-28 10:40:04 +08:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2015-11-05 06:32:32 +08:00
|
|
|
typedef int (*MainFnTy)();
|
2015-10-28 10:40:04 +08:00
|
|
|
|
2015-11-05 06:32:32 +08:00
|
|
|
static int myTestFuncImpl() {
|
2015-10-28 10:40:04 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-10-30 11:20:21 +08:00
|
|
|
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()),
|
2015-11-05 06:32:32 +08:00
|
|
|
myResolver, nullptr);
|
2015-10-30 11:20:21 +08:00
|
|
|
CCtx->Compiled = true;
|
|
|
|
LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
|
|
|
|
LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
|
|
|
|
return MainAddr;
|
|
|
|
}
|
2015-10-28 10:40:04 +08:00
|
|
|
};
|
|
|
|
|
2015-11-05 06:32:32 +08:00
|
|
|
char *OrcCAPIExecutionTest::testFuncName = nullptr;
|
2015-10-28 10:40:04 +08:00
|
|
|
|
|
|
|
TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
|
|
|
|
if (!TM)
|
|
|
|
return;
|
|
|
|
|
|
|
|
LLVMOrcJITStackRef JIT =
|
2015-11-04 00:40:37 +08:00
|
|
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
2015-10-28 10:40:04 +08:00
|
|
|
|
2015-10-30 11:20:21 +08:00
|
|
|
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
|
|
|
|
2015-10-28 10:40:04 +08:00
|
|
|
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
|
|
|
|
|
|
|
LLVMOrcModuleHandle H =
|
2015-11-05 06:32:32 +08:00
|
|
|
LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
|
2015-10-28 10:40:04 +08:00
|
|
|
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 =
|
2015-11-04 00:40:37 +08:00
|
|
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
2015-10-28 10:40:04 +08:00
|
|
|
|
2015-10-30 11:20:21 +08:00
|
|
|
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
|
|
|
|
2015-10-28 10:40:04 +08:00
|
|
|
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
2015-10-30 11:20:21 +08:00
|
|
|
|
2015-10-28 10:40:04 +08:00
|
|
|
LLVMOrcModuleHandle H =
|
2015-11-05 06:32:32 +08:00
|
|
|
LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
|
2015-10-28 10:40:04 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-10-30 11:20:21 +08:00
|
|
|
TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
|
|
|
|
if (!TM)
|
|
|
|
return;
|
|
|
|
|
|
|
|
LLVMOrcJITStackRef JIT =
|
2015-11-04 00:40:37 +08:00
|
|
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
2015-10-30 11:20:21 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-11-05 06:32:32 +08:00
|
|
|
} // namespace llvm
|