Mercurial > hg > CbC > CbC_llvm
comparison unittests/Transforms/Utils/Local.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | 3a76565eade5 |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "llvm/Transforms/Utils/Local.h" | 10 #include "llvm/Transforms/Utils/Local.h" |
11 #include "llvm/AsmParser/Parser.h" | |
11 #include "llvm/IR/BasicBlock.h" | 12 #include "llvm/IR/BasicBlock.h" |
13 #include "llvm/IR/DIBuilder.h" | |
12 #include "llvm/IR/IRBuilder.h" | 14 #include "llvm/IR/IRBuilder.h" |
13 #include "llvm/IR/Instructions.h" | 15 #include "llvm/IR/Instructions.h" |
16 #include "llvm/IR/IntrinsicInst.h" | |
14 #include "llvm/IR/LLVMContext.h" | 17 #include "llvm/IR/LLVMContext.h" |
18 #include "llvm/Support/SourceMgr.h" | |
15 #include "gtest/gtest.h" | 19 #include "gtest/gtest.h" |
16 | 20 |
17 using namespace llvm; | 21 using namespace llvm; |
18 | 22 |
19 TEST(Local, RecursivelyDeleteDeadPHINodes) { | 23 TEST(Local, RecursivelyDeleteDeadPHINodes) { |
93 // Verify that we can eliminate PHIs that become duplicates after chaning PHIs | 97 // Verify that we can eliminate PHIs that become duplicates after chaning PHIs |
94 // downstream. | 98 // downstream. |
95 EXPECT_TRUE(EliminateDuplicatePHINodes(BB)); | 99 EXPECT_TRUE(EliminateDuplicatePHINodes(BB)); |
96 EXPECT_EQ(3U, BB->size()); | 100 EXPECT_EQ(3U, BB->size()); |
97 } | 101 } |
102 | |
103 std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { | |
104 SMDiagnostic Err; | |
105 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C); | |
106 if (!Mod) | |
107 Err.print("UtilsTests", errs()); | |
108 return Mod; | |
109 } | |
110 | |
111 TEST(Local, ReplaceDbgDeclare) { | |
112 LLVMContext C; | |
113 | |
114 // Original C source to get debug info for a local variable: | |
115 // void f() { int x; } | |
116 std::unique_ptr<Module> M = parseIR( | |
117 C, | |
118 "define void @f() !dbg !8 {\n" | |
119 "entry:\n" | |
120 " %x = alloca i32, align 4\n" | |
121 " call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata " | |
122 "!DIExpression()), !dbg !13\n" | |
123 " call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata " | |
124 "!DIExpression()), !dbg !13\n" | |
125 " ret void, !dbg !14\n" | |
126 "}\n" | |
127 "declare void @llvm.dbg.declare(metadata, metadata, metadata)\n" | |
128 "!llvm.dbg.cu = !{!0}\n" | |
129 "!llvm.module.flags = !{!3, !4}\n" | |
130 "!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: " | |
131 "\"clang version 6.0.0 \", isOptimized: false, runtimeVersion: 0, " | |
132 "emissionKind: FullDebug, enums: !2)\n" | |
133 "!1 = !DIFile(filename: \"t2.c\", directory: \"foo\")\n" | |
134 "!2 = !{}\n" | |
135 "!3 = !{i32 2, !\"Dwarf Version\", i32 4}\n" | |
136 "!4 = !{i32 2, !\"Debug Info Version\", i32 3}\n" | |
137 "!8 = distinct !DISubprogram(name: \"f\", scope: !1, file: !1, line: 1, " | |
138 "type: !9, isLocal: false, isDefinition: true, scopeLine: 1, " | |
139 "isOptimized: false, unit: !0, variables: !2)\n" | |
140 "!9 = !DISubroutineType(types: !10)\n" | |
141 "!10 = !{null}\n" | |
142 "!11 = !DILocalVariable(name: \"x\", scope: !8, file: !1, line: 2, type: " | |
143 "!12)\n" | |
144 "!12 = !DIBasicType(name: \"int\", size: 32, encoding: DW_ATE_signed)\n" | |
145 "!13 = !DILocation(line: 2, column: 7, scope: !8)\n" | |
146 "!14 = !DILocation(line: 3, column: 1, scope: !8)\n"); | |
147 auto *GV = M->getNamedValue("f"); | |
148 ASSERT_TRUE(GV); | |
149 auto *F = dyn_cast<Function>(GV); | |
150 ASSERT_TRUE(F); | |
151 Instruction *Inst = &F->front().front(); | |
152 auto *AI = dyn_cast<AllocaInst>(Inst); | |
153 ASSERT_TRUE(AI); | |
154 Inst = Inst->getNextNode()->getNextNode(); | |
155 ASSERT_TRUE(Inst); | |
156 auto *DII = dyn_cast<DbgDeclareInst>(Inst); | |
157 ASSERT_TRUE(DII); | |
158 Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C)); | |
159 DIBuilder DIB(*M); | |
160 replaceDbgDeclare(AI, NewBase, DII, DIB, /*Deref=*/false, /*Offset=*/0); | |
161 | |
162 // There should be exactly two dbg.declares. | |
163 int Declares = 0; | |
164 for (const Instruction &I : F->front()) | |
165 if (isa<DbgDeclareInst>(I)) | |
166 Declares++; | |
167 EXPECT_EQ(2, Declares); | |
168 } | |
169 | |
170 /// Build the dominator tree for the function and run the Test. | |
171 static void runWithDomTree( | |
172 Module &M, StringRef FuncName, | |
173 function_ref<void(Function &F, DominatorTree *DT)> Test) { | |
174 auto *F = M.getFunction(FuncName); | |
175 ASSERT_NE(F, nullptr) << "Could not find " << FuncName; | |
176 // Compute the dominator tree for the function. | |
177 DominatorTree DT(*F); | |
178 Test(*F, &DT); | |
179 } | |
180 | |
181 TEST(Local, MergeBasicBlockIntoOnlyPred) { | |
182 LLVMContext C; | |
183 | |
184 std::unique_ptr<Module> M = parseIR( | |
185 C, | |
186 "define i32 @f(i8* %str) {\n" | |
187 "entry:\n" | |
188 " br label %bb2.i\n" | |
189 "bb2.i: ; preds = %bb4.i, %entry\n" | |
190 " br i1 false, label %bb4.i, label %base2flt.exit204\n" | |
191 "bb4.i: ; preds = %bb2.i\n" | |
192 " br i1 false, label %base2flt.exit204, label %bb2.i\n" | |
193 "bb10.i196.bb7.i197_crit_edge: ; No predecessors!\n" | |
194 " br label %bb7.i197\n" | |
195 "bb7.i197: ; preds = %bb10.i196.bb7.i197_crit_edge\n" | |
196 " %.reg2mem.0 = phi i32 [ %.reg2mem.0, %bb10.i196.bb7.i197_crit_edge ]\n" | |
197 " br i1 undef, label %base2flt.exit204, label %base2flt.exit204\n" | |
198 "base2flt.exit204: ; preds = %bb7.i197, %bb7.i197, %bb2.i, %bb4.i\n" | |
199 " ret i32 0\n" | |
200 "}\n"); | |
201 runWithDomTree( | |
202 *M, "f", [&](Function &F, DominatorTree *DT) { | |
203 for (Function::iterator I = F.begin(), E = F.end(); I != E;) { | |
204 BasicBlock *BB = &*I++; | |
205 BasicBlock *SinglePred = BB->getSinglePredecessor(); | |
206 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken()) continue; | |
207 BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator()); | |
208 if (Term && !Term->isConditional()) | |
209 MergeBasicBlockIntoOnlyPred(BB, DT); | |
210 } | |
211 EXPECT_TRUE(DT->verify()); | |
212 }); | |
213 } |