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