blob: bdeeffde1524513cf2907da6a8fb6daba0da3be0 [file] [log] [blame]
NAKAMURA Takumiafda71e2013-01-23 08:30:10 +00001//===- llvm/unittests/IR/DominatorTreeTest.cpp - Constants unit tests -----===//
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
Diego Novilloee592422013-12-02 14:08:27 +000010#include "llvm/Analysis/PostDominators.h"
Chandler Carruth9aca9182014-01-07 12:34:26 +000011#include "llvm/AsmParser/Parser.h"
Daniel Berlin8f8174c2015-04-14 19:49:26 +000012#include "llvm/IR/Constants.h"
Adam Nemet7fa6dee2017-05-27 04:05:50 +000013#include "llvm/IR/Dominators.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000014#include "llvm/IR/Instructions.h"
15#include "llvm/IR/LLVMContext.h"
Adam Nemet7fa6dee2017-05-27 04:05:50 +000016#include "llvm/IR/Module.h"
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000017#include "llvm/Support/SourceMgr.h"
Jakub Kuderski13e9ef12017-07-14 21:17:33 +000018#include "CFGBuilder.h"
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000019#include "gtest/gtest.h"
20
21using namespace llvm;
22
Jakub Kuderskib292c222017-07-14 18:26:09 +000023struct PostDomTree : PostDomTreeBase<BasicBlock> {
24 PostDomTree(Function &F) { recalculate(F); }
25};
26
Adam Nemet147ede92017-05-27 04:05:52 +000027/// Build the dominator tree for the function and run the Test.
Jakub Kuderskib292c222017-07-14 18:26:09 +000028static void runWithDomTree(
29 Module &M, StringRef FuncName,
30 function_ref<void(Function &F, DominatorTree *DT, PostDomTree *PDT)> Test) {
Adam Nemet147ede92017-05-27 04:05:52 +000031 auto *F = M.getFunction(FuncName);
32 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
33 // Compute the dominator tree for the function.
34 DominatorTree DT(*F);
Jakub Kuderskib292c222017-07-14 18:26:09 +000035 PostDomTree PDT(*F);
Adam Nemet147ede92017-05-27 04:05:52 +000036 Test(*F, &DT, &PDT);
37}
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000038
Adam Nemet147ede92017-05-27 04:05:52 +000039static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
40 StringRef ModuleStr) {
41 SMDiagnostic Err;
42 std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
43 assert(M && "Bad assembly?");
44 return M;
45}
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000046
Adam Nemet147ede92017-05-27 04:05:52 +000047TEST(DominatorTree, Unreachable) {
48 StringRef ModuleString =
Adam Nemet7fa6dee2017-05-27 04:05:50 +000049 "declare i32 @g()\n"
50 "define void @f(i32 %x) personality i32 ()* @g {\n"
51 "bb0:\n"
52 " %y1 = add i32 %x, 1\n"
53 " %y2 = add i32 %x, 1\n"
54 " %y3 = invoke i32 @g() to label %bb1 unwind label %bb2\n"
55 "bb1:\n"
56 " %y4 = add i32 %x, 1\n"
57 " br label %bb4\n"
58 "bb2:\n"
59 " %y5 = landingpad i32\n"
60 " cleanup\n"
61 " br label %bb4\n"
62 "bb3:\n"
63 " %y6 = add i32 %x, 1\n"
64 " %y7 = add i32 %x, 1\n"
65 " ret void\n"
66 "bb4:\n"
67 " %y8 = phi i32 [0, %bb2], [%y4, %bb1]\n"
68 " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n"
69 " ret void\n"
70 "}\n";
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000071
Adam Nemet147ede92017-05-27 04:05:52 +000072 // Parse the module.
Adam Nemet7fa6dee2017-05-27 04:05:50 +000073 LLVMContext Context;
Adam Nemet147ede92017-05-27 04:05:52 +000074 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
Adam Nemet7fa6dee2017-05-27 04:05:50 +000075
Adam Nemet147ede92017-05-27 04:05:52 +000076 runWithDomTree(
Jakub Kuderskib292c222017-07-14 18:26:09 +000077 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
Adam Nemet147ede92017-05-27 04:05:52 +000078 Function::iterator FI = F.begin();
79
80 BasicBlock *BB0 = &*FI++;
81 BasicBlock::iterator BBI = BB0->begin();
82 Instruction *Y1 = &*BBI++;
83 Instruction *Y2 = &*BBI++;
84 Instruction *Y3 = &*BBI++;
85
86 BasicBlock *BB1 = &*FI++;
87 BBI = BB1->begin();
88 Instruction *Y4 = &*BBI++;
89
90 BasicBlock *BB2 = &*FI++;
91 BBI = BB2->begin();
92 Instruction *Y5 = &*BBI++;
93
94 BasicBlock *BB3 = &*FI++;
95 BBI = BB3->begin();
96 Instruction *Y6 = &*BBI++;
97 Instruction *Y7 = &*BBI++;
98
99 BasicBlock *BB4 = &*FI++;
100 BBI = BB4->begin();
101 Instruction *Y8 = &*BBI++;
102 Instruction *Y9 = &*BBI++;
103
104 // Reachability
105 EXPECT_TRUE(DT->isReachableFromEntry(BB0));
106 EXPECT_TRUE(DT->isReachableFromEntry(BB1));
107 EXPECT_TRUE(DT->isReachableFromEntry(BB2));
108 EXPECT_FALSE(DT->isReachableFromEntry(BB3));
109 EXPECT_TRUE(DT->isReachableFromEntry(BB4));
110
111 // BB dominance
112 EXPECT_TRUE(DT->dominates(BB0, BB0));
113 EXPECT_TRUE(DT->dominates(BB0, BB1));
114 EXPECT_TRUE(DT->dominates(BB0, BB2));
115 EXPECT_TRUE(DT->dominates(BB0, BB3));
116 EXPECT_TRUE(DT->dominates(BB0, BB4));
117
118 EXPECT_FALSE(DT->dominates(BB1, BB0));
119 EXPECT_TRUE(DT->dominates(BB1, BB1));
120 EXPECT_FALSE(DT->dominates(BB1, BB2));
121 EXPECT_TRUE(DT->dominates(BB1, BB3));
122 EXPECT_FALSE(DT->dominates(BB1, BB4));
123
124 EXPECT_FALSE(DT->dominates(BB2, BB0));
125 EXPECT_FALSE(DT->dominates(BB2, BB1));
126 EXPECT_TRUE(DT->dominates(BB2, BB2));
127 EXPECT_TRUE(DT->dominates(BB2, BB3));
128 EXPECT_FALSE(DT->dominates(BB2, BB4));
129
130 EXPECT_FALSE(DT->dominates(BB3, BB0));
131 EXPECT_FALSE(DT->dominates(BB3, BB1));
132 EXPECT_FALSE(DT->dominates(BB3, BB2));
133 EXPECT_TRUE(DT->dominates(BB3, BB3));
134 EXPECT_FALSE(DT->dominates(BB3, BB4));
135
136 // BB proper dominance
137 EXPECT_FALSE(DT->properlyDominates(BB0, BB0));
138 EXPECT_TRUE(DT->properlyDominates(BB0, BB1));
139 EXPECT_TRUE(DT->properlyDominates(BB0, BB2));
140 EXPECT_TRUE(DT->properlyDominates(BB0, BB3));
141
142 EXPECT_FALSE(DT->properlyDominates(BB1, BB0));
143 EXPECT_FALSE(DT->properlyDominates(BB1, BB1));
144 EXPECT_FALSE(DT->properlyDominates(BB1, BB2));
145 EXPECT_TRUE(DT->properlyDominates(BB1, BB3));
146
147 EXPECT_FALSE(DT->properlyDominates(BB2, BB0));
148 EXPECT_FALSE(DT->properlyDominates(BB2, BB1));
149 EXPECT_FALSE(DT->properlyDominates(BB2, BB2));
150 EXPECT_TRUE(DT->properlyDominates(BB2, BB3));
151
152 EXPECT_FALSE(DT->properlyDominates(BB3, BB0));
153 EXPECT_FALSE(DT->properlyDominates(BB3, BB1));
154 EXPECT_FALSE(DT->properlyDominates(BB3, BB2));
155 EXPECT_FALSE(DT->properlyDominates(BB3, BB3));
156
157 // Instruction dominance in the same reachable BB
158 EXPECT_FALSE(DT->dominates(Y1, Y1));
159 EXPECT_TRUE(DT->dominates(Y1, Y2));
160 EXPECT_FALSE(DT->dominates(Y2, Y1));
161 EXPECT_FALSE(DT->dominates(Y2, Y2));
162
163 // Instruction dominance in the same unreachable BB
164 EXPECT_TRUE(DT->dominates(Y6, Y6));
165 EXPECT_TRUE(DT->dominates(Y6, Y7));
166 EXPECT_TRUE(DT->dominates(Y7, Y6));
167 EXPECT_TRUE(DT->dominates(Y7, Y7));
168
169 // Invoke
170 EXPECT_TRUE(DT->dominates(Y3, Y4));
171 EXPECT_FALSE(DT->dominates(Y3, Y5));
172
173 // Phi
174 EXPECT_TRUE(DT->dominates(Y2, Y9));
175 EXPECT_FALSE(DT->dominates(Y3, Y9));
176 EXPECT_FALSE(DT->dominates(Y8, Y9));
177
178 // Anything dominates unreachable
179 EXPECT_TRUE(DT->dominates(Y1, Y6));
180 EXPECT_TRUE(DT->dominates(Y3, Y6));
181
182 // Unreachable doesn't dominate reachable
183 EXPECT_FALSE(DT->dominates(Y6, Y1));
184
185 // Instruction, BB dominance
186 EXPECT_FALSE(DT->dominates(Y1, BB0));
187 EXPECT_TRUE(DT->dominates(Y1, BB1));
188 EXPECT_TRUE(DT->dominates(Y1, BB2));
189 EXPECT_TRUE(DT->dominates(Y1, BB3));
190 EXPECT_TRUE(DT->dominates(Y1, BB4));
191
192 EXPECT_FALSE(DT->dominates(Y3, BB0));
193 EXPECT_TRUE(DT->dominates(Y3, BB1));
194 EXPECT_FALSE(DT->dominates(Y3, BB2));
195 EXPECT_TRUE(DT->dominates(Y3, BB3));
196 EXPECT_FALSE(DT->dominates(Y3, BB4));
197
198 EXPECT_TRUE(DT->dominates(Y6, BB3));
199
200 // Post dominance.
201 EXPECT_TRUE(PDT->dominates(BB0, BB0));
202 EXPECT_FALSE(PDT->dominates(BB1, BB0));
203 EXPECT_FALSE(PDT->dominates(BB2, BB0));
204 EXPECT_FALSE(PDT->dominates(BB3, BB0));
205 EXPECT_TRUE(PDT->dominates(BB4, BB1));
206
207 // Dominance descendants.
208 SmallVector<BasicBlock *, 8> DominatedBBs, PostDominatedBBs;
209
210 DT->getDescendants(BB0, DominatedBBs);
211 PDT->getDescendants(BB0, PostDominatedBBs);
212 EXPECT_EQ(DominatedBBs.size(), 4UL);
213 EXPECT_EQ(PostDominatedBBs.size(), 1UL);
214
215 // BB3 is unreachable. It should have no dominators nor postdominators.
216 DominatedBBs.clear();
217 PostDominatedBBs.clear();
218 DT->getDescendants(BB3, DominatedBBs);
219 DT->getDescendants(BB3, PostDominatedBBs);
220 EXPECT_EQ(DominatedBBs.size(), 0UL);
221 EXPECT_EQ(PostDominatedBBs.size(), 0UL);
222
223 // Check DFS Numbers before
Jakub Kuderski837755c2017-06-30 01:28:21 +0000224 DT->updateDFSNumbers();
Adam Nemet147ede92017-05-27 04:05:52 +0000225 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
226 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 7UL);
227 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
228 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 2UL);
229 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 5UL);
230 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 6UL);
231 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 3UL);
232 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 4UL);
233
Jakub Kuderski604a22b2017-07-01 00:23:01 +0000234 // Check levels before
235 EXPECT_EQ(DT->getNode(BB0)->getLevel(), 0U);
236 EXPECT_EQ(DT->getNode(BB1)->getLevel(), 1U);
237 EXPECT_EQ(DT->getNode(BB2)->getLevel(), 1U);
238 EXPECT_EQ(DT->getNode(BB4)->getLevel(), 1U);
239
Adam Nemet147ede92017-05-27 04:05:52 +0000240 // Reattach block 3 to block 1 and recalculate
241 BB1->getTerminator()->eraseFromParent();
242 BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getContext()), BB1);
243 DT->recalculate(F);
244
245 // Check DFS Numbers after
Jakub Kuderski837755c2017-06-30 01:28:21 +0000246 DT->updateDFSNumbers();
Adam Nemet147ede92017-05-27 04:05:52 +0000247 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
248 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 9UL);
249 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
250 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 4UL);
251 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 7UL);
252 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 8UL);
253 EXPECT_EQ(DT->getNode(BB3)->getDFSNumIn(), 2UL);
254 EXPECT_EQ(DT->getNode(BB3)->getDFSNumOut(), 3UL);
255 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 5UL);
256 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 6UL);
257
Jakub Kuderski604a22b2017-07-01 00:23:01 +0000258 // Check levels after
259 EXPECT_EQ(DT->getNode(BB0)->getLevel(), 0U);
260 EXPECT_EQ(DT->getNode(BB1)->getLevel(), 1U);
261 EXPECT_EQ(DT->getNode(BB2)->getLevel(), 1U);
262 EXPECT_EQ(DT->getNode(BB3)->getLevel(), 2U);
263 EXPECT_EQ(DT->getNode(BB4)->getLevel(), 1U);
264
Adam Nemet147ede92017-05-27 04:05:52 +0000265 // Change root node
266 DT->verifyDomTree();
267 BasicBlock *NewEntry =
268 BasicBlock::Create(F.getContext(), "new_entry", &F, BB0);
269 BranchInst::Create(BB0, NewEntry);
270 EXPECT_EQ(F.begin()->getName(), NewEntry->getName());
271 EXPECT_TRUE(&F.getEntryBlock() == NewEntry);
272 DT->setNewRoot(NewEntry);
273 DT->verifyDomTree();
274 });
275}
Adam Nemet4ef096b2017-06-05 16:27:09 +0000276
277TEST(DominatorTree, NonUniqueEdges) {
278 StringRef ModuleString =
279 "define i32 @f(i32 %i, i32 *%p) {\n"
280 "bb0:\n"
281 " store i32 %i, i32 *%p\n"
282 " switch i32 %i, label %bb2 [\n"
283 " i32 0, label %bb1\n"
284 " i32 1, label %bb1\n"
285 " ]\n"
286 " bb1:\n"
287 " ret i32 1\n"
288 " bb2:\n"
289 " ret i32 4\n"
290 "}\n";
291
292 // Parse the module.
293 LLVMContext Context;
294 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
295
296 runWithDomTree(
Jakub Kuderskib292c222017-07-14 18:26:09 +0000297 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
Adam Nemet4ef096b2017-06-05 16:27:09 +0000298 Function::iterator FI = F.begin();
299
300 BasicBlock *BB0 = &*FI++;
301 BasicBlock *BB1 = &*FI++;
302 BasicBlock *BB2 = &*FI++;
303
304 const TerminatorInst *TI = BB0->getTerminator();
305 assert(TI->getNumSuccessors() == 3 && "Switch has three successors");
306
307 BasicBlockEdge Edge_BB0_BB2(BB0, TI->getSuccessor(0));
308 assert(Edge_BB0_BB2.getEnd() == BB2 &&
309 "Default label is the 1st successor");
310
311 BasicBlockEdge Edge_BB0_BB1_a(BB0, TI->getSuccessor(1));
312 assert(Edge_BB0_BB1_a.getEnd() == BB1 && "BB1 is the 2nd successor");
313
314 BasicBlockEdge Edge_BB0_BB1_b(BB0, TI->getSuccessor(2));
315 assert(Edge_BB0_BB1_b.getEnd() == BB1 && "BB1 is the 3rd successor");
316
317 EXPECT_TRUE(DT->dominates(Edge_BB0_BB2, BB2));
318 EXPECT_FALSE(DT->dominates(Edge_BB0_BB2, BB1));
319
320 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_a, BB1));
321 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_b, BB1));
322
323 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_a, BB2));
324 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_b, BB2));
325 });
326}
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000327
328namespace {
329const auto Insert = CFGBuilder::ActionKind::Insert;
Jakub Kuderskieb59ff22017-07-14 21:58:53 +0000330const auto Delete = CFGBuilder::ActionKind::Delete;
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000331
332bool CompUpdates(const CFGBuilder::Update &A, const CFGBuilder::Update &B) {
333 return std::tie(A.Action, A.Edge.From, A.Edge.To) <
334 std::tie(B.Action, B.Edge.From, B.Edge.To);
335};
336} // namespace
337
338TEST(DominatorTree, InsertReachable) {
339 CFGHolder Holder;
340 std::vector<CFGBuilder::Arc> Arcs = {
341 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
342 {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
343
344 std::vector<CFGBuilder::Update> Updates = {{Insert, {"12", "10"}},
345 {Insert, {"10", "9"}},
346 {Insert, {"7", "6"}},
347 {Insert, {"7", "5"}}};
348 CFGBuilder B(Holder.F, Arcs, Updates);
349 DominatorTree DT(*Holder.F);
350 EXPECT_TRUE(DT.verify());
351 PostDomTree PDT(*Holder.F);
352 EXPECT_TRUE(PDT.verify());
353
354 Optional<CFGBuilder::Update> LastUpdate;
355 while ((LastUpdate = B.applyUpdate())) {
356 EXPECT_EQ(LastUpdate->Action, Insert);
357 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
358 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
359 DT.insertEdge(From, To);
360 EXPECT_TRUE(DT.verify());
361 PDT.insertEdge(From, To);
362 EXPECT_TRUE(PDT.verify());
363 }
364}
365
366TEST(DominatorTree, InsertUnreachable) {
367 CFGHolder Holder;
368 std::vector<CFGBuilder::Arc> Arcs = {{"1", "2"}, {"2", "3"}, {"3", "4"},
369 {"5", "6"}, {"5", "7"}, {"3", "8"},
370 {"9", "10"}, {"11", "12"}};
371
372 std::vector<CFGBuilder::Update> Updates = {{Insert, {"4", "5"}},
373 {Insert, {"8", "9"}},
374 {Insert, {"10", "12"}},
375 {Insert, {"10", "11"}}};
376 CFGBuilder B(Holder.F, Arcs, Updates);
377 DominatorTree DT(*Holder.F);
378 EXPECT_TRUE(DT.verify());
379 PostDomTree PDT(*Holder.F);
380 EXPECT_TRUE(PDT.verify());
381
382 Optional<CFGBuilder::Update> LastUpdate;
383 while ((LastUpdate = B.applyUpdate())) {
384 EXPECT_EQ(LastUpdate->Action, Insert);
385 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
386 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
387 DT.insertEdge(From, To);
388 EXPECT_TRUE(DT.verify());
389 PDT.insertEdge(From, To);
390 EXPECT_TRUE(PDT.verify());
391 }
392}
393
394TEST(DominatorTree, InsertMixed) {
395 CFGHolder Holder;
396 std::vector<CFGBuilder::Arc> Arcs = {
397 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"5", "6"}, {"5", "7"},
398 {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}, {"7", "3"}};
399
400 std::vector<CFGBuilder::Update> Updates = {
401 {Insert, {"4", "5"}}, {Insert, {"2", "5"}}, {Insert, {"10", "9"}},
402 {Insert, {"12", "10"}}, {Insert, {"12", "10"}}, {Insert, {"7", "8"}},
403 {Insert, {"7", "5"}}};
404 CFGBuilder B(Holder.F, Arcs, Updates);
405 DominatorTree DT(*Holder.F);
406 EXPECT_TRUE(DT.verify());
407 PostDomTree PDT(*Holder.F);
408 EXPECT_TRUE(PDT.verify());
409
410 Optional<CFGBuilder::Update> LastUpdate;
411 while ((LastUpdate = B.applyUpdate())) {
412 EXPECT_EQ(LastUpdate->Action, Insert);
413 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
414 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
415 DT.insertEdge(From, To);
416 EXPECT_TRUE(DT.verify());
417 PDT.insertEdge(From, To);
418 EXPECT_TRUE(PDT.verify());
419 }
420}
421
422TEST(DominatorTree, InsertPermut) {
423 std::vector<CFGBuilder::Arc> Arcs = {
424 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"5", "6"}, {"5", "7"},
425 {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}, {"7", "3"}};
426
427 std::vector<CFGBuilder::Update> Updates = {{Insert, {"4", "5"}},
428 {Insert, {"2", "5"}},
429 {Insert, {"10", "9"}},
430 {Insert, {"12", "10"}}};
431
432 while (std::next_permutation(Updates.begin(), Updates.end(), CompUpdates)) {
433 CFGHolder Holder;
434 CFGBuilder B(Holder.F, Arcs, Updates);
435 DominatorTree DT(*Holder.F);
436 EXPECT_TRUE(DT.verify());
437 PostDomTree PDT(*Holder.F);
438 EXPECT_TRUE(PDT.verify());
439
440 Optional<CFGBuilder::Update> LastUpdate;
441 while ((LastUpdate = B.applyUpdate())) {
442 EXPECT_EQ(LastUpdate->Action, Insert);
443 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
444 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
445 DT.insertEdge(From, To);
446 EXPECT_TRUE(DT.verify());
447 PDT.insertEdge(From, To);
448 EXPECT_TRUE(PDT.verify());
449 }
450 }
451}
Jakub Kuderskieb59ff22017-07-14 21:58:53 +0000452
453TEST(DominatorTree, DeleteReachable) {
454 CFGHolder Holder;
455 std::vector<CFGBuilder::Arc> Arcs = {
456 {"1", "2"}, {"2", "3"}, {"2", "4"}, {"3", "4"}, {"4", "5"}, {"5", "6"},
457 {"5", "7"}, {"7", "8"}, {"3", "8"}, {"8", "9"}, {"9", "10"}, {"10", "2"}};
458
459 std::vector<CFGBuilder::Update> Updates = {
460 {Delete, {"2", "4"}}, {Delete, {"7", "8"}}, {Delete, {"10", "2"}}};
461 CFGBuilder B(Holder.F, Arcs, Updates);
462 DominatorTree DT(*Holder.F);
463 EXPECT_TRUE(DT.verify());
464 PostDomTree PDT(*Holder.F);
465 EXPECT_TRUE(PDT.verify());
466
467 Optional<CFGBuilder::Update> LastUpdate;
468 while ((LastUpdate = B.applyUpdate())) {
469 EXPECT_EQ(LastUpdate->Action, Delete);
470 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
471 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
472 DT.deleteEdge(From, To);
473 EXPECT_TRUE(DT.verify());
474 PDT.deleteEdge(From, To);
475 EXPECT_TRUE(PDT.verify());
476 }
477}
478
479TEST(DominatorTree, DeleteUnreachable) {
480 CFGHolder Holder;
481 std::vector<CFGBuilder::Arc> Arcs = {
482 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
483 {"7", "8"}, {"3", "8"}, {"8", "9"}, {"9", "10"}, {"10", "2"}};
484
485 std::vector<CFGBuilder::Update> Updates = {
486 {Delete, {"8", "9"}}, {Delete, {"7", "8"}}, {Delete, {"3", "4"}}};
487 CFGBuilder B(Holder.F, Arcs, Updates);
488 DominatorTree DT(*Holder.F);
489 EXPECT_TRUE(DT.verify());
490 PostDomTree PDT(*Holder.F);
491 EXPECT_TRUE(PDT.verify());
492
493 Optional<CFGBuilder::Update> LastUpdate;
494 while ((LastUpdate = B.applyUpdate())) {
495 EXPECT_EQ(LastUpdate->Action, Delete);
496 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
497 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
498 DT.deleteEdge(From, To);
499 EXPECT_TRUE(DT.verify());
500 PDT.deleteEdge(From, To);
501 EXPECT_TRUE(PDT.verify());
502 }
503}
504
505TEST(DominatorTree, InsertDelete) {
506 std::vector<CFGBuilder::Arc> Arcs = {
507 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
508 {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
509
510 std::vector<CFGBuilder::Update> Updates = {
511 {Insert, {"2", "4"}}, {Insert, {"12", "10"}}, {Insert, {"10", "9"}},
512 {Insert, {"7", "6"}}, {Insert, {"7", "5"}}, {Delete, {"3", "8"}},
513 {Insert, {"10", "7"}}, {Insert, {"2", "8"}}, {Delete, {"3", "4"}},
514 {Delete, {"8", "9"}}, {Delete, {"11", "12"}}};
515
516 CFGHolder Holder;
517 CFGBuilder B(Holder.F, Arcs, Updates);
518 DominatorTree DT(*Holder.F);
519 EXPECT_TRUE(DT.verify());
520 PostDomTree PDT(*Holder.F);
521 EXPECT_TRUE(PDT.verify());
522
523 Optional<CFGBuilder::Update> LastUpdate;
524 while ((LastUpdate = B.applyUpdate())) {
525 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
526 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
527 if (LastUpdate->Action == Insert) {
528 DT.insertEdge(From, To);
529 PDT.insertEdge(From, To);
530 } else {
531 DT.deleteEdge(From, To);
532 PDT.deleteEdge(From, To);
533 }
534
535 EXPECT_TRUE(DT.verify());
536 EXPECT_TRUE(PDT.verify());
537 }
538}
539
540TEST(DominatorTree, InsertDeleteExhaustive) {
541 std::vector<CFGBuilder::Arc> Arcs = {
542 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
543 {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
544
545 std::vector<CFGBuilder::Update> Updates = {
546 {Insert, {"2", "4"}}, {Insert, {"12", "10"}}, {Insert, {"10", "9"}},
547 {Insert, {"7", "6"}}, {Insert, {"7", "5"}}, {Delete, {"3", "8"}},
548 {Insert, {"10", "7"}}, {Insert, {"2", "8"}}, {Delete, {"3", "4"}},
549 {Delete, {"8", "9"}}, {Delete, {"11", "12"}}};
550
551 std::mt19937 Generator(0);
552 for (unsigned i = 0; i < 16; ++i) {
553 std::shuffle(Updates.begin(), Updates.end(), Generator);
554 CFGHolder Holder;
555 CFGBuilder B(Holder.F, Arcs, Updates);
556 DominatorTree DT(*Holder.F);
557 EXPECT_TRUE(DT.verify());
558 PostDomTree PDT(*Holder.F);
559 EXPECT_TRUE(PDT.verify());
560
561 Optional<CFGBuilder::Update> LastUpdate;
562 while ((LastUpdate = B.applyUpdate())) {
563 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
564 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
565 if (LastUpdate->Action == Insert) {
566 DT.insertEdge(From, To);
567 PDT.insertEdge(From, To);
568 } else {
569 DT.deleteEdge(From, To);
570 PDT.deleteEdge(From, To);
571 }
572
573 EXPECT_TRUE(DT.verify());
574 EXPECT_TRUE(PDT.verify());
575 }
576 }
577}