170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor//===- MCJITMultipeModuleTest.cpp - Unit tests for the MCJIT---------------===// 270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// 370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// The LLVM Compiler Infrastructure 470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// 570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// This file is distributed under the University of Illinois Open Source 670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// License. See LICENSE.TXT for details. 770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// 870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor//===----------------------------------------------------------------------===// 970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// 1070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// This test suite verifies MCJIT for handling multiple modules in a single 1170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// ExecutionEngine by building multiple modules, making function calls across 1270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// modules, accessing global variables, etc. 1370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor//===----------------------------------------------------------------------===// 1470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 1570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor#include "llvm/ExecutionEngine/MCJIT.h" 1670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor#include "MCJITTestBase.h" 1770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor#include "gtest/gtest.h" 1870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 1970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylorusing namespace llvm; 2070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 2170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylornamespace { 2270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 239d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendlingclass MCJITMultipleModuleTest : public testing::Test, public MCJITTestBase {}; 249d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendling 2570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// FIXME: ExecutionEngine has no support empty modules 2670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor/* 2770c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, multiple_empty_modules) { 2870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 2970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 3070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createJIT(M.take()); 3170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // JIT-compile 3270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_NE(0, TheJIT->getObjectImage()) 3370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor << "Unable to generate executable loaded object image"; 3470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 3570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->addModule(createEmptyModule("<other module>")); 3670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->addModule(createEmptyModule("<other other module>")); 3770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 3870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // JIT again 3970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_NE(0, TheJIT->getObjectImage()) 4070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor << "Unable to generate executable loaded object image"; 4170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 4270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor*/ 4370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 4470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Helper Function to test add operation 4570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylorvoid checkAdd(uint64_t ptr) { 4670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ASSERT_TRUE(ptr != 0) << "Unable to get pointer to function."; 4770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor int (*AddPtr)(int, int) = (int (*)(int, int))ptr; 4870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(0, AddPtr(0, 0)); 4970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(1, AddPtr(1, 0)); 5070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(3, AddPtr(1, 2)); 5170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(-5, AddPtr(-2, -3)); 5270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(30, AddPtr(10, 20)); 5370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(-30, AddPtr(-10, -20)); 5470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(-40, AddPtr(-10, -30)); 5570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 5670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 5770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylorvoid checkAccumulate(uint64_t ptr) { 5870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ASSERT_TRUE(ptr != 0) << "Unable to get pointer to function."; 5970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor int32_t (*FPtr)(int32_t) = (int32_t (*)(int32_t))(intptr_t)ptr; 6070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(0, FPtr(0)); 6170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(1, FPtr(1)); 6270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(3, FPtr(2)); 6370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(6, FPtr(3)); 6470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(10, FPtr(4)); 6570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(15, FPtr(5)); 6670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 6770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 6870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// FIXME: ExecutionEngine has no support empty modules 6970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor/* 7070c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, multiple_empty_modules) { 7170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 7270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 7370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createJIT(M.take()); 7470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // JIT-compile 7570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_NE(0, TheJIT->getObjectImage()) 7670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor << "Unable to generate executable loaded object image"; 7770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 7870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->addModule(createEmptyModule("<other module>")); 7970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->addModule(createEmptyModule("<other other module>")); 8070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 8170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // JIT again 8270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_NE(0, TheJIT->getObjectImage()) 8370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor << "Unable to generate executable loaded object image"; 8470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 8570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor*/ 8670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 8770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 8870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Function FB }, 8970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FA then FB 9070c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, two_module_case) { 9170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 9270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 9470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB; 9570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createTwoModuleCase(A, FA, B, FB); 9670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 9970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 10070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str()); 10170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 10270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 10370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB->getName().str()); 10470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 10570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 10670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 10770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 10870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Function FB }, 10970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FB then FA 11070c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, two_module_reverse_case) { 11170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 11270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 11470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB; 11570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createTwoModuleCase(A, FA, B, FB); 11670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 11970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 12070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str()); 12170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->finalizeObject(); 12270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 12370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 12470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FA->getName().str()); 12570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 12670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 12770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 12870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 12970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB which calls FA }, 13070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FB then FA 13170c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, two_module_extern_reverse_case) { 13270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 13370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 13570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB; 13670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createTwoModuleExternCase(A, FA, B, FB); 13770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 14070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 14170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str()); 14270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->finalizeObject(); 14370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 14470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 14570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FA->getName().str()); 14670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 14770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 14870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 14970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 15070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB which calls FA }, 15170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FA then FB 15270c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, two_module_extern_case) { 15370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 15470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 15670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB; 15770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createTwoModuleExternCase(A, FA, B, FB); 15870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 16170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 16270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str()); 16370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 16470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 16570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB->getName().str()); 16670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 16770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 16870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 16970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA1, Function FA2 which calls FA1 }, 17070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA1, Function FB which calls FA1 }, 17170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FB then FA2 17270c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) { 17370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 17470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 17670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA1, *FA2, *FB; 17770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createTwoModuleExternCase(A, FA1, B, FB); 17870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1); 17970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 18270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 18370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str()); 18470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->finalizeObject(); 18570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 18670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 18770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FA2->getName().str()); 18870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 18970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 19070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 19170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// TODO: 19270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Extern Global GVB, Global Variable GVA, Function FA loads GVB }, 19370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern Global GVA, Global Variable GVB, Function FB loads GVA }, 19470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 19570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 19670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Global Variable GVA, Function FA loads GVA }, 19770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Global Variable GVB, Function FB loads GVB }, 19870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FB then FA 19970c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) { 20070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 20170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 20370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB; 20470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor GlobalVariable *GVA, *GVB; 20570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor A.reset(createEmptyModule("A")); 20670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor B.reset(createEmptyModule("B")); 20770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 20870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor int32_t initialNum = 7; 20970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor GVA = insertGlobalInt32(A.get(), "GVA", initialNum); 21070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor GVB = insertGlobalInt32(B.get(), "GVB", initialNum); 21170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FA = startFunction<int32_t(void)>(A.get(), "FA"); 21270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor endFunctionWithRet(FA, Builder.CreateLoad(GVA)); 21370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FB = startFunction<int32_t(void)>(B.get(), "FB"); 21470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor endFunctionWithRet(FB, Builder.CreateLoad(GVB)); 21570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 21870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 21970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str()); 22070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor TheJIT->finalizeObject(); 22170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_TRUE(0 != FBPtr); 22270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor int32_t(*FuncPtr)(void) = (int32_t(*)(void))FBPtr; 22370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(initialNum, FuncPtr()) 22470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor << "Invalid value for global returned from JITted function in module B"; 22570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 22670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t FAPtr = TheJIT->getFunctionAddress(FA->getName().str()); 22770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_TRUE(0 != FAPtr); 22870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FuncPtr = (int32_t(*)(void))FAPtr; 22970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor EXPECT_EQ(initialNum, FuncPtr()) 23070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor << "Invalid value for global returned from JITted function in module A"; 23170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 23270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 23370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 23470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB which calls FA }, 23570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module C { Extern FA, Function FC which calls FA }, 23670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FC, FB, FA 23770c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, three_module_case) { 238ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover SKIP_UNSUPPORTED_PLATFORM; 239ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B, C; 24170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB, *FC; 24270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createThreeModuleCase(A, FA, B, FB, C, FC); 24370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(C)); 24770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 24870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str()); 24970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 25070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 25170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB->getName().str()); 25270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 25370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 25470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FA->getName().str()); 25570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 25670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 25770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 25870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 25970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB which calls FA }, 26070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module C { Extern FA, Function FC which calls FA }, 26170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FA, FB, FC 26270c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, three_module_case_reverse_order) { 263ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover SKIP_UNSUPPORTED_PLATFORM; 264ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B, C; 26670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB, *FC; 26770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createThreeModuleCase(A, FA, B, FB, C, FC); 26870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(C)); 27270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 27370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str()); 27470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 27570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 27670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB->getName().str()); 27770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 27870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 27970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FC->getName().str()); 28070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 28170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 28270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 28370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 28470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB which calls FA }, 28570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module C { Extern FB, Function FC which calls FB }, 28670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FC, FB, FA 28770c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, three_module_chain_case) { 288ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover SKIP_UNSUPPORTED_PLATFORM; 289ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B, C; 29170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB, *FC; 29270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC); 29370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(C)); 29770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 29870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str()); 29970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 30070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 30170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB->getName().str()); 30270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 30370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 30470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FA->getName().str()); 30570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 30670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 30770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 30870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Function FA }, 30970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB which calls FA }, 31070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module C { Extern FB, Function FC which calls FB }, 31170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FA, FB, FC 31270c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, three_modules_chain_case_reverse_order) { 313ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover SKIP_UNSUPPORTED_PLATFORM; 314ea246d6af8f112001c8b13ffcc9c4fcc6ad992a2Tim Northover 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B, C; 31670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB, *FC; 31770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC); 31870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 31937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 32137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(C)); 32270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 32370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str()); 32470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 32570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 32670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB->getName().str()); 32770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 32870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 32970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FC->getName().str()); 33070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAdd(ptr); 33170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 33270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 33370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Extern FB, Function FA which calls FB1 }, 33470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB1, Function FB2 which calls FA }, 33570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FA, then FB1 33670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// FIXME: this test case is not supported by MCJIT 33770c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, cross_module_dependency_case) { 33870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 33970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 34170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB1, *FB2; 34270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createCrossModuleRecursiveCase(A, FA, B, FB1, FB2); 34370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 34670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 34770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str()); 34870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAccumulate(ptr); 34970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 35070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB1->getName().str()); 35170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAccumulate(ptr); 35270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 35370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 35470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Extern FB, Function FA which calls FB1 }, 35570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB1, Function FB2 which calls FA }, 35670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FB1 then FA 35770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// FIXME: this test case is not supported by MCJIT 35870c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, cross_module_dependency_case_reverse_order) { 35970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 36070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 36270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB1, *FB2; 36370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createCrossModuleRecursiveCase(A, FA, B, FB1, FB2); 36470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 36770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 36870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str()); 36970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAccumulate(ptr); 37070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 37170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FA->getName().str()); 37270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAccumulate(ptr); 37370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 37470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 37570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module A { Extern FB1, Function FA which calls FB1 }, 37670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// Module B { Extern FA, Function FB1, Function FB2 which calls FA }, 37770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// execute FB1 then FB2 37870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor// FIXME: this test case is not supported by MCJIT 37970c1ea493e6156eccde5270c139ef423b19ab580Andrew KaylorTEST_F(MCJITMultipleModuleTest, cross_module_dependency_case3) { 38070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor SKIP_UNSUPPORTED_PLATFORM; 38170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> A, B; 38370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FA, *FB1, *FB2; 38470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor createCrossModuleRecursiveCase(A, FA, B, FB1, FB2); 38570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createJIT(std::move(A)); 38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TheJIT->addModule(std::move(B)); 38870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 38970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str()); 39070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAccumulate(ptr); 39170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 39270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor ptr = TheJIT->getFunctionAddress(FB2->getName().str()); 39370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor checkAccumulate(ptr); 39470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Test that FindFunctionNamed finds the definition of 397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// a function in the correct module. We check two functions 398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// in two different modules, to make sure that for at least 399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// one of them MCJIT had to ignore the extern declaration. 400ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesTEST_F(MCJITMultipleModuleTest, FindFunctionNamed_test) { 401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SKIP_UNSUPPORTED_PLATFORM; 402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 403ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<Module> A, B; 404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *FA, *FB1, *FB2; 405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines createCrossModuleRecursiveCase(A, FA, B, FB1, FB2); 406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines createJIT(std::move(A)); 408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheJIT->addModule(std::move(B)); 409ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EXPECT_EQ(FA, TheJIT->FindFunctionNamed(FA->getName().data())); 411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EXPECT_EQ(FB1, TheJIT->FindFunctionNamed(FB1->getName().data())); 412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 41470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor} 415