1 //===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "OrcTestCommon.h"
11 #include "gtest/gtest.h"
12 #include "llvm-c/OrcBindings.h"
13 #include "llvm-c/Target.h"
14 #include "llvm-c/TargetMachine.h"
22 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
24 class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
26 std::unique_ptr<Module> createTestModule(const Triple &TT) {
27 ModuleBuilder MB(getGlobalContext(), TT.str(), "");
28 Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
29 Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
31 Main->getBasicBlockList().push_back(BasicBlock::Create(getGlobalContext()));
32 IRBuilder<> B(&Main->back());
33 Value* Result = B.CreateCall(TestFunc);
36 return MB.takeModule();
39 typedef int (*MainFnTy)();
41 static int myTestFuncImpl() {
45 static char *testFuncName;
47 static uint64_t myResolver(const char *Name, void *Ctx) {
48 if (!strncmp(Name, testFuncName, 8))
49 return (uint64_t)&myTestFuncImpl;
53 struct CompileContext {
54 CompileContext() : Compiled(false) { }
56 OrcCAPIExecutionTest* APIExecTest;
57 std::unique_ptr<Module> M;
58 LLVMOrcModuleHandle H;
62 static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
64 CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
65 auto *ET = CCtx->APIExecTest;
66 CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
67 CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()),
69 CCtx->Compiled = true;
70 LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
71 LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
76 char *OrcCAPIExecutionTest::testFuncName = nullptr;
78 TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
82 LLVMOrcJITStackRef JIT =
83 LLVMOrcCreateInstance(wrap(TM.get()));
85 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
87 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
89 LLVMOrcModuleHandle H =
90 LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
91 MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
92 int Result = MainFn();
94 << "Eagerly JIT'd code did not return expected result";
96 LLVMOrcRemoveModule(JIT, H);
98 LLVMOrcDisposeMangledSymbol(testFuncName);
99 LLVMOrcDisposeInstance(JIT);
102 TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
106 LLVMOrcJITStackRef JIT =
107 LLVMOrcCreateInstance(wrap(TM.get()));
109 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
111 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
113 LLVMOrcModuleHandle H =
114 LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
115 MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
116 int Result = MainFn();
117 EXPECT_EQ(Result, 42)
118 << "Lazily JIT'd code did not return expected result";
120 LLVMOrcRemoveModule(JIT, H);
122 LLVMOrcDisposeMangledSymbol(testFuncName);
123 LLVMOrcDisposeInstance(JIT);
126 TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
130 LLVMOrcJITStackRef JIT =
131 LLVMOrcCreateInstance(wrap(TM.get()));
133 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
136 C.APIExecTest = this;
137 LLVMOrcCreateIndirectStub(JIT, "foo",
138 LLVMOrcCreateLazyCompileCallback(JIT,
141 MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo");
142 int Result = FooFn();
143 EXPECT_TRUE(C.Compiled)
144 << "Function wasn't lazily compiled";
145 EXPECT_EQ(Result, 42)
146 << "Direct-callback JIT'd code did not return expected result";
150 EXPECT_FALSE(C.Compiled)
151 << "Direct-callback JIT'd code was JIT'd twice";
153 LLVMOrcRemoveModule(JIT, C.H);
155 LLVMOrcDisposeMangledSymbol(testFuncName);
156 LLVMOrcDisposeInstance(JIT);