Tests for MCJIT multiple module support
[oota-llvm.git] / unittests / ExecutionEngine / MCJIT / MCJITMultipleModuleTest.cpp
1 //===- MCJITMultipeModuleTest.cpp - Unit tests for the MCJIT---------------===//
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 // This test suite verifies MCJIT for handling multiple modules in a single
11 // ExecutionEngine by building multiple modules, making function calls across
12 // modules, accessing global variables, etc.
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/ExecutionEngine/MCJIT.h"
16 #include "MCJITTestBase.h"
17 #include "gtest/gtest.h"
18
19 using namespace llvm;
20
21 class MCJITMultipleModuleTest : public testing::Test, public MCJITTestBase {};
22
23 namespace {
24
25 // FIXME: ExecutionEngine has no support empty modules
26 /*
27 TEST_F(MCJITMultipleModuleTest, multiple_empty_modules) {
28   SKIP_UNSUPPORTED_PLATFORM;
29
30   createJIT(M.take());
31   // JIT-compile
32   EXPECT_NE(0, TheJIT->getObjectImage())
33     << "Unable to generate executable loaded object image";
34
35   TheJIT->addModule(createEmptyModule("<other module>"));
36   TheJIT->addModule(createEmptyModule("<other other module>"));
37
38   // JIT again
39   EXPECT_NE(0, TheJIT->getObjectImage())
40     << "Unable to generate executable loaded object image";
41 }
42 */
43
44 // Helper Function to test add operation
45 void checkAdd(uint64_t ptr) {
46   ASSERT_TRUE(ptr != 0) << "Unable to get pointer to function.";
47   int (*AddPtr)(int, int) = (int (*)(int, int))ptr;
48   EXPECT_EQ(0, AddPtr(0, 0));
49   EXPECT_EQ(1, AddPtr(1, 0));
50   EXPECT_EQ(3, AddPtr(1, 2));
51   EXPECT_EQ(-5, AddPtr(-2, -3));
52   EXPECT_EQ(30, AddPtr(10, 20));
53   EXPECT_EQ(-30, AddPtr(-10, -20));
54   EXPECT_EQ(-40, AddPtr(-10, -30));
55 }
56
57 void checkAccumulate(uint64_t ptr) {
58   ASSERT_TRUE(ptr != 0) << "Unable to get pointer to function.";
59   int32_t (*FPtr)(int32_t) = (int32_t (*)(int32_t))(intptr_t)ptr;
60   EXPECT_EQ(0, FPtr(0));
61   EXPECT_EQ(1, FPtr(1));
62   EXPECT_EQ(3, FPtr(2));
63   EXPECT_EQ(6, FPtr(3));
64   EXPECT_EQ(10, FPtr(4));
65   EXPECT_EQ(15, FPtr(5));
66 }
67
68 // FIXME: ExecutionEngine has no support empty modules
69 /*
70 TEST_F(MCJITMultipleModuleTest, multiple_empty_modules) {
71   SKIP_UNSUPPORTED_PLATFORM;
72
73   createJIT(M.take());
74   // JIT-compile
75   EXPECT_NE(0, TheJIT->getObjectImage())
76     << "Unable to generate executable loaded object image";
77
78   TheJIT->addModule(createEmptyModule("<other module>"));
79   TheJIT->addModule(createEmptyModule("<other other module>"));
80
81   // JIT again
82   EXPECT_NE(0, TheJIT->getObjectImage())
83     << "Unable to generate executable loaded object image";
84 }
85 */
86
87 // Module A { Function FA },
88 // Module B { Function FB },
89 // execute FA then FB
90 TEST_F(MCJITMultipleModuleTest, two_module_case) {
91   SKIP_UNSUPPORTED_PLATFORM;
92
93   OwningPtr<Module> A, B;
94   Function *FA, *FB;
95   createTwoModuleCase(A, FA, B, FB);
96
97   createJIT(A.take());
98   TheJIT->addModule(B.take());
99
100   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
101   checkAdd(ptr);
102
103   ptr = TheJIT->getFunctionAddress(FB->getName().str());
104   checkAdd(ptr);
105 }
106
107 // Module A { Function FA },
108 // Module B { Function FB },
109 // execute FB then FA
110 TEST_F(MCJITMultipleModuleTest, two_module_reverse_case) {
111   SKIP_UNSUPPORTED_PLATFORM;
112
113   OwningPtr<Module> A, B;
114   Function *FA, *FB;
115   createTwoModuleCase(A, FA, B, FB);
116
117   createJIT(A.take());
118   TheJIT->addModule(B.take());
119
120   uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
121   TheJIT->finalizeObject();
122   checkAdd(ptr);
123
124   ptr = TheJIT->getFunctionAddress(FA->getName().str());
125   checkAdd(ptr);
126 }
127
128 // Module A { Function FA },
129 // Module B { Extern FA, Function FB which calls FA },
130 // execute FB then FA
131 TEST_F(MCJITMultipleModuleTest, two_module_extern_reverse_case) {
132   SKIP_UNSUPPORTED_PLATFORM;
133
134   OwningPtr<Module> A, B;
135   Function *FA, *FB;
136   createTwoModuleExternCase(A, FA, B, FB);
137
138   createJIT(A.take());
139   TheJIT->addModule(B.take());
140
141   uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
142   TheJIT->finalizeObject();
143   checkAdd(ptr);
144
145   ptr = TheJIT->getFunctionAddress(FA->getName().str());
146   checkAdd(ptr);
147 }
148
149 // Module A { Function FA },
150 // Module B { Extern FA, Function FB which calls FA },
151 // execute FA then FB
152 TEST_F(MCJITMultipleModuleTest, two_module_extern_case) {
153   SKIP_UNSUPPORTED_PLATFORM;
154
155   OwningPtr<Module> A, B;
156   Function *FA, *FB;
157   createTwoModuleExternCase(A, FA, B, FB);
158
159   createJIT(A.take());
160   TheJIT->addModule(B.take());
161
162   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
163   checkAdd(ptr);
164
165   ptr = TheJIT->getFunctionAddress(FB->getName().str());
166   checkAdd(ptr);
167 }
168
169 // Module A { Function FA1, Function FA2 which calls FA1 },
170 // Module B { Extern FA1, Function FB which calls FA1 },
171 // execute FB then FA2
172 TEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) {
173   SKIP_UNSUPPORTED_PLATFORM;
174
175   OwningPtr<Module> A, B;
176   Function *FA1, *FA2, *FB;
177   createTwoModuleExternCase(A, FA1, B, FB);
178   FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1);
179
180   createJIT(A.take());
181   TheJIT->addModule(B.take());
182
183   uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
184   TheJIT->finalizeObject();
185   checkAdd(ptr);
186
187   ptr = TheJIT->getFunctionAddress(FA2->getName().str());
188   checkAdd(ptr);
189 }
190
191 // TODO:
192 // Module A { Extern Global GVB, Global Variable GVA, Function FA loads GVB },
193 // Module B { Extern Global GVA, Global Variable GVB, Function FB loads GVA },
194
195
196 // Module A { Global Variable GVA, Function FA loads GVA },
197 // Module B { Global Variable GVB, Function FB loads GVB },
198 // execute FB then FA
199 TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
200   SKIP_UNSUPPORTED_PLATFORM;
201
202   OwningPtr<Module> A, B;
203   Function *FA, *FB;
204   GlobalVariable *GVA, *GVB;
205   A.reset(createEmptyModule("A"));
206   B.reset(createEmptyModule("B"));
207
208   int32_t initialNum = 7;
209   GVA = insertGlobalInt32(A.get(), "GVA", initialNum);
210   GVB = insertGlobalInt32(B.get(), "GVB", initialNum);
211   FA = startFunction<int32_t(void)>(A.get(), "FA");
212   endFunctionWithRet(FA, Builder.CreateLoad(GVA));
213   FB = startFunction<int32_t(void)>(B.get(), "FB");
214   endFunctionWithRet(FB, Builder.CreateLoad(GVB));
215
216   createJIT(A.take());
217   TheJIT->addModule(B.take());
218
219   uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
220   TheJIT->finalizeObject();
221   EXPECT_TRUE(0 != FBPtr);
222   int32_t(*FuncPtr)(void) = (int32_t(*)(void))FBPtr;
223   EXPECT_EQ(initialNum, FuncPtr())
224     << "Invalid value for global returned from JITted function in module B";
225
226   uint64_t FAPtr = TheJIT->getFunctionAddress(FA->getName().str());
227   EXPECT_TRUE(0 != FAPtr);
228   FuncPtr = (int32_t(*)(void))FAPtr;
229   EXPECT_EQ(initialNum, FuncPtr())
230     << "Invalid value for global returned from JITted function in module A";
231 }
232
233 // Module A { Function FA },
234 // Module B { Extern FA, Function FB which calls FA },
235 // Module C { Extern FA, Function FC which calls FA },
236 // execute FC, FB, FA
237 TEST_F(MCJITMultipleModuleTest, three_module_case) {
238   OwningPtr<Module> A, B, C;
239   Function *FA, *FB, *FC;
240   createThreeModuleCase(A, FA, B, FB, C, FC);
241
242   createJIT(A.take());
243   TheJIT->addModule(B.take());
244   TheJIT->addModule(C.take());
245
246   uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
247   checkAdd(ptr);
248
249   ptr = TheJIT->getFunctionAddress(FB->getName().str());
250   checkAdd(ptr);
251
252   ptr = TheJIT->getFunctionAddress(FA->getName().str());
253   checkAdd(ptr);
254 }
255
256 // Module A { Function FA },
257 // Module B { Extern FA, Function FB which calls FA },
258 // Module C { Extern FA, Function FC which calls FA },
259 // execute FA, FB, FC
260 TEST_F(MCJITMultipleModuleTest, three_module_case_reverse_order) {
261   OwningPtr<Module> A, B, C;
262   Function *FA, *FB, *FC;
263   createThreeModuleCase(A, FA, B, FB, C, FC);
264
265   createJIT(A.take());
266   TheJIT->addModule(B.take());
267   TheJIT->addModule(C.take());
268
269   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
270   checkAdd(ptr);
271
272   ptr = TheJIT->getFunctionAddress(FB->getName().str());
273   checkAdd(ptr);
274
275   ptr = TheJIT->getFunctionAddress(FC->getName().str());
276   checkAdd(ptr);
277 }
278
279 // Module A { Function FA },
280 // Module B { Extern FA, Function FB which calls FA },
281 // Module C { Extern FB, Function FC which calls FB },
282 // execute FC, FB, FA
283 TEST_F(MCJITMultipleModuleTest, three_module_chain_case) {
284   OwningPtr<Module> A, B, C;
285   Function *FA, *FB, *FC;
286   createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
287
288   createJIT(A.take());
289   TheJIT->addModule(B.take());
290   TheJIT->addModule(C.take());
291
292   uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
293   checkAdd(ptr);
294
295   ptr = TheJIT->getFunctionAddress(FB->getName().str());
296   checkAdd(ptr);
297
298   ptr = TheJIT->getFunctionAddress(FA->getName().str());
299   checkAdd(ptr);
300 }
301
302 // Module A { Function FA },
303 // Module B { Extern FA, Function FB which calls FA },
304 // Module C { Extern FB, Function FC which calls FB },
305 // execute FA, FB, FC
306 TEST_F(MCJITMultipleModuleTest, three_modules_chain_case_reverse_order) {
307   OwningPtr<Module> A, B, C;
308   Function *FA, *FB, *FC;
309   createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
310
311   createJIT(A.take());
312   TheJIT->addModule(B.take());
313   TheJIT->addModule(C.take());
314
315   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
316   checkAdd(ptr);
317
318   ptr = TheJIT->getFunctionAddress(FB->getName().str());
319   checkAdd(ptr);
320
321   ptr = TheJIT->getFunctionAddress(FC->getName().str());
322   checkAdd(ptr);
323 }
324
325 // Module A { Extern FB, Function FA which calls FB1 },
326 // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
327 // execute FA, then FB1
328 // FIXME: this test case is not supported by MCJIT
329 TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case) {
330   SKIP_UNSUPPORTED_PLATFORM;
331
332   OwningPtr<Module> A, B;
333   Function *FA, *FB1, *FB2;
334   createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
335
336   createJIT(A.take());
337   TheJIT->addModule(B.take());
338
339   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
340   checkAccumulate(ptr);
341
342   ptr = TheJIT->getFunctionAddress(FB1->getName().str());
343   checkAccumulate(ptr);
344 }
345
346 // Module A { Extern FB, Function FA which calls FB1 },
347 // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
348 // execute FB1 then FA
349 // FIXME: this test case is not supported by MCJIT
350 TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case_reverse_order) {
351   SKIP_UNSUPPORTED_PLATFORM;
352
353   OwningPtr<Module> A, B;
354   Function *FA, *FB1, *FB2;
355   createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
356
357   createJIT(A.take());
358   TheJIT->addModule(B.take());
359
360   uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
361   checkAccumulate(ptr);
362
363   ptr = TheJIT->getFunctionAddress(FA->getName().str());
364   checkAccumulate(ptr);
365 }
366
367 // Module A { Extern FB1, Function FA which calls FB1 },
368 // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
369 // execute FB1 then FB2
370 // FIXME: this test case is not supported by MCJIT
371 TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case3) {
372   SKIP_UNSUPPORTED_PLATFORM;
373
374   OwningPtr<Module> A, B;
375   Function *FA, *FB1, *FB2;
376   createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
377
378   createJIT(A.take());
379   TheJIT->addModule(B.take());
380
381   uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
382   checkAccumulate(ptr);
383
384   ptr = TheJIT->getFunctionAddress(FB2->getName().str());
385   checkAccumulate(ptr);
386 }
387 }