blob: 2957a3c1570994e8c45e6d32d704eda3c2e76227 [file] [log] [blame]
Lang Hames130a7c42015-10-28 02:40:04 +00001//===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
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"
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20namespace llvm {
21
22DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef);
23
24class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
25protected:
26
27 std::unique_ptr<Module> createTestModule(const Triple &TT) {
28 ModuleBuilder MB(getGlobalContext(), TT.str(), "");
29 Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
30 Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
31
32 Main->getBasicBlockList().push_back(BasicBlock::Create(getGlobalContext()));
33 IRBuilder<> B(&Main->back());
34 Value* Result = B.CreateCall(TestFunc);
35 B.CreateRet(Result);
36
37 return MB.takeModule();
38 }
39
40 typedef int (*MainFnTy)(void);
41
42 static int myTestFuncImpl(void) {
43 return 42;
44 }
45
46 static char *testFuncName;
47
48 static uint64_t myResolver(const char *Name, void *Ctx) {
49 if (!strncmp(Name, testFuncName, 8))
50 return (uint64_t)&myTestFuncImpl;
51 return 0;
52 }
53
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000054 struct CompileContext {
55 CompileContext() : Compiled(false) { }
56
57 OrcCAPIExecutionTest* APIExecTest;
58 std::unique_ptr<Module> M;
59 LLVMOrcModuleHandle H;
60 bool Compiled;
61 };
62
63 static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
64 void *Ctx) {
65 CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
66 auto *ET = CCtx->APIExecTest;
67 CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
68 CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()),
69 myResolver, 0);
70 CCtx->Compiled = true;
71 LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
72 LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
73 return MainAddr;
74 }
75
Lang Hames130a7c42015-10-28 02:40:04 +000076};
77
78char *OrcCAPIExecutionTest::testFuncName = 0;
79
80TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
Lang Hames130a7c42015-10-28 02:40:04 +000081 if (!TM)
82 return;
83
Lang Hames130a7c42015-10-28 02:40:04 +000084 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +000085 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hames130a7c42015-10-28 02:40:04 +000086
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000087 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
88
Lang Hames130a7c42015-10-28 02:40:04 +000089 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
90
91 LLVMOrcModuleHandle H =
92 LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
93 MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
94 int Result = MainFn();
95 EXPECT_EQ(Result, 42)
96 << "Eagerly JIT'd code did not return expected result";
97
98 LLVMOrcRemoveModule(JIT, H);
99
100 LLVMOrcDisposeMangledSymbol(testFuncName);
101 LLVMOrcDisposeInstance(JIT);
102}
103
104TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
Lang Hames130a7c42015-10-28 02:40:04 +0000105 if (!TM)
106 return;
107
Lang Hames130a7c42015-10-28 02:40:04 +0000108 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +0000109 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hames130a7c42015-10-28 02:40:04 +0000110
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000111 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
112
Lang Hames130a7c42015-10-28 02:40:04 +0000113 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000114
Lang Hames130a7c42015-10-28 02:40:04 +0000115 LLVMOrcModuleHandle H =
116 LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
117 MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
118 int Result = MainFn();
119 EXPECT_EQ(Result, 42)
120 << "Lazily JIT'd code did not return expected result";
121
122 LLVMOrcRemoveModule(JIT, H);
123
124 LLVMOrcDisposeMangledSymbol(testFuncName);
125 LLVMOrcDisposeInstance(JIT);
126}
127
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000128TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
129 if (!TM)
130 return;
131
132 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +0000133 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000134
135 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
136
137 CompileContext C;
138 C.APIExecTest = this;
139 LLVMOrcCreateIndirectStub(JIT, "foo",
140 LLVMOrcCreateLazyCompileCallback(JIT,
141 myCompileCallback,
142 &C));
143 MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo");
144 int Result = FooFn();
145 EXPECT_TRUE(C.Compiled)
146 << "Function wasn't lazily compiled";
147 EXPECT_EQ(Result, 42)
148 << "Direct-callback JIT'd code did not return expected result";
149
150 C.Compiled = false;
151 FooFn();
152 EXPECT_FALSE(C.Compiled)
153 << "Direct-callback JIT'd code was JIT'd twice";
154
155 LLVMOrcRemoveModule(JIT, C.H);
156
157 LLVMOrcDisposeMangledSymbol(testFuncName);
158 LLVMOrcDisposeInstance(JIT);
159}
160
Lang Hames130a7c42015-10-28 02:40:04 +0000161}