blob: 5a4d6b4a2252b3c08c16dd4b10ca1247043c4128 [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"
Eric Christophera6b96002015-12-18 01:46:52 +000011#include "llvm-c/Core.h"
Lang Hames130a7c42015-10-28 02:40:04 +000012#include "llvm-c/OrcBindings.h"
13#include "llvm-c/Target.h"
14#include "llvm-c/TargetMachine.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +000015#include "gtest/gtest.h"
Lang Hames130a7c42015-10-28 02:40:04 +000016
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000017#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
Lang Hames130a7c42015-10-28 02:40:04 +000020
21namespace llvm {
22
Aaron Ballman5db085d2015-11-04 14:40:54 +000023DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
Lang Hames130a7c42015-10-28 02:40:04 +000024
25class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
26protected:
Lang Hames130a7c42015-10-28 02:40:04 +000027 std::unique_ptr<Module> createTestModule(const Triple &TT) {
Mehdi Amini03b42e42016-04-14 21:59:01 +000028 ModuleBuilder MB(Context, TT.str(), "");
Lang Hames130a7c42015-10-28 02:40:04 +000029 Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
30 Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
31
Mehdi Amini03b42e42016-04-14 21:59:01 +000032 Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
Lang Hames130a7c42015-10-28 02:40:04 +000033 IRBuilder<> B(&Main->back());
34 Value* Result = B.CreateCall(TestFunc);
35 B.CreateRet(Result);
36
37 return MB.takeModule();
38 }
39
Eugene Zelenkoffec81c2015-11-04 22:32:32 +000040 typedef int (*MainFnTy)();
Lang Hames130a7c42015-10-28 02:40:04 +000041
Eugene Zelenkoffec81c2015-11-04 22:32:32 +000042 static int myTestFuncImpl() {
Lang Hames130a7c42015-10-28 02:40:04 +000043 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());
Lang Hamescd9d49b2017-06-23 23:25:28 +000068 LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(CCtx->M.release()));
Lang Hames4ce98662017-07-07 02:59:13 +000069 LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, SM, myResolver, nullptr);
Lang Hamescd9d49b2017-06-23 23:25:28 +000070 LLVMOrcDisposeSharedModuleRef(SM);
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000071 CCtx->Compiled = true;
Lang Hames4ce98662017-07-07 02:59:13 +000072 LLVMOrcTargetAddress MainAddr;
73 LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main");
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000074 LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
75 return MainAddr;
76 }
Lang Hames130a7c42015-10-28 02:40:04 +000077};
78
Eugene Zelenkoffec81c2015-11-04 22:32:32 +000079char *OrcCAPIExecutionTest::testFuncName = nullptr;
Lang Hames130a7c42015-10-28 02:40:04 +000080
81TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
Lang Hames130a7c42015-10-28 02:40:04 +000082 if (!TM)
83 return;
84
Lang Hames130a7c42015-10-28 02:40:04 +000085 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +000086 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hames130a7c42015-10-28 02:40:04 +000087
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000088 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
89
Lang Hames130a7c42015-10-28 02:40:04 +000090 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
91
Lang Hamescd9d49b2017-06-23 23:25:28 +000092 LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
Lang Hames4ce98662017-07-07 02:59:13 +000093 LLVMOrcModuleHandle H;
94 LLVMOrcAddEagerlyCompiledIR(JIT, &H, SM, myResolver, nullptr);
Lang Hamescd9d49b2017-06-23 23:25:28 +000095 LLVMOrcDisposeSharedModuleRef(SM);
Lang Hames4ce98662017-07-07 02:59:13 +000096 LLVMOrcTargetAddress MainAddr;
97 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
98 MainFnTy MainFn = (MainFnTy)MainAddr;
Lang Hames130a7c42015-10-28 02:40:04 +000099 int Result = MainFn();
100 EXPECT_EQ(Result, 42)
101 << "Eagerly JIT'd code did not return expected result";
102
103 LLVMOrcRemoveModule(JIT, H);
104
105 LLVMOrcDisposeMangledSymbol(testFuncName);
106 LLVMOrcDisposeInstance(JIT);
107}
108
109TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
Lang Hames130a7c42015-10-28 02:40:04 +0000110 if (!TM)
111 return;
112
Lang Hames130a7c42015-10-28 02:40:04 +0000113 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +0000114 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hames130a7c42015-10-28 02:40:04 +0000115
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000116 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
117
Lang Hames130a7c42015-10-28 02:40:04 +0000118 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000119
Lang Hamescd9d49b2017-06-23 23:25:28 +0000120 LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
Lang Hames4ce98662017-07-07 02:59:13 +0000121 LLVMOrcModuleHandle H;
122 LLVMOrcAddLazilyCompiledIR(JIT, &H, SM, myResolver, nullptr);
Lang Hamescd9d49b2017-06-23 23:25:28 +0000123 LLVMOrcDisposeSharedModuleRef(SM);
Lang Hames4ce98662017-07-07 02:59:13 +0000124 LLVMOrcTargetAddress MainAddr;
125 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
126 MainFnTy MainFn = (MainFnTy)MainAddr;
Lang Hames130a7c42015-10-28 02:40:04 +0000127 int Result = MainFn();
128 EXPECT_EQ(Result, 42)
129 << "Lazily JIT'd code did not return expected result";
130
131 LLVMOrcRemoveModule(JIT, H);
132
133 LLVMOrcDisposeMangledSymbol(testFuncName);
134 LLVMOrcDisposeInstance(JIT);
135}
136
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000137TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
138 if (!TM)
139 return;
140
141 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +0000142 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000143
144 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
145
146 CompileContext C;
147 C.APIExecTest = this;
Lang Hames4ce98662017-07-07 02:59:13 +0000148 LLVMOrcTargetAddress CCAddr;
149 LLVMOrcCreateLazyCompileCallback(JIT, &CCAddr, myCompileCallback, &C);
150 LLVMOrcCreateIndirectStub(JIT, "foo", CCAddr);
151 LLVMOrcTargetAddress MainAddr;
152 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "foo");
153 MainFnTy FooFn = (MainFnTy)MainAddr;
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000154 int Result = FooFn();
155 EXPECT_TRUE(C.Compiled)
156 << "Function wasn't lazily compiled";
157 EXPECT_EQ(Result, 42)
158 << "Direct-callback JIT'd code did not return expected result";
159
160 C.Compiled = false;
161 FooFn();
162 EXPECT_FALSE(C.Compiled)
163 << "Direct-callback JIT'd code was JIT'd twice";
164
165 LLVMOrcRemoveModule(JIT, C.H);
166
167 LLVMOrcDisposeMangledSymbol(testFuncName);
168 LLVMOrcDisposeInstance(JIT);
169}
170
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000171} // namespace llvm