MCJITMultipleModuleTest.cpp 11 KB

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