xref: /llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp (revision 14359ef1b6a0610ac91df5f5a91c88a0b51c187c)
1ffec81caSEugene Zelenko //===- MCJITMultipeModuleTest.cpp - Unit tests for the MCJIT ----*- C++ -*-===//
26bbb2c9fSAndrew Kaylor //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66bbb2c9fSAndrew Kaylor //
76bbb2c9fSAndrew Kaylor //===----------------------------------------------------------------------===//
86bbb2c9fSAndrew Kaylor //
96bbb2c9fSAndrew Kaylor // This test suite verifies MCJIT for handling multiple modules in a single
106bbb2c9fSAndrew Kaylor // ExecutionEngine by building multiple modules, making function calls across
116bbb2c9fSAndrew Kaylor // modules, accessing global variables, etc.
126bbb2c9fSAndrew Kaylor //===----------------------------------------------------------------------===//
136bbb2c9fSAndrew Kaylor 
146bbb2c9fSAndrew Kaylor #include "MCJITTestBase.h"
159a67b073SChandler Carruth #include "llvm/ExecutionEngine/MCJIT.h"
166bbb2c9fSAndrew Kaylor #include "gtest/gtest.h"
176bbb2c9fSAndrew Kaylor 
186bbb2c9fSAndrew Kaylor using namespace llvm;
196bbb2c9fSAndrew Kaylor 
206bbb2c9fSAndrew Kaylor namespace {
216bbb2c9fSAndrew Kaylor 
2205c5a932SJuergen Ributzka class MCJITMultipleModuleTest : public testing::Test, public MCJITTestBase {};
2305c5a932SJuergen Ributzka 
246bbb2c9fSAndrew Kaylor // FIXME: ExecutionEngine has no support empty modules
256bbb2c9fSAndrew Kaylor /*
266bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, multiple_empty_modules) {
276bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
286bbb2c9fSAndrew Kaylor 
296bbb2c9fSAndrew Kaylor   createJIT(M.take());
306bbb2c9fSAndrew Kaylor   // JIT-compile
316bbb2c9fSAndrew Kaylor   EXPECT_NE(0, TheJIT->getObjectImage())
326bbb2c9fSAndrew Kaylor     << "Unable to generate executable loaded object image";
336bbb2c9fSAndrew Kaylor 
346bbb2c9fSAndrew Kaylor   TheJIT->addModule(createEmptyModule("<other module>"));
356bbb2c9fSAndrew Kaylor   TheJIT->addModule(createEmptyModule("<other other module>"));
366bbb2c9fSAndrew Kaylor 
376bbb2c9fSAndrew Kaylor   // JIT again
386bbb2c9fSAndrew Kaylor   EXPECT_NE(0, TheJIT->getObjectImage())
396bbb2c9fSAndrew Kaylor     << "Unable to generate executable loaded object image";
406bbb2c9fSAndrew Kaylor }
416bbb2c9fSAndrew Kaylor */
426bbb2c9fSAndrew Kaylor 
436bbb2c9fSAndrew Kaylor // Helper Function to test add operation
checkAdd(uint64_t ptr)446bbb2c9fSAndrew Kaylor void checkAdd(uint64_t ptr) {
456bbb2c9fSAndrew Kaylor   ASSERT_TRUE(ptr != 0) << "Unable to get pointer to function.";
466bbb2c9fSAndrew Kaylor   int (*AddPtr)(int, int) = (int (*)(int, int))ptr;
476bbb2c9fSAndrew Kaylor   EXPECT_EQ(0, AddPtr(0, 0));
486bbb2c9fSAndrew Kaylor   EXPECT_EQ(1, AddPtr(1, 0));
496bbb2c9fSAndrew Kaylor   EXPECT_EQ(3, AddPtr(1, 2));
506bbb2c9fSAndrew Kaylor   EXPECT_EQ(-5, AddPtr(-2, -3));
516bbb2c9fSAndrew Kaylor   EXPECT_EQ(30, AddPtr(10, 20));
526bbb2c9fSAndrew Kaylor   EXPECT_EQ(-30, AddPtr(-10, -20));
536bbb2c9fSAndrew Kaylor   EXPECT_EQ(-40, AddPtr(-10, -30));
546bbb2c9fSAndrew Kaylor }
556bbb2c9fSAndrew Kaylor 
checkAccumulate(uint64_t ptr)566bbb2c9fSAndrew Kaylor void checkAccumulate(uint64_t ptr) {
576bbb2c9fSAndrew Kaylor   ASSERT_TRUE(ptr != 0) << "Unable to get pointer to function.";
586bbb2c9fSAndrew Kaylor   int32_t (*FPtr)(int32_t) = (int32_t (*)(int32_t))(intptr_t)ptr;
596bbb2c9fSAndrew Kaylor   EXPECT_EQ(0, FPtr(0));
606bbb2c9fSAndrew Kaylor   EXPECT_EQ(1, FPtr(1));
616bbb2c9fSAndrew Kaylor   EXPECT_EQ(3, FPtr(2));
626bbb2c9fSAndrew Kaylor   EXPECT_EQ(6, FPtr(3));
636bbb2c9fSAndrew Kaylor   EXPECT_EQ(10, FPtr(4));
646bbb2c9fSAndrew Kaylor   EXPECT_EQ(15, FPtr(5));
656bbb2c9fSAndrew Kaylor }
666bbb2c9fSAndrew Kaylor 
676bbb2c9fSAndrew Kaylor // FIXME: ExecutionEngine has no support empty modules
686bbb2c9fSAndrew Kaylor /*
696bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, multiple_empty_modules) {
706bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
716bbb2c9fSAndrew Kaylor 
726bbb2c9fSAndrew Kaylor   createJIT(M.take());
736bbb2c9fSAndrew Kaylor   // JIT-compile
746bbb2c9fSAndrew Kaylor   EXPECT_NE(0, TheJIT->getObjectImage())
756bbb2c9fSAndrew Kaylor     << "Unable to generate executable loaded object image";
766bbb2c9fSAndrew Kaylor 
776bbb2c9fSAndrew Kaylor   TheJIT->addModule(createEmptyModule("<other module>"));
786bbb2c9fSAndrew Kaylor   TheJIT->addModule(createEmptyModule("<other other module>"));
796bbb2c9fSAndrew Kaylor 
806bbb2c9fSAndrew Kaylor   // JIT again
816bbb2c9fSAndrew Kaylor   EXPECT_NE(0, TheJIT->getObjectImage())
826bbb2c9fSAndrew Kaylor     << "Unable to generate executable loaded object image";
836bbb2c9fSAndrew Kaylor }
846bbb2c9fSAndrew Kaylor */
856bbb2c9fSAndrew Kaylor 
866bbb2c9fSAndrew Kaylor // Module A { Function FA },
876bbb2c9fSAndrew Kaylor // Module B { Function FB },
886bbb2c9fSAndrew Kaylor // execute FA then FB
TEST_F(MCJITMultipleModuleTest,two_module_case)896bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, two_module_case) {
906bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
916bbb2c9fSAndrew Kaylor 
9256440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
936bbb2c9fSAndrew Kaylor   Function *FA, *FB;
946bbb2c9fSAndrew Kaylor   createTwoModuleCase(A, FA, B, FB);
956bbb2c9fSAndrew Kaylor 
962a8a2795SRafael Espindola   createJIT(std::move(A));
972a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
986bbb2c9fSAndrew Kaylor 
996bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
1006bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1016bbb2c9fSAndrew Kaylor 
1026bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB->getName().str());
1036bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1046bbb2c9fSAndrew Kaylor }
1056bbb2c9fSAndrew Kaylor 
1066bbb2c9fSAndrew Kaylor // Module A { Function FA },
1076bbb2c9fSAndrew Kaylor // Module B { Function FB },
1086bbb2c9fSAndrew Kaylor // execute FB then FA
TEST_F(MCJITMultipleModuleTest,two_module_reverse_case)1096bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, two_module_reverse_case) {
1106bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
1116bbb2c9fSAndrew Kaylor 
11256440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
1136bbb2c9fSAndrew Kaylor   Function *FA, *FB;
1146bbb2c9fSAndrew Kaylor   createTwoModuleCase(A, FA, B, FB);
1156bbb2c9fSAndrew Kaylor 
1162a8a2795SRafael Espindola   createJIT(std::move(A));
1172a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
1186bbb2c9fSAndrew Kaylor 
1196bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
1206bbb2c9fSAndrew Kaylor   TheJIT->finalizeObject();
1216bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1226bbb2c9fSAndrew Kaylor 
1236bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FA->getName().str());
1246bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1256bbb2c9fSAndrew Kaylor }
1266bbb2c9fSAndrew Kaylor 
1276bbb2c9fSAndrew Kaylor // Module A { Function FA },
1286bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB which calls FA },
1296bbb2c9fSAndrew Kaylor // execute FB then FA
TEST_F(MCJITMultipleModuleTest,two_module_extern_reverse_case)1306bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, two_module_extern_reverse_case) {
1316bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
1326bbb2c9fSAndrew Kaylor 
13356440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
1346bbb2c9fSAndrew Kaylor   Function *FA, *FB;
1356bbb2c9fSAndrew Kaylor   createTwoModuleExternCase(A, FA, B, FB);
1366bbb2c9fSAndrew Kaylor 
1372a8a2795SRafael Espindola   createJIT(std::move(A));
1382a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
1396bbb2c9fSAndrew Kaylor 
1406bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
1416bbb2c9fSAndrew Kaylor   TheJIT->finalizeObject();
1426bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1436bbb2c9fSAndrew Kaylor 
1446bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FA->getName().str());
1456bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1466bbb2c9fSAndrew Kaylor }
1476bbb2c9fSAndrew Kaylor 
1486bbb2c9fSAndrew Kaylor // Module A { Function FA },
1496bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB which calls FA },
1506bbb2c9fSAndrew Kaylor // execute FA then FB
TEST_F(MCJITMultipleModuleTest,two_module_extern_case)1516bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, two_module_extern_case) {
1526bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
1536bbb2c9fSAndrew Kaylor 
15456440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
1556bbb2c9fSAndrew Kaylor   Function *FA, *FB;
1566bbb2c9fSAndrew Kaylor   createTwoModuleExternCase(A, FA, B, FB);
1576bbb2c9fSAndrew Kaylor 
1582a8a2795SRafael Espindola   createJIT(std::move(A));
1592a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
1606bbb2c9fSAndrew Kaylor 
1616bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
1626bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1636bbb2c9fSAndrew Kaylor 
1646bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB->getName().str());
1656bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1666bbb2c9fSAndrew Kaylor }
1676bbb2c9fSAndrew Kaylor 
1686bbb2c9fSAndrew Kaylor // Module A { Function FA1, Function FA2 which calls FA1 },
1696bbb2c9fSAndrew Kaylor // Module B { Extern FA1, Function FB which calls FA1 },
1706bbb2c9fSAndrew Kaylor // execute FB then FA2
TEST_F(MCJITMultipleModuleTest,two_module_consecutive_call_case)1716bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) {
1726bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
1736bbb2c9fSAndrew Kaylor 
17456440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
1756bbb2c9fSAndrew Kaylor   Function *FA1, *FA2, *FB;
1766bbb2c9fSAndrew Kaylor   createTwoModuleExternCase(A, FA1, B, FB);
177c0044118SJames Y Knight   FA2 = insertSimpleCallFunction(A.get(), FA1);
1786bbb2c9fSAndrew Kaylor 
1792a8a2795SRafael Espindola   createJIT(std::move(A));
1802a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
1816bbb2c9fSAndrew Kaylor 
1826bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
1836bbb2c9fSAndrew Kaylor   TheJIT->finalizeObject();
1846bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1856bbb2c9fSAndrew Kaylor 
1866bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FA2->getName().str());
1876bbb2c9fSAndrew Kaylor   checkAdd(ptr);
1886bbb2c9fSAndrew Kaylor }
1896bbb2c9fSAndrew Kaylor 
1906bbb2c9fSAndrew Kaylor // TODO:
1916bbb2c9fSAndrew Kaylor // Module A { Extern Global GVB, Global Variable GVA, Function FA loads GVB },
1926bbb2c9fSAndrew Kaylor // Module B { Extern Global GVA, Global Variable GVB, Function FB loads GVA },
1936bbb2c9fSAndrew Kaylor 
1946bbb2c9fSAndrew Kaylor 
1956bbb2c9fSAndrew Kaylor // Module A { Global Variable GVA, Function FA loads GVA },
19673378eb1SKeno Fischer // Module B { Global Variable GVB, Internal Global GVC, Function FB loads GVB },
19773378eb1SKeno Fischer // execute FB then FA, also check that the global variables are properly accesible
19873378eb1SKeno Fischer // through the ExecutionEngine APIs
TEST_F(MCJITMultipleModuleTest,two_module_global_variables_case)1996bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
2006bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
2016bbb2c9fSAndrew Kaylor 
20256440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
2036bbb2c9fSAndrew Kaylor   Function *FA, *FB;
20473378eb1SKeno Fischer   GlobalVariable *GVA, *GVB, *GVC;
205c0044118SJames Y Knight 
2066bbb2c9fSAndrew Kaylor   A.reset(createEmptyModule("A"));
2076bbb2c9fSAndrew Kaylor   B.reset(createEmptyModule("B"));
2086bbb2c9fSAndrew Kaylor 
2096bbb2c9fSAndrew Kaylor   int32_t initialNum = 7;
2106bbb2c9fSAndrew Kaylor   GVA = insertGlobalInt32(A.get(), "GVA", initialNum);
2116bbb2c9fSAndrew Kaylor   GVB = insertGlobalInt32(B.get(), "GVB", initialNum);
212c0044118SJames Y Knight   FA = startFunction(A.get(),
213c0044118SJames Y Knight                      FunctionType::get(Builder.getInt32Ty(), {}, false), "FA");
214*14359ef1SJames Y Knight   endFunctionWithRet(FA, Builder.CreateLoad(Builder.getInt32Ty(), GVA));
215c0044118SJames Y Knight   FB = startFunction(B.get(),
216c0044118SJames Y Knight                      FunctionType::get(Builder.getInt32Ty(), {}, false), "FB");
217*14359ef1SJames Y Knight   endFunctionWithRet(FB, Builder.CreateLoad(Builder.getInt32Ty(), GVB));
2186bbb2c9fSAndrew Kaylor 
21973378eb1SKeno Fischer   GVC = insertGlobalInt32(B.get(), "GVC", initialNum);
22073378eb1SKeno Fischer   GVC->setLinkage(GlobalValue::InternalLinkage);
22173378eb1SKeno Fischer 
2222a8a2795SRafael Espindola   createJIT(std::move(A));
2232a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
2246bbb2c9fSAndrew Kaylor 
22573378eb1SKeno Fischer   EXPECT_EQ(GVA, TheJIT->FindGlobalVariableNamed("GVA"));
22673378eb1SKeno Fischer   EXPECT_EQ(GVB, TheJIT->FindGlobalVariableNamed("GVB"));
22773378eb1SKeno Fischer   EXPECT_EQ(GVC, TheJIT->FindGlobalVariableNamed("GVC",true));
228083ca9bbSHans Wennborg   EXPECT_EQ(nullptr, TheJIT->FindGlobalVariableNamed("GVC"));
22973378eb1SKeno Fischer 
2306bbb2c9fSAndrew Kaylor   uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
2316bbb2c9fSAndrew Kaylor   TheJIT->finalizeObject();
2326bbb2c9fSAndrew Kaylor   EXPECT_TRUE(0 != FBPtr);
233ffec81caSEugene Zelenko   int32_t(*FuncPtr)() = (int32_t(*)())FBPtr;
2346bbb2c9fSAndrew Kaylor   EXPECT_EQ(initialNum, FuncPtr())
2356bbb2c9fSAndrew Kaylor     << "Invalid value for global returned from JITted function in module B";
2366bbb2c9fSAndrew Kaylor 
2376bbb2c9fSAndrew Kaylor   uint64_t FAPtr = TheJIT->getFunctionAddress(FA->getName().str());
2386bbb2c9fSAndrew Kaylor   EXPECT_TRUE(0 != FAPtr);
239ffec81caSEugene Zelenko   FuncPtr = (int32_t(*)())FAPtr;
2406bbb2c9fSAndrew Kaylor   EXPECT_EQ(initialNum, FuncPtr())
2416bbb2c9fSAndrew Kaylor     << "Invalid value for global returned from JITted function in module A";
2426bbb2c9fSAndrew Kaylor }
2436bbb2c9fSAndrew Kaylor 
2446bbb2c9fSAndrew Kaylor // Module A { Function FA },
2456bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB which calls FA },
2466bbb2c9fSAndrew Kaylor // Module C { Extern FA, Function FC which calls FA },
2476bbb2c9fSAndrew Kaylor // execute FC, FB, FA
TEST_F(MCJITMultipleModuleTest,three_module_case)2486bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, three_module_case) {
24939ddb3f9STim Northover   SKIP_UNSUPPORTED_PLATFORM;
25039ddb3f9STim Northover 
25156440fd8SAhmed Charles   std::unique_ptr<Module> A, B, C;
2526bbb2c9fSAndrew Kaylor   Function *FA, *FB, *FC;
2536bbb2c9fSAndrew Kaylor   createThreeModuleCase(A, FA, B, FB, C, FC);
2546bbb2c9fSAndrew Kaylor 
2552a8a2795SRafael Espindola   createJIT(std::move(A));
2562a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
2572a8a2795SRafael Espindola   TheJIT->addModule(std::move(C));
2586bbb2c9fSAndrew Kaylor 
2596bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
2606bbb2c9fSAndrew Kaylor   checkAdd(ptr);
2616bbb2c9fSAndrew Kaylor 
2626bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB->getName().str());
2636bbb2c9fSAndrew Kaylor   checkAdd(ptr);
2646bbb2c9fSAndrew Kaylor 
2656bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FA->getName().str());
2666bbb2c9fSAndrew Kaylor   checkAdd(ptr);
2676bbb2c9fSAndrew Kaylor }
2686bbb2c9fSAndrew Kaylor 
2696bbb2c9fSAndrew Kaylor // Module A { Function FA },
2706bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB which calls FA },
2716bbb2c9fSAndrew Kaylor // Module C { Extern FA, Function FC which calls FA },
2726bbb2c9fSAndrew Kaylor // execute FA, FB, FC
TEST_F(MCJITMultipleModuleTest,three_module_case_reverse_order)2736bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, three_module_case_reverse_order) {
27439ddb3f9STim Northover   SKIP_UNSUPPORTED_PLATFORM;
27539ddb3f9STim Northover 
27656440fd8SAhmed Charles   std::unique_ptr<Module> A, B, C;
2776bbb2c9fSAndrew Kaylor   Function *FA, *FB, *FC;
2786bbb2c9fSAndrew Kaylor   createThreeModuleCase(A, FA, B, FB, C, FC);
2796bbb2c9fSAndrew Kaylor 
2802a8a2795SRafael Espindola   createJIT(std::move(A));
2812a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
2822a8a2795SRafael Espindola   TheJIT->addModule(std::move(C));
2836bbb2c9fSAndrew Kaylor 
2846bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
2856bbb2c9fSAndrew Kaylor   checkAdd(ptr);
2866bbb2c9fSAndrew Kaylor 
2876bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB->getName().str());
2886bbb2c9fSAndrew Kaylor   checkAdd(ptr);
2896bbb2c9fSAndrew Kaylor 
2906bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FC->getName().str());
2916bbb2c9fSAndrew Kaylor   checkAdd(ptr);
2926bbb2c9fSAndrew Kaylor }
2936bbb2c9fSAndrew Kaylor 
2946bbb2c9fSAndrew Kaylor // Module A { Function FA },
2956bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB which calls FA },
2966bbb2c9fSAndrew Kaylor // Module C { Extern FB, Function FC which calls FB },
2976bbb2c9fSAndrew Kaylor // execute FC, FB, FA
TEST_F(MCJITMultipleModuleTest,three_module_chain_case)2986bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, three_module_chain_case) {
29939ddb3f9STim Northover   SKIP_UNSUPPORTED_PLATFORM;
30039ddb3f9STim Northover 
30156440fd8SAhmed Charles   std::unique_ptr<Module> A, B, C;
3026bbb2c9fSAndrew Kaylor   Function *FA, *FB, *FC;
3036bbb2c9fSAndrew Kaylor   createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
3046bbb2c9fSAndrew Kaylor 
3052a8a2795SRafael Espindola   createJIT(std::move(A));
3062a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
3072a8a2795SRafael Espindola   TheJIT->addModule(std::move(C));
3086bbb2c9fSAndrew Kaylor 
3096bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
3106bbb2c9fSAndrew Kaylor   checkAdd(ptr);
3116bbb2c9fSAndrew Kaylor 
3126bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB->getName().str());
3136bbb2c9fSAndrew Kaylor   checkAdd(ptr);
3146bbb2c9fSAndrew Kaylor 
3156bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FA->getName().str());
3166bbb2c9fSAndrew Kaylor   checkAdd(ptr);
3176bbb2c9fSAndrew Kaylor }
3186bbb2c9fSAndrew Kaylor 
3196bbb2c9fSAndrew Kaylor // Module A { Function FA },
3206bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB which calls FA },
3216bbb2c9fSAndrew Kaylor // Module C { Extern FB, Function FC which calls FB },
3226bbb2c9fSAndrew Kaylor // execute FA, FB, FC
TEST_F(MCJITMultipleModuleTest,three_modules_chain_case_reverse_order)3236bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, three_modules_chain_case_reverse_order) {
32439ddb3f9STim Northover   SKIP_UNSUPPORTED_PLATFORM;
32539ddb3f9STim Northover 
32656440fd8SAhmed Charles   std::unique_ptr<Module> A, B, C;
3276bbb2c9fSAndrew Kaylor   Function *FA, *FB, *FC;
3286bbb2c9fSAndrew Kaylor   createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
3296bbb2c9fSAndrew Kaylor 
3302a8a2795SRafael Espindola   createJIT(std::move(A));
3312a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
3322a8a2795SRafael Espindola   TheJIT->addModule(std::move(C));
3336bbb2c9fSAndrew Kaylor 
3346bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
3356bbb2c9fSAndrew Kaylor   checkAdd(ptr);
3366bbb2c9fSAndrew Kaylor 
3376bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB->getName().str());
3386bbb2c9fSAndrew Kaylor   checkAdd(ptr);
3396bbb2c9fSAndrew Kaylor 
3406bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FC->getName().str());
3416bbb2c9fSAndrew Kaylor   checkAdd(ptr);
3426bbb2c9fSAndrew Kaylor }
3436bbb2c9fSAndrew Kaylor 
3446bbb2c9fSAndrew Kaylor // Module A { Extern FB, Function FA which calls FB1 },
3456bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
3466bbb2c9fSAndrew Kaylor // execute FA, then FB1
3476bbb2c9fSAndrew Kaylor // FIXME: this test case is not supported by MCJIT
TEST_F(MCJITMultipleModuleTest,cross_module_dependency_case)3486bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case) {
3496bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
3506bbb2c9fSAndrew Kaylor 
35156440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
3526bbb2c9fSAndrew Kaylor   Function *FA, *FB1, *FB2;
3536bbb2c9fSAndrew Kaylor   createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
3546bbb2c9fSAndrew Kaylor 
3552a8a2795SRafael Espindola   createJIT(std::move(A));
3562a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
3576bbb2c9fSAndrew Kaylor 
3586bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
3596bbb2c9fSAndrew Kaylor   checkAccumulate(ptr);
3606bbb2c9fSAndrew Kaylor 
3616bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB1->getName().str());
3626bbb2c9fSAndrew Kaylor   checkAccumulate(ptr);
3636bbb2c9fSAndrew Kaylor }
3646bbb2c9fSAndrew Kaylor 
3656bbb2c9fSAndrew Kaylor // Module A { Extern FB, Function FA which calls FB1 },
3666bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
3676bbb2c9fSAndrew Kaylor // execute FB1 then FA
3686bbb2c9fSAndrew Kaylor // FIXME: this test case is not supported by MCJIT
TEST_F(MCJITMultipleModuleTest,cross_module_dependency_case_reverse_order)3696bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case_reverse_order) {
3706bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
3716bbb2c9fSAndrew Kaylor 
37256440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
3736bbb2c9fSAndrew Kaylor   Function *FA, *FB1, *FB2;
3746bbb2c9fSAndrew Kaylor   createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
3756bbb2c9fSAndrew Kaylor 
3762a8a2795SRafael Espindola   createJIT(std::move(A));
3772a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
3786bbb2c9fSAndrew Kaylor 
3796bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
3806bbb2c9fSAndrew Kaylor   checkAccumulate(ptr);
3816bbb2c9fSAndrew Kaylor 
3826bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FA->getName().str());
3836bbb2c9fSAndrew Kaylor   checkAccumulate(ptr);
3846bbb2c9fSAndrew Kaylor }
3856bbb2c9fSAndrew Kaylor 
3866bbb2c9fSAndrew Kaylor // Module A { Extern FB1, Function FA which calls FB1 },
3876bbb2c9fSAndrew Kaylor // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
3886bbb2c9fSAndrew Kaylor // execute FB1 then FB2
3896bbb2c9fSAndrew Kaylor // FIXME: this test case is not supported by MCJIT
TEST_F(MCJITMultipleModuleTest,cross_module_dependency_case3)3906bbb2c9fSAndrew Kaylor TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case3) {
3916bbb2c9fSAndrew Kaylor   SKIP_UNSUPPORTED_PLATFORM;
3926bbb2c9fSAndrew Kaylor 
39356440fd8SAhmed Charles   std::unique_ptr<Module> A, B;
3946bbb2c9fSAndrew Kaylor   Function *FA, *FB1, *FB2;
3956bbb2c9fSAndrew Kaylor   createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
3966bbb2c9fSAndrew Kaylor 
3972a8a2795SRafael Espindola   createJIT(std::move(A));
3982a8a2795SRafael Espindola   TheJIT->addModule(std::move(B));
3996bbb2c9fSAndrew Kaylor 
4006bbb2c9fSAndrew Kaylor   uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
4016bbb2c9fSAndrew Kaylor   checkAccumulate(ptr);
4026bbb2c9fSAndrew Kaylor 
4036bbb2c9fSAndrew Kaylor   ptr = TheJIT->getFunctionAddress(FB2->getName().str());
4046bbb2c9fSAndrew Kaylor   checkAccumulate(ptr);
4056bbb2c9fSAndrew Kaylor }
4065f92a08fSKeno Fischer 
4075f92a08fSKeno Fischer // Test that FindFunctionNamed finds the definition of
4085f92a08fSKeno Fischer // a function in the correct module. We check two functions
4095f92a08fSKeno Fischer // in two different modules, to make sure that for at least
4105f92a08fSKeno Fischer // one of them MCJIT had to ignore the extern declaration.
TEST_F(MCJITMultipleModuleTest,FindFunctionNamed_test)4115f92a08fSKeno Fischer TEST_F(MCJITMultipleModuleTest, FindFunctionNamed_test) {
4125f92a08fSKeno Fischer   SKIP_UNSUPPORTED_PLATFORM;
4135f92a08fSKeno Fischer 
4145f92a08fSKeno Fischer   std::unique_ptr<Module> A, B;
4155f92a08fSKeno Fischer   Function *FA, *FB1, *FB2;
4165f92a08fSKeno Fischer   createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
4175f92a08fSKeno Fischer 
4185f92a08fSKeno Fischer   createJIT(std::move(A));
4195f92a08fSKeno Fischer   TheJIT->addModule(std::move(B));
4205f92a08fSKeno Fischer 
4215f92a08fSKeno Fischer   EXPECT_EQ(FA, TheJIT->FindFunctionNamed(FA->getName().data()));
4225f92a08fSKeno Fischer   EXPECT_EQ(FB1, TheJIT->FindFunctionNamed(FB1->getName().data()));
4235f92a08fSKeno Fischer }
4245f92a08fSKeno Fischer 
425083ca9bbSHans Wennborg } // end anonymous namespace
426