PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/unittests/Transforms/Utils/Local.cpp

https://github.com/mono/llvm
C++ | 214 lines | 165 code | 31 blank | 18 comment | 11 complexity | 01e9b6263b4ba44505688eb070a96f18 MD5 | raw file
Possible License(s): JSON
  1. //===- Local.cpp - Unit tests for Local -----------------------------------===//
  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/Transforms/Utils/Local.h"
  10. #include "llvm/AsmParser/Parser.h"
  11. #include "llvm/IR/BasicBlock.h"
  12. #include "llvm/IR/DIBuilder.h"
  13. #include "llvm/IR/IRBuilder.h"
  14. #include "llvm/IR/Instructions.h"
  15. #include "llvm/IR/IntrinsicInst.h"
  16. #include "llvm/IR/LLVMContext.h"
  17. #include "llvm/Support/SourceMgr.h"
  18. #include "gtest/gtest.h"
  19. using namespace llvm;
  20. TEST(Local, RecursivelyDeleteDeadPHINodes) {
  21. LLVMContext C;
  22. IRBuilder<> builder(C);
  23. // Make blocks
  24. BasicBlock *bb0 = BasicBlock::Create(C);
  25. BasicBlock *bb1 = BasicBlock::Create(C);
  26. builder.SetInsertPoint(bb0);
  27. PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C), 2);
  28. BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
  29. builder.SetInsertPoint(bb1);
  30. BranchInst *br1 = builder.CreateBr(bb0);
  31. phi->addIncoming(phi, bb0);
  32. phi->addIncoming(phi, bb1);
  33. // The PHI will be removed
  34. EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
  35. // Make sure the blocks only contain the branches
  36. EXPECT_EQ(&bb0->front(), br0);
  37. EXPECT_EQ(&bb1->front(), br1);
  38. builder.SetInsertPoint(bb0);
  39. phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
  40. EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
  41. builder.SetInsertPoint(bb0);
  42. phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
  43. builder.CreateAdd(phi, phi);
  44. EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
  45. bb0->dropAllReferences();
  46. bb1->dropAllReferences();
  47. delete bb0;
  48. delete bb1;
  49. }
  50. TEST(Local, RemoveDuplicatePHINodes) {
  51. LLVMContext C;
  52. IRBuilder<> B(C);
  53. std::unique_ptr<Function> F(
  54. Function::Create(FunctionType::get(B.getVoidTy(), false),
  55. GlobalValue::ExternalLinkage, "F"));
  56. BasicBlock *Entry(BasicBlock::Create(C, "", F.get()));
  57. BasicBlock *BB(BasicBlock::Create(C, "", F.get()));
  58. BranchInst::Create(BB, Entry);
  59. B.SetInsertPoint(BB);
  60. AssertingVH<PHINode> P1 = B.CreatePHI(Type::getInt32Ty(C), 2);
  61. P1->addIncoming(B.getInt32(42), Entry);
  62. PHINode *P2 = B.CreatePHI(Type::getInt32Ty(C), 2);
  63. P2->addIncoming(B.getInt32(42), Entry);
  64. AssertingVH<PHINode> P3 = B.CreatePHI(Type::getInt32Ty(C), 2);
  65. P3->addIncoming(B.getInt32(42), Entry);
  66. P3->addIncoming(B.getInt32(23), BB);
  67. PHINode *P4 = B.CreatePHI(Type::getInt32Ty(C), 2);
  68. P4->addIncoming(B.getInt32(42), Entry);
  69. P4->addIncoming(B.getInt32(23), BB);
  70. P1->addIncoming(P3, BB);
  71. P2->addIncoming(P4, BB);
  72. BranchInst::Create(BB, BB);
  73. // Verify that we can eliminate PHIs that become duplicates after chaning PHIs
  74. // downstream.
  75. EXPECT_TRUE(EliminateDuplicatePHINodes(BB));
  76. EXPECT_EQ(3U, BB->size());
  77. }
  78. std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
  79. SMDiagnostic Err;
  80. std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
  81. if (!Mod)
  82. Err.print("UtilsTests", errs());
  83. return Mod;
  84. }
  85. TEST(Local, ReplaceDbgDeclare) {
  86. LLVMContext C;
  87. // Original C source to get debug info for a local variable:
  88. // void f() { int x; }
  89. std::unique_ptr<Module> M = parseIR(
  90. C,
  91. "define void @f() !dbg !8 {\n"
  92. "entry:\n"
  93. " %x = alloca i32, align 4\n"
  94. " call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata "
  95. "!DIExpression()), !dbg !13\n"
  96. " call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata "
  97. "!DIExpression()), !dbg !13\n"
  98. " ret void, !dbg !14\n"
  99. "}\n"
  100. "declare void @llvm.dbg.declare(metadata, metadata, metadata)\n"
  101. "!llvm.dbg.cu = !{!0}\n"
  102. "!llvm.module.flags = !{!3, !4}\n"
  103. "!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "
  104. "\"clang version 6.0.0 \", isOptimized: false, runtimeVersion: 0, "
  105. "emissionKind: FullDebug, enums: !2)\n"
  106. "!1 = !DIFile(filename: \"t2.c\", directory: \"foo\")\n"
  107. "!2 = !{}\n"
  108. "!3 = !{i32 2, !\"Dwarf Version\", i32 4}\n"
  109. "!4 = !{i32 2, !\"Debug Info Version\", i32 3}\n"
  110. "!8 = distinct !DISubprogram(name: \"f\", scope: !1, file: !1, line: 1, "
  111. "type: !9, isLocal: false, isDefinition: true, scopeLine: 1, "
  112. "isOptimized: false, unit: !0, variables: !2)\n"
  113. "!9 = !DISubroutineType(types: !10)\n"
  114. "!10 = !{null}\n"
  115. "!11 = !DILocalVariable(name: \"x\", scope: !8, file: !1, line: 2, type: "
  116. "!12)\n"
  117. "!12 = !DIBasicType(name: \"int\", size: 32, encoding: DW_ATE_signed)\n"
  118. "!13 = !DILocation(line: 2, column: 7, scope: !8)\n"
  119. "!14 = !DILocation(line: 3, column: 1, scope: !8)\n");
  120. auto *GV = M->getNamedValue("f");
  121. ASSERT_TRUE(GV);
  122. auto *F = dyn_cast<Function>(GV);
  123. ASSERT_TRUE(F);
  124. Instruction *Inst = &F->front().front();
  125. auto *AI = dyn_cast<AllocaInst>(Inst);
  126. ASSERT_TRUE(AI);
  127. Inst = Inst->getNextNode()->getNextNode();
  128. ASSERT_TRUE(Inst);
  129. auto *DII = dyn_cast<DbgDeclareInst>(Inst);
  130. ASSERT_TRUE(DII);
  131. Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C));
  132. DIBuilder DIB(*M);
  133. replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::NoDeref, 0,
  134. DIExpression::NoDeref);
  135. // There should be exactly two dbg.declares.
  136. int Declares = 0;
  137. for (const Instruction &I : F->front())
  138. if (isa<DbgDeclareInst>(I))
  139. Declares++;
  140. EXPECT_EQ(2, Declares);
  141. }
  142. /// Build the dominator tree for the function and run the Test.
  143. static void runWithDomTree(
  144. Module &M, StringRef FuncName,
  145. function_ref<void(Function &F, DominatorTree *DT)> Test) {
  146. auto *F = M.getFunction(FuncName);
  147. ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
  148. // Compute the dominator tree for the function.
  149. DominatorTree DT(*F);
  150. Test(*F, &DT);
  151. }
  152. TEST(Local, MergeBasicBlockIntoOnlyPred) {
  153. LLVMContext C;
  154. std::unique_ptr<Module> M = parseIR(
  155. C,
  156. "define i32 @f(i8* %str) {\n"
  157. "entry:\n"
  158. " br label %bb2.i\n"
  159. "bb2.i: ; preds = %bb4.i, %entry\n"
  160. " br i1 false, label %bb4.i, label %base2flt.exit204\n"
  161. "bb4.i: ; preds = %bb2.i\n"
  162. " br i1 false, label %base2flt.exit204, label %bb2.i\n"
  163. "bb10.i196.bb7.i197_crit_edge: ; No predecessors!\n"
  164. " br label %bb7.i197\n"
  165. "bb7.i197: ; preds = %bb10.i196.bb7.i197_crit_edge\n"
  166. " %.reg2mem.0 = phi i32 [ %.reg2mem.0, %bb10.i196.bb7.i197_crit_edge ]\n"
  167. " br i1 undef, label %base2flt.exit204, label %base2flt.exit204\n"
  168. "base2flt.exit204: ; preds = %bb7.i197, %bb7.i197, %bb2.i, %bb4.i\n"
  169. " ret i32 0\n"
  170. "}\n");
  171. runWithDomTree(
  172. *M, "f", [&](Function &F, DominatorTree *DT) {
  173. for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
  174. BasicBlock *BB = &*I++;
  175. BasicBlock *SinglePred = BB->getSinglePredecessor();
  176. if (!SinglePred || SinglePred == BB || BB->hasAddressTaken()) continue;
  177. BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator());
  178. if (Term && !Term->isConditional())
  179. MergeBasicBlockIntoOnlyPred(BB, DT);
  180. }
  181. EXPECT_TRUE(DT->verify());
  182. });
  183. }