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