2
0

BitReaderTest.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. //===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
  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. #include "llvm/ADT/SmallString.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/AsmParser/Parser.h"
  12. #include "llvm/Bitcode/BitstreamWriter.h"
  13. #include "llvm/Bitcode/ReaderWriter.h"
  14. #include "llvm/IR/Constants.h"
  15. #include "llvm/IR/Instructions.h"
  16. #include "llvm/IR/LLVMContext.h"
  17. #include "llvm/IR/Module.h"
  18. #include "llvm/IR/Verifier.h"
  19. #include "llvm/Support/DataStream.h"
  20. #include "llvm/Support/Debug.h"
  21. #include "llvm/Support/MemoryBuffer.h"
  22. #include "llvm/Support/SourceMgr.h"
  23. #include "gtest/gtest.h"
  24. using namespace llvm;
  25. namespace {
  26. std::unique_ptr<Module> parseAssembly(const char *Assembly) {
  27. SMDiagnostic Error;
  28. std::unique_ptr<Module> M =
  29. parseAssemblyString(Assembly, Error, getGlobalContext());
  30. std::string ErrMsg;
  31. raw_string_ostream OS(ErrMsg);
  32. Error.print("", OS);
  33. // A failure here means that the test itself is buggy.
  34. if (!M)
  35. report_fatal_error(OS.str().c_str());
  36. return M;
  37. }
  38. static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
  39. SmallVectorImpl<char> &Buffer) {
  40. raw_svector_ostream OS(Buffer);
  41. WriteBitcodeToFile(Mod.get(), OS);
  42. }
  43. static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
  44. SmallString<1024> &Mem,
  45. const char *Assembly) {
  46. writeModuleToBuffer(parseAssembly(Assembly), Mem);
  47. std::unique_ptr<MemoryBuffer> Buffer =
  48. MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
  49. ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
  50. getLazyBitcodeModule(std::move(Buffer), Context);
  51. return std::move(ModuleOrErr.get());
  52. }
  53. class BufferDataStreamer : public DataStreamer {
  54. std::unique_ptr<MemoryBuffer> Buffer;
  55. unsigned Pos = 0;
  56. size_t GetBytes(unsigned char *Out, size_t Len) override {
  57. StringRef Buf = Buffer->getBuffer();
  58. size_t Left = Buf.size() - Pos;
  59. Len = std::min(Left, Len);
  60. memcpy(Out, Buffer->getBuffer().substr(Pos).data(), Len);
  61. Pos += Len;
  62. return Len;
  63. }
  64. public:
  65. BufferDataStreamer(std::unique_ptr<MemoryBuffer> Buffer)
  66. : Buffer(std::move(Buffer)) {}
  67. };
  68. static std::unique_ptr<Module>
  69. getStreamedModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem,
  70. const char *Assembly) {
  71. writeModuleToBuffer(parseAssembly(Assembly), Mem);
  72. std::unique_ptr<MemoryBuffer> Buffer =
  73. MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
  74. auto Streamer = llvm::make_unique<BufferDataStreamer>(std::move(Buffer));
  75. ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
  76. getStreamedBitcodeModule("test", std::move(Streamer), Context);
  77. return std::move(ModuleOrErr.get());
  78. }
  79. TEST(BitReaderTest, MateralizeForwardRefWithStream) {
  80. SmallString<1024> Mem;
  81. LLVMContext Context;
  82. std::unique_ptr<Module> M = getStreamedModuleFromAssembly(
  83. Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
  84. "define void @func() {\n"
  85. " unreachable\n"
  86. "bb:\n"
  87. " unreachable\n"
  88. "}\n");
  89. EXPECT_FALSE(M->getFunction("func")->empty());
  90. }
  91. TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) {
  92. SmallString<1024> Mem;
  93. LLVMContext Context;
  94. std::unique_ptr<Module> M = getLazyModuleFromAssembly(
  95. Context, Mem, "define internal i32 @func() {\n"
  96. "ret i32 0\n"
  97. "}\n");
  98. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  99. M->getFunction("func")->materialize();
  100. EXPECT_FALSE(M->getFunction("func")->empty());
  101. EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
  102. GlobalValue::InternalLinkage);
  103. // Check that the linkage type is preserved after dematerialization.
  104. M->getFunction("func")->dematerialize();
  105. EXPECT_TRUE(M->getFunction("func")->empty());
  106. EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
  107. GlobalValue::InternalLinkage);
  108. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  109. }
  110. // Tests that lazy evaluation can parse functions out of order.
  111. TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
  112. SmallString<1024> Mem;
  113. LLVMContext Context;
  114. std::unique_ptr<Module> M = getLazyModuleFromAssembly(
  115. Context, Mem, "define void @f() {\n"
  116. " unreachable\n"
  117. "}\n"
  118. "define void @g() {\n"
  119. " unreachable\n"
  120. "}\n"
  121. "define void @h() {\n"
  122. " unreachable\n"
  123. "}\n"
  124. "define void @j() {\n"
  125. " unreachable\n"
  126. "}\n");
  127. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  128. Function *F = M->getFunction("f");
  129. Function *G = M->getFunction("g");
  130. Function *H = M->getFunction("h");
  131. Function *J = M->getFunction("j");
  132. // Initially all functions are not materialized (no basic blocks).
  133. EXPECT_TRUE(F->empty());
  134. EXPECT_TRUE(G->empty());
  135. EXPECT_TRUE(H->empty());
  136. EXPECT_TRUE(J->empty());
  137. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  138. // Materialize h.
  139. H->materialize();
  140. EXPECT_TRUE(F->empty());
  141. EXPECT_TRUE(G->empty());
  142. EXPECT_FALSE(H->empty());
  143. EXPECT_TRUE(J->empty());
  144. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  145. // Materialize g.
  146. G->materialize();
  147. EXPECT_TRUE(F->empty());
  148. EXPECT_FALSE(G->empty());
  149. EXPECT_FALSE(H->empty());
  150. EXPECT_TRUE(J->empty());
  151. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  152. // Materialize j.
  153. J->materialize();
  154. EXPECT_TRUE(F->empty());
  155. EXPECT_FALSE(G->empty());
  156. EXPECT_FALSE(H->empty());
  157. EXPECT_FALSE(J->empty());
  158. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  159. // Materialize f.
  160. F->materialize();
  161. EXPECT_FALSE(F->empty());
  162. EXPECT_FALSE(G->empty());
  163. EXPECT_FALSE(H->empty());
  164. EXPECT_FALSE(J->empty());
  165. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  166. }
  167. TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
  168. SmallString<1024> Mem;
  169. LLVMContext Context;
  170. std::unique_ptr<Module> M = getLazyModuleFromAssembly(
  171. Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
  172. "define void @func() {\n"
  173. " unreachable\n"
  174. "bb:\n"
  175. " unreachable\n"
  176. "}\n");
  177. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  178. // Try (and fail) to dematerialize @func.
  179. M->getFunction("func")->dematerialize();
  180. EXPECT_FALSE(M->getFunction("func")->empty());
  181. }
  182. TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
  183. SmallString<1024> Mem;
  184. LLVMContext Context;
  185. std::unique_ptr<Module> M = getLazyModuleFromAssembly(
  186. Context, Mem, "define i8* @before() {\n"
  187. " ret i8* blockaddress(@func, %bb)\n"
  188. "}\n"
  189. "define void @other() {\n"
  190. " unreachable\n"
  191. "}\n"
  192. "define void @func() {\n"
  193. " unreachable\n"
  194. "bb:\n"
  195. " unreachable\n"
  196. "}\n");
  197. EXPECT_TRUE(M->getFunction("before")->empty());
  198. EXPECT_TRUE(M->getFunction("func")->empty());
  199. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  200. // Materialize @before, pulling in @func.
  201. EXPECT_FALSE(M->getFunction("before")->materialize());
  202. EXPECT_FALSE(M->getFunction("func")->empty());
  203. EXPECT_TRUE(M->getFunction("other")->empty());
  204. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  205. // Try (and fail) to dematerialize @func.
  206. M->getFunction("func")->dematerialize();
  207. EXPECT_FALSE(M->getFunction("func")->empty());
  208. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  209. }
  210. TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
  211. SmallString<1024> Mem;
  212. LLVMContext Context;
  213. std::unique_ptr<Module> M = getLazyModuleFromAssembly(
  214. Context, Mem, "define void @func() {\n"
  215. " unreachable\n"
  216. "bb:\n"
  217. " unreachable\n"
  218. "}\n"
  219. "define void @other() {\n"
  220. " unreachable\n"
  221. "}\n"
  222. "define i8* @after() {\n"
  223. " ret i8* blockaddress(@func, %bb)\n"
  224. "}\n");
  225. EXPECT_TRUE(M->getFunction("after")->empty());
  226. EXPECT_TRUE(M->getFunction("func")->empty());
  227. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  228. // Materialize @after, pulling in @func.
  229. EXPECT_FALSE(M->getFunction("after")->materialize());
  230. EXPECT_FALSE(M->getFunction("func")->empty());
  231. EXPECT_TRUE(M->getFunction("other")->empty());
  232. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  233. // Try (and fail) to dematerialize @func.
  234. M->getFunction("func")->dematerialize();
  235. EXPECT_FALSE(M->getFunction("func")->empty());
  236. EXPECT_FALSE(verifyModule(*M, &dbgs()));
  237. }
  238. } // end namespace