blob: ca445b4d4e1570f783df89d3ae4fa9dd4dc6a67e [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"
Lang Hamesec300632017-09-17 03:25:03 +000011#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
Eric Christophera6b96002015-12-18 01:46:52 +000012#include "llvm-c/Core.h"
Lang Hames130a7c42015-10-28 02:40:04 +000013#include "llvm-c/OrcBindings.h"
14#include "llvm-c/Target.h"
15#include "llvm-c/TargetMachine.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +000016#include "gtest/gtest.h"
Lang Hames130a7c42015-10-28 02:40:04 +000017
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000018#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
Lang Hames130a7c42015-10-28 02:40:04 +000021
22namespace llvm {
23
Aaron Ballman5db085d2015-11-04 14:40:54 +000024DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
Lang Hames130a7c42015-10-28 02:40:04 +000025
26class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
27protected:
Lang Hames130a7c42015-10-28 02:40:04 +000028 std::unique_ptr<Module> createTestModule(const Triple &TT) {
Mehdi Amini03b42e42016-04-14 21:59:01 +000029 ModuleBuilder MB(Context, TT.str(), "");
Lang Hames130a7c42015-10-28 02:40:04 +000030 Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
31 Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
32
Mehdi Amini03b42e42016-04-14 21:59:01 +000033 Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
Lang Hames130a7c42015-10-28 02:40:04 +000034 IRBuilder<> B(&Main->back());
35 Value* Result = B.CreateCall(TestFunc);
36 B.CreateRet(Result);
37
38 return MB.takeModule();
39 }
40
Lang Hames589eece2018-02-21 21:55:49 +000041 std::unique_ptr<MemoryBuffer> createTestObject() {
Lang Hamesec300632017-09-17 03:25:03 +000042 orc::SimpleCompiler IRCompiler(*TM);
43 auto M = createTestModule(TM->getTargetTriple());
44 M->setDataLayout(TM->createDataLayout());
Lang Hames589eece2018-02-21 21:55:49 +000045 return IRCompiler(*M);
Lang Hamesec300632017-09-17 03:25:03 +000046 }
47
Eugene Zelenkoffec81c2015-11-04 22:32:32 +000048 typedef int (*MainFnTy)();
Lang Hames130a7c42015-10-28 02:40:04 +000049
Eugene Zelenkoffec81c2015-11-04 22:32:32 +000050 static int myTestFuncImpl() {
Lang Hames130a7c42015-10-28 02:40:04 +000051 return 42;
52 }
53
54 static char *testFuncName;
55
56 static uint64_t myResolver(const char *Name, void *Ctx) {
57 if (!strncmp(Name, testFuncName, 8))
58 return (uint64_t)&myTestFuncImpl;
59 return 0;
60 }
61
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000062 struct CompileContext {
63 CompileContext() : Compiled(false) { }
64
65 OrcCAPIExecutionTest* APIExecTest;
66 std::unique_ptr<Module> M;
67 LLVMOrcModuleHandle H;
68 bool Compiled;
69 };
70
71 static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
72 void *Ctx) {
73 CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
74 auto *ET = CCtx->APIExecTest;
75 CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
Lang Hamescd9d49b2017-06-23 23:25:28 +000076 LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(CCtx->M.release()));
Lang Hames4ce98662017-07-07 02:59:13 +000077 LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, SM, myResolver, nullptr);
Lang Hamescd9d49b2017-06-23 23:25:28 +000078 LLVMOrcDisposeSharedModuleRef(SM);
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000079 CCtx->Compiled = true;
Lang Hames4ce98662017-07-07 02:59:13 +000080 LLVMOrcTargetAddress MainAddr;
81 LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main");
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000082 LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
83 return MainAddr;
84 }
Lang Hames130a7c42015-10-28 02:40:04 +000085};
86
Eugene Zelenkoffec81c2015-11-04 22:32:32 +000087char *OrcCAPIExecutionTest::testFuncName = nullptr;
Lang Hames130a7c42015-10-28 02:40:04 +000088
89TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
Lang Hames130a7c42015-10-28 02:40:04 +000090 if (!TM)
91 return;
92
Lang Hames130a7c42015-10-28 02:40:04 +000093 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +000094 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hames130a7c42015-10-28 02:40:04 +000095
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000096 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
97
Lang Hames130a7c42015-10-28 02:40:04 +000098 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
99
Lang Hamescd9d49b2017-06-23 23:25:28 +0000100 LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
Lang Hames4ce98662017-07-07 02:59:13 +0000101 LLVMOrcModuleHandle H;
102 LLVMOrcAddEagerlyCompiledIR(JIT, &H, SM, myResolver, nullptr);
Lang Hamescd9d49b2017-06-23 23:25:28 +0000103 LLVMOrcDisposeSharedModuleRef(SM);
Lang Hames4ce98662017-07-07 02:59:13 +0000104 LLVMOrcTargetAddress MainAddr;
105 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
106 MainFnTy MainFn = (MainFnTy)MainAddr;
Lang Hames130a7c42015-10-28 02:40:04 +0000107 int Result = MainFn();
108 EXPECT_EQ(Result, 42)
109 << "Eagerly JIT'd code did not return expected result";
110
111 LLVMOrcRemoveModule(JIT, H);
112
113 LLVMOrcDisposeMangledSymbol(testFuncName);
114 LLVMOrcDisposeInstance(JIT);
115}
116
117TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
Lang Hames130a7c42015-10-28 02:40:04 +0000118 if (!TM)
119 return;
120
Lang Hames130a7c42015-10-28 02:40:04 +0000121 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +0000122 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hames130a7c42015-10-28 02:40:04 +0000123
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000124 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
125
Lang Hames130a7c42015-10-28 02:40:04 +0000126 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000127
Lang Hamescd9d49b2017-06-23 23:25:28 +0000128 LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
Lang Hames4ce98662017-07-07 02:59:13 +0000129 LLVMOrcModuleHandle H;
130 LLVMOrcAddLazilyCompiledIR(JIT, &H, SM, myResolver, nullptr);
Lang Hamescd9d49b2017-06-23 23:25:28 +0000131 LLVMOrcDisposeSharedModuleRef(SM);
Lang Hames4ce98662017-07-07 02:59:13 +0000132 LLVMOrcTargetAddress MainAddr;
133 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
134 MainFnTy MainFn = (MainFnTy)MainAddr;
Lang Hames130a7c42015-10-28 02:40:04 +0000135 int Result = MainFn();
136 EXPECT_EQ(Result, 42)
137 << "Lazily JIT'd code did not return expected result";
138
139 LLVMOrcRemoveModule(JIT, H);
140
141 LLVMOrcDisposeMangledSymbol(testFuncName);
142 LLVMOrcDisposeInstance(JIT);
143}
144
Lang Hamesec300632017-09-17 03:25:03 +0000145TEST_F(OrcCAPIExecutionTest, TestAddObjectFile) {
146 if (!TM)
147 return;
148
Lang Hames589eece2018-02-21 21:55:49 +0000149 auto ObjBuffer = createTestObject();
Lang Hamesec300632017-09-17 03:25:03 +0000150
151 LLVMOrcJITStackRef JIT =
152 LLVMOrcCreateInstance(wrap(TM.get()));
153 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
154
155 LLVMOrcModuleHandle H;
156 LLVMOrcAddObjectFile(JIT, &H, wrap(ObjBuffer.release()), myResolver, nullptr);
157 LLVMOrcTargetAddress MainAddr;
158 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
159 MainFnTy MainFn = (MainFnTy)MainAddr;
160 int Result = MainFn();
161 EXPECT_EQ(Result, 42)
162 << "Lazily JIT'd code did not return expected result";
163
164 LLVMOrcRemoveModule(JIT, H);
165
166 LLVMOrcDisposeMangledSymbol(testFuncName);
167 LLVMOrcDisposeInstance(JIT);
168}
169
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000170TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
171 if (!TM)
172 return;
173
174 LLVMOrcJITStackRef JIT =
Rafael Espindolae63e0182015-11-03 16:40:37 +0000175 LLVMOrcCreateInstance(wrap(TM.get()));
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000176
177 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
178
179 CompileContext C;
180 C.APIExecTest = this;
Lang Hames4ce98662017-07-07 02:59:13 +0000181 LLVMOrcTargetAddress CCAddr;
182 LLVMOrcCreateLazyCompileCallback(JIT, &CCAddr, myCompileCallback, &C);
183 LLVMOrcCreateIndirectStub(JIT, "foo", CCAddr);
184 LLVMOrcTargetAddress MainAddr;
185 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "foo");
186 MainFnTy FooFn = (MainFnTy)MainAddr;
Lang Hamesfd6e8dc2015-10-30 03:20:21 +0000187 int Result = FooFn();
188 EXPECT_TRUE(C.Compiled)
189 << "Function wasn't lazily compiled";
190 EXPECT_EQ(Result, 42)
191 << "Direct-callback JIT'd code did not return expected result";
192
193 C.Compiled = false;
194 FooFn();
195 EXPECT_FALSE(C.Compiled)
196 << "Direct-callback JIT'd code was JIT'd twice";
197
198 LLVMOrcRemoveModule(JIT, C.H);
199
200 LLVMOrcDisposeMangledSymbol(testFuncName);
201 LLVMOrcDisposeInstance(JIT);
202}
203
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000204} // namespace llvm