blob: f431fa210397c6c164679b2b3a53ab809d4d4dfd [file] [log] [blame]
Jakub Kuderski5e3ab7a2018-07-03 02:06:23 +00001//==- llvm/unittests/IR/DomTreeUpdaterTest.cpp - DomTreeUpdater 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
10#include "llvm/IR/DomTreeUpdater.h"
11#include "llvm/Analysis/PostDominators.h"
12#include "llvm/AsmParser/Parser.h"
13#include "llvm/IR/Constants.h"
14#include "llvm/IR/Dominators.h"
15#include "llvm/IR/Instructions.h"
16#include "llvm/IR/LLVMContext.h"
17#include "llvm/IR/Module.h"
18#include "llvm/Support/SourceMgr.h"
19#include "gtest/gtest.h"
20#include <algorithm>
21
22using namespace llvm;
23
24static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
25 StringRef ModuleStr) {
26 SMDiagnostic Err;
27 std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
28 assert(M && "Bad LLVM IR?");
29 return M;
30}
31
32TEST(DomTreeUpdater, EagerUpdateBasicOperations) {
33 StringRef FuncName = "f";
34 StringRef ModuleString = R"(
35 define i32 @f(i32 %i, i32 *%p) {
36 bb0:
37 store i32 %i, i32 *%p
38 switch i32 %i, label %bb1 [
39 i32 1, label %bb2
40 i32 2, label %bb3
41 ]
42 bb1:
43 ret i32 1
44 bb2:
45 ret i32 2
46 bb3:
47 ret i32 3
48 })";
49 // Make the module.
50 LLVMContext Context;
51 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
52 Function *F = M->getFunction(FuncName);
53
54 // Make the DomTreeUpdater.
55 DominatorTree DT(*F);
56 PostDominatorTree PDT(*F);
57 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
58
59 ASSERT_TRUE(DTU.hasDomTree());
60 ASSERT_TRUE(DTU.hasPostDomTree());
61 ASSERT_EQ(DTU.getUpdateStrategy(), DomTreeUpdater::UpdateStrategy::Eager);
62 ASSERT_TRUE(DTU.getDomTree().verify());
63 ASSERT_TRUE(DTU.getPostDomTree().verify());
64 ASSERT_FALSE(DTU.hasPendingUpdates());
65
66 Function::iterator FI = F->begin();
67 BasicBlock *BB0 = &*FI++;
68 BasicBlock *BB1 = &*FI++;
69 BasicBlock *BB2 = &*FI++;
70 BasicBlock *BB3 = &*FI++;
71 SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
72 ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";
73
74 ASSERT_FALSE(DTU.insertEdgeRelaxed(BB0, BB0));
75 ASSERT_TRUE(DTU.deleteEdgeRelaxed(BB0, BB0));
76
77 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
78 // entries are discarded.
79 std::vector<DominatorTree::UpdateType> Updates;
80 Updates.reserve(4);
81 Updates.push_back({DominatorTree::Delete, BB0, BB3});
82 Updates.push_back({DominatorTree::Delete, BB0, BB3});
83
84 // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
85 Updates.push_back({DominatorTree::Insert, BB1, BB2});
86 // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
87 Updates.push_back({DominatorTree::Delete, BB0, BB1});
88
89 // CFG Change: remove edge bb0 -> bb3.
90 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u);
91 BB3->removePredecessor(BB0);
92 for (auto i = SI->case_begin(), e = SI->case_end(); i != e; ++i) {
93 if (i->getCaseSuccessor() == BB3) {
94 SI->removeCase(i);
95 break;
96 }
97 }
98 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
99 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
100 // contained Instructions and change the Terminator to "unreachable" when
101 // queued for deletion.
102 ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
103 EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
104 DTU.applyUpdates(Updates, /*ForceRemoveDuplicates*/ true);
105 ASSERT_FALSE(DTU.hasPendingUpdates());
106
107 // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
108 ASSERT_FALSE(DTU.insertEdgeRelaxed(BB1, BB2));
109 // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
110 ASSERT_FALSE(DTU.deleteEdgeRelaxed(BB0, BB1));
111
112 // DTU working with Eager UpdateStrategy does not need to flush.
113 ASSERT_TRUE(DT.verify());
114 ASSERT_TRUE(PDT.verify());
115
116 // Test callback utils.
117 ASSERT_EQ(BB3->getParent(), F);
118 DTU.callbackDeleteBB(BB3,
119 [&F](BasicBlock *BB) { ASSERT_NE(BB->getParent(), F); });
120
121 ASSERT_TRUE(DT.verify());
122 ASSERT_TRUE(PDT.verify());
123 ASSERT_FALSE(DTU.hasPendingUpdates());
124
125 // Unnecessary flush() test
126 DTU.flush();
127 EXPECT_TRUE(DT.verify());
128 EXPECT_TRUE(PDT.verify());
129
130 // Remove all case branch to BB2 to test Eager recalculation.
131 // Code section from llvm::ConstantFoldTerminator
132 for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) {
133 if (i->getCaseSuccessor() == BB2) {
134 // Remove this entry.
135 BB2->removePredecessor(BB0);
136 i = SI->removeCase(i);
137 e = SI->case_end();
138 } else
139 ++i;
140 }
141 ASSERT_FALSE(DT.verify());
142 ASSERT_FALSE(PDT.verify());
143 DTU.recalculate(*F);
144 ASSERT_TRUE(DT.verify());
145 ASSERT_TRUE(PDT.verify());
146}
147
148TEST(DomTreeUpdater, EagerUpdateReplaceEntryBB) {
149 StringRef FuncName = "f";
150 StringRef ModuleString = R"(
151 define i32 @f() {
152 bb0:
153 br label %bb1
154 bb1:
155 ret i32 1
156 }
157 )";
158 // Make the module.
159 LLVMContext Context;
160 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
161 Function *F = M->getFunction(FuncName);
162
163 // Make the DTU.
164 DominatorTree DT(*F);
165 PostDominatorTree PDT(*F);
166 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
167 ASSERT_TRUE(DTU.hasDomTree());
168 ASSERT_TRUE(DTU.hasPostDomTree());
169 ASSERT_EQ(DTU.getUpdateStrategy(), DomTreeUpdater::UpdateStrategy::Eager);
170 ASSERT_TRUE(DT.verify());
171 ASSERT_TRUE(PDT.verify());
172
173 Function::iterator FI = F->begin();
174 BasicBlock *BB0 = &*FI++;
175 BasicBlock *BB1 = &*FI++;
176
177 // Add a block as the new function entry BB. We also link it to BB0.
178 BasicBlock *NewEntry =
179 BasicBlock::Create(F->getContext(), "new_entry", F, BB0);
180 BranchInst::Create(BB0, NewEntry);
181 EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
182 EXPECT_TRUE(&F->getEntryBlock() == NewEntry);
183
184 ASSERT_TRUE(DTU.insertEdgeRelaxed(NewEntry, BB0));
185
186 // Changing the Entry BB requires a full recalculation of DomTree.
187 DTU.recalculate(*F);
188 ASSERT_TRUE(DT.verify());
189 ASSERT_TRUE(PDT.verify());
190
191 // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1.
192 EXPECT_EQ(NewEntry->getTerminator()->getNumSuccessors(), 1u);
193 NewEntry->getTerminator()->eraseFromParent();
194 BranchInst::Create(BB1, NewEntry);
195 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
196
197 // Update the DTU. At this point bb0 now has no predecessors but is still a
198 // Child of F.
199 DTU.applyUpdates({{DominatorTree::Delete, NewEntry, BB0},
200 {DominatorTree::Insert, NewEntry, BB1}});
201 ASSERT_TRUE(DT.verify());
202 ASSERT_TRUE(PDT.verify());
203
204 // Now remove bb0 from F.
205 ASSERT_FALSE(isa<UnreachableInst>(BB0->getTerminator()));
206 EXPECT_FALSE(DTU.isBBPendingDeletion(BB0));
207 DTU.deleteBB(BB0);
208 ASSERT_TRUE(DT.verify());
209 ASSERT_TRUE(PDT.verify());
210}
211
212TEST(DomTreeUpdater, LazyUpdateDTBasicOperations) {
213 StringRef FuncName = "f";
214 StringRef ModuleString = R"(
215 define i32 @f(i32 %i, i32 *%p) {
216 bb0:
217 store i32 %i, i32 *%p
218 switch i32 %i, label %bb1 [
219 i32 0, label %bb2
220 i32 1, label %bb2
221 i32 2, label %bb3
222 ]
223 bb1:
224 ret i32 1
225 bb2:
226 ret i32 2
227 bb3:
228 ret i32 3
229 }
230 )";
231 // Make the module.
232 LLVMContext Context;
233 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
234 Function *F = M->getFunction(FuncName);
235
236 // Make the DTU.
237 DominatorTree DT(*F);
Jakub Kuderskibea19a92018-07-04 18:37:15 +0000238 PostDominatorTree *PDT = nullptr;
239 DomTreeUpdater DTU(&DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
Jakub Kuderski5e3ab7a2018-07-03 02:06:23 +0000240 ASSERT_TRUE(DTU.hasDomTree());
241 ASSERT_FALSE(DTU.hasPostDomTree());
242 ASSERT_EQ(DTU.getUpdateStrategy(), DomTreeUpdater::UpdateStrategy::Lazy);
243 ASSERT_TRUE(DTU.getDomTree().verify());
244
245 Function::iterator FI = F->begin();
246 BasicBlock *BB0 = &*FI++;
247 BasicBlock *BB1 = &*FI++;
248 BasicBlock *BB2 = &*FI++;
249 BasicBlock *BB3 = &*FI++;
250
251 // Test discards of self-domination update.
252 DTU.deleteEdge(BB0, BB0);
253 ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
254
255 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
256 // entries are discarded.
257 std::vector<DominatorTree::UpdateType> Updates;
258 Updates.reserve(4);
259 Updates.push_back({DominatorTree::Delete, BB0, BB3});
260 Updates.push_back({DominatorTree::Delete, BB0, BB3});
261
262 // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
263 Updates.push_back({DominatorTree::Insert, BB1, BB2});
264 // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
265 Updates.push_back({DominatorTree::Delete, BB0, BB1});
266
267 // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2.
268 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u);
269 BB0->getTerminator()->eraseFromParent();
270 BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0);
271 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
272
273 // Verify. Updates to DTU must be applied *after* all changes to the CFG
274 // (including block deletion).
275 DTU.applyUpdates(Updates);
276 ASSERT_TRUE(DTU.getDomTree().verify());
277
278 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
279 // contained Instructions and change the Terminator to "unreachable" when
280 // queued for deletion. Its parent is still F until all the pending updates
281 // are applied to all trees held by the DomTreeUpdater (DomTree/PostDomTree).
282 // We don't defer this action because it can cause problems for other
283 // transforms or analysis as it's part of the actual CFG. We only defer
284 // updates to the DominatorTrees. This code will crash if it is placed before
285 // the BranchInst::Create() call above. After a deletion of a BasicBlock. Only
286 // an explicit flush event can trigger the flushing of deleteBBs. Because some
287 // passes using Lazy UpdateStrategy rely on this behavior.
288
289 ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
290 EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
291 EXPECT_FALSE(DTU.hasPendingDeletedBB());
292 DTU.deleteBB(BB3);
293 EXPECT_TRUE(DTU.isBBPendingDeletion(BB3));
294 EXPECT_TRUE(DTU.hasPendingDeletedBB());
295 ASSERT_TRUE(isa<UnreachableInst>(BB3->getTerminator()));
296 EXPECT_EQ(BB3->getParent(), F);
297 DTU.recalculate(*F);
298
299 EXPECT_FALSE(DTU.hasPendingDeletedBB());
300}
301
302TEST(DomTreeUpdater, LazyUpdateDTInheritedPreds) {
303 StringRef FuncName = "f";
304 StringRef ModuleString = R"(
305 define i32 @f(i32 %i, i32 *%p) {
306 bb0:
307 store i32 %i, i32 *%p
308 switch i32 %i, label %bb1 [
309 i32 2, label %bb2
310 i32 3, label %bb3
311 ]
312 bb1:
313 br label %bb3
314 bb2:
315 br label %bb3
316 bb3:
317 ret i32 3
318 }
319 )";
320 // Make the module.
321 LLVMContext Context;
322 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
323 Function *F = M->getFunction(FuncName);
324
325 // Make the DTU.
326 DominatorTree DT(*F);
Jakub Kuderskibea19a92018-07-04 18:37:15 +0000327 PostDominatorTree *PDT = nullptr;
328 DomTreeUpdater DTU(&DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
Jakub Kuderski5e3ab7a2018-07-03 02:06:23 +0000329 ASSERT_TRUE(DTU.hasDomTree());
330 ASSERT_FALSE(DTU.hasPostDomTree());
331 ASSERT_EQ(DTU.getUpdateStrategy(), DomTreeUpdater::UpdateStrategy::Lazy);
332 ASSERT_TRUE(DTU.getDomTree().verify());
333
334 Function::iterator FI = F->begin();
335 BasicBlock *BB0 = &*FI++;
336 BasicBlock *BB1 = &*FI++;
337 BasicBlock *BB2 = &*FI++;
338 BasicBlock *BB3 = &*FI++;
339
340 // There are several CFG locations where we have:
341 //
342 // pred1..predN
343 // | |
344 // +> curr <+ converted into: pred1..predN curr
345 // | | |
346 // v +> succ <+
347 // succ
348 //
349 // There is a specific shape of this we have to be careful of:
350 //
351 // pred1..predN
352 // || |
353 // |+> curr <+ converted into: pred1..predN curr
354 // | | | |
355 // | v +> succ <+
356 // +-> succ
357 //
358 // While the final CFG form is functionally identical the updates to
359 // DTU are not. In the first case we must have DTU.insertEdge(Pred1, Succ)
360 // while in the latter case we must *NOT* have DTU.insertEdge(Pred1, Succ).
361
362 // CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to
363 // remove bb2.
364 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u);
365 BB0->getTerminator()->eraseFromParent();
366 BranchInst::Create(BB1, BB3, ConstantInt::getTrue(F->getContext()), BB0);
367 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
368
369 // Test callback utils.
370 std::vector<BasicBlock *> BasicBlocks;
371 BasicBlocks.push_back(BB1);
372 BasicBlocks.push_back(BB2);
373 auto Eraser = [&](BasicBlock *BB) {
374 BasicBlocks.erase(
375 std::remove_if(BasicBlocks.begin(), BasicBlocks.end(),
376 [&](const BasicBlock *i) { return i == BB; }),
377 BasicBlocks.end());
378 };
379 ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
380 // Remove bb2 from F. This has to happen before the call to applyUpdates() for
381 // DTU to detect there is no longer an edge between bb2 -> bb3. The deleteBB()
382 // method converts bb2's TI into "unreachable".
383 ASSERT_FALSE(isa<UnreachableInst>(BB2->getTerminator()));
384 EXPECT_FALSE(DTU.isBBPendingDeletion(BB2));
385 DTU.callbackDeleteBB(BB2, Eraser);
386 EXPECT_TRUE(DTU.isBBPendingDeletion(BB2));
387 ASSERT_TRUE(isa<UnreachableInst>(BB2->getTerminator()));
388 EXPECT_EQ(BB2->getParent(), F);
389
390 // Queue up the DTU updates.
391 std::vector<DominatorTree::UpdateType> Updates;
392 Updates.reserve(4);
393 Updates.push_back({DominatorTree::Delete, BB0, BB2});
394 Updates.push_back({DominatorTree::Delete, BB2, BB3});
395
396 // Handle the specific shape case next.
397 // CFG Change: bb0 now only branches to bb3. We are preparing to remove bb1.
398 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
399 BB0->getTerminator()->eraseFromParent();
400 BranchInst::Create(BB3, BB0);
401 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
402
403 // Remove bb1 from F. This has to happen before the call to applyUpdates() for
404 // DTU to detect there is no longer an edge between bb1 -> bb3. The deleteBB()
405 // method converts bb1's TI into "unreachable".
406 ASSERT_FALSE(isa<UnreachableInst>(BB1->getTerminator()));
407 EXPECT_FALSE(DTU.isBBPendingDeletion(BB1));
408 DTU.callbackDeleteBB(BB1, Eraser);
409 EXPECT_TRUE(DTU.isBBPendingDeletion(BB1));
410 ASSERT_TRUE(isa<UnreachableInst>(BB1->getTerminator()));
411 EXPECT_EQ(BB1->getParent(), F);
412
413 // Update the DTU. In this case we don't call DTU.insertEdge(BB0, BB3) because
414 // the edge previously existed at the start of this test when DT was first
415 // created.
416 Updates.push_back({DominatorTree::Delete, BB0, BB1});
417 Updates.push_back({DominatorTree::Delete, BB1, BB3});
418
419 // Verify everything.
420 DTU.applyUpdates(Updates);
421 ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
422 DTU.flush();
423 ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(0));
424 ASSERT_TRUE(DT.verify());
425}
426
427TEST(DomTreeUpdater, LazyUpdateBasicOperations) {
428 StringRef FuncName = "f";
429 StringRef ModuleString = R"(
430 define i32 @f(i32 %i, i32 *%p) {
431 bb0:
432 store i32 %i, i32 *%p
433 switch i32 %i, label %bb1 [
434 i32 0, label %bb2
435 i32 1, label %bb2
436 i32 2, label %bb3
437 ]
438 bb1:
439 ret i32 1
440 bb2:
441 ret i32 2
442 bb3:
443 ret i32 3
444 }
445 )";
446 // Make the module.
447 LLVMContext Context;
448 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
449 Function *F = M->getFunction(FuncName);
450
451 // Make the DTU.
452 DominatorTree DT(*F);
453 PostDominatorTree PDT(*F);
Jakub Kuderskibea19a92018-07-04 18:37:15 +0000454 DomTreeUpdater DTU(&DT, &PDT, DomTreeUpdater::UpdateStrategy::Lazy);
Jakub Kuderski5e3ab7a2018-07-03 02:06:23 +0000455 ASSERT_TRUE(DTU.hasDomTree());
456 ASSERT_TRUE(DTU.hasPostDomTree());
457 ASSERT_EQ(DTU.getUpdateStrategy(), DomTreeUpdater::UpdateStrategy::Lazy);
458 ASSERT_TRUE(DTU.getDomTree().verify());
459 ASSERT_TRUE(DTU.getPostDomTree().verify());
460
461 Function::iterator FI = F->begin();
462 BasicBlock *BB0 = &*FI++;
463 BasicBlock *BB1 = &*FI++;
464 BasicBlock *BB2 = &*FI++;
465 BasicBlock *BB3 = &*FI++;
466 // Test discards of self-domination update.
467 DTU.deleteEdge(BB0, BB0);
468
469 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
470 // entries are discarded.
471 std::vector<DominatorTree::UpdateType> Updates;
472 Updates.reserve(4);
473 Updates.push_back({DominatorTree::Delete, BB0, BB3});
474 Updates.push_back({DominatorTree::Delete, BB0, BB3});
475
476 // Unnecessary Insert: no edge bb1 -> bb2 after change to bb0.
477 Updates.push_back({DominatorTree::Insert, BB1, BB2});
478 // Unnecessary Delete: edge exists bb0 -> bb1 after change to bb0.
479 Updates.push_back({DominatorTree::Delete, BB0, BB1});
480
481 // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2.
482 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u);
483 BB0->getTerminator()->eraseFromParent();
484 BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0);
485 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
486
487 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
488 // contained Instructions and change the Terminator to "unreachable" when
489 // queued for deletion. Its parent is still F until DTU.flushDomTree is
490 // called. We don't defer this action because it can cause problems for other
491 // transforms or analysis as it's part of the actual CFG. We only defer
492 // updates to the DominatorTree. This code will crash if it is placed before
493 // the BranchInst::Create() call above.
494 bool CallbackFlag = false;
495 ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
496 EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
497 DTU.callbackDeleteBB(BB3, [&](BasicBlock *) { CallbackFlag = true; });
498 EXPECT_TRUE(DTU.isBBPendingDeletion(BB3));
499 ASSERT_TRUE(isa<UnreachableInst>(BB3->getTerminator()));
500 EXPECT_EQ(BB3->getParent(), F);
501
502 // Verify. Updates to DTU must be applied *after* all changes to the CFG
503 // (including block deletion).
504 DTU.applyUpdates(Updates);
505 ASSERT_TRUE(DTU.getDomTree().verify());
506 ASSERT_TRUE(DTU.hasPendingUpdates());
507 ASSERT_TRUE(DTU.hasPendingPostDomTreeUpdates());
508 ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
509 ASSERT_TRUE(DTU.hasPendingDeletedBB());
510 ASSERT_TRUE(DTU.getPostDomTree().verify());
511 ASSERT_FALSE(DTU.hasPendingUpdates());
512 ASSERT_FALSE(DTU.hasPendingPostDomTreeUpdates());
513 ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
514 ASSERT_FALSE(DTU.hasPendingDeletedBB());
515 ASSERT_EQ(CallbackFlag, true);
516}
517
518TEST(DomTreeUpdater, LazyUpdateReplaceEntryBB) {
519 StringRef FuncName = "f";
520 StringRef ModuleString = R"(
521 define i32 @f() {
522 bb0:
523 br label %bb1
524 bb1:
525 ret i32 1
526 }
527 )";
528 // Make the module.
529 LLVMContext Context;
530 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
531 Function *F = M->getFunction(FuncName);
532
533 // Make the DTU.
534 DominatorTree DT(*F);
535 PostDominatorTree PDT(*F);
536 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
537 ASSERT_TRUE(DTU.hasDomTree());
538 ASSERT_TRUE(DTU.hasPostDomTree());
539 ASSERT_EQ(DTU.getUpdateStrategy(), DomTreeUpdater::UpdateStrategy::Lazy);
540 ASSERT_TRUE(DTU.getDomTree().verify());
541 ASSERT_TRUE(DTU.getPostDomTree().verify());
542
543 Function::iterator FI = F->begin();
544 BasicBlock *BB0 = &*FI++;
545 BasicBlock *BB1 = &*FI++;
546
547 // Add a block as the new function entry BB. We also link it to BB0.
548 BasicBlock *NewEntry =
549 BasicBlock::Create(F->getContext(), "new_entry", F, BB0);
550 BranchInst::Create(BB0, NewEntry);
551 EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
552 EXPECT_TRUE(&F->getEntryBlock() == NewEntry);
553
554 // Insert the new edge between new_entry -> bb0. Without this the
555 // recalculate() call below will not actually recalculate the DT as there
556 // are no changes pending and no blocks deleted.
557 DTU.insertEdge(NewEntry, BB0);
558
559 // Changing the Entry BB requires a full recalculation.
560 DTU.recalculate(*F);
561 ASSERT_TRUE(DTU.getDomTree().verify());
562 ASSERT_TRUE(DTU.getPostDomTree().verify());
563
564 // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1.
565 EXPECT_EQ(NewEntry->getTerminator()->getNumSuccessors(), 1u);
566 NewEntry->getTerminator()->eraseFromParent();
567 BranchInst::Create(BB1, NewEntry);
568 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
569
570 // Update the DTU. At this point bb0 now has no predecessors but is still a
571 // Child of F.
572 DTU.applyUpdates({{DominatorTree::Delete, NewEntry, BB0},
573 {DominatorTree::Insert, NewEntry, BB1}});
574 DTU.flush();
575 ASSERT_TRUE(DT.verify());
576 ASSERT_TRUE(PDT.verify());
577
578 // Now remove bb0 from F.
579 ASSERT_FALSE(isa<UnreachableInst>(BB0->getTerminator()));
580 EXPECT_FALSE(DTU.isBBPendingDeletion(BB0));
581 DTU.deleteBB(BB0);
582 EXPECT_TRUE(DTU.isBBPendingDeletion(BB0));
583 ASSERT_TRUE(isa<UnreachableInst>(BB0->getTerminator()));
584 EXPECT_EQ(BB0->getParent(), F);
585
586 // Perform a full recalculation of the DTU. It is not necessary here but we
587 // do this to test the case when there are no pending DT updates but there are
588 // pending deleted BBs.
589 ASSERT_TRUE(DTU.hasPendingDeletedBB());
590 DTU.recalculate(*F);
591 ASSERT_FALSE(DTU.hasPendingDeletedBB());
592}
593
594TEST(DomTreeUpdater, LazyUpdateStepTest) {
595 // This test focus on testing a DTU holding both trees applying multiple
596 // updates and DT/PDT not flushed together.
597 StringRef FuncName = "f";
598 StringRef ModuleString = R"(
599 define i32 @f(i32 %i, i32 *%p) {
600 bb0:
601 store i32 %i, i32 *%p
602 switch i32 %i, label %bb1 [
603 i32 0, label %bb1
604 i32 1, label %bb2
605 i32 2, label %bb3
606 i32 3, label %bb1
607 ]
608 bb1:
609 ret i32 1
610 bb2:
611 ret i32 2
612 bb3:
613 ret i32 3
614 }
615 )";
616 // Make the module.
617 LLVMContext Context;
618 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
619 Function *F = M->getFunction(FuncName);
620
621 // Make the DomTreeUpdater.
622 DominatorTree DT(*F);
623 PostDominatorTree PDT(*F);
624 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
625
626 ASSERT_TRUE(DTU.hasDomTree());
627 ASSERT_TRUE(DTU.hasPostDomTree());
628 ASSERT_EQ(DTU.getUpdateStrategy(), DomTreeUpdater::UpdateStrategy::Lazy);
629 ASSERT_TRUE(DTU.getDomTree().verify());
630 ASSERT_TRUE(DTU.getPostDomTree().verify());
631 ASSERT_FALSE(DTU.hasPendingUpdates());
632
633 Function::iterator FI = F->begin();
634 BasicBlock *BB0 = &*FI++;
635 FI++;
636 BasicBlock *BB2 = &*FI++;
637 BasicBlock *BB3 = &*FI++;
638 SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
639 ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";
640
641 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
642 // entries are discarded.
643 std::vector<DominatorTree::UpdateType> Updates;
644 Updates.reserve(1);
645 Updates.push_back({DominatorTree::Delete, BB0, BB3});
646
647 // CFG Change: remove edge bb0 -> bb3.
648 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 5u);
649 BB3->removePredecessor(BB0);
650 for (auto i = SI->case_begin(), e = SI->case_end(); i != e; ++i) {
651 if (i->getCaseIndex() == 2) {
652 SI->removeCase(i);
653 break;
654 }
655 }
656 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u);
657 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
658 // contained Instructions and change the Terminator to "unreachable" when
659 // queued for deletion.
660 ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
661 EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
662 DTU.applyUpdates(Updates);
663
664 // Only flush DomTree.
665 ASSERT_TRUE(DTU.getDomTree().verify());
666 ASSERT_TRUE(DTU.hasPendingPostDomTreeUpdates());
667 ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
668
669 ASSERT_EQ(BB3->getParent(), F);
670 DTU.deleteBB(BB3);
671
672 Updates.clear();
673
674 // Remove all case branch to BB2 to test Eager recalculation.
675 // Code section from llvm::ConstantFoldTerminator
676 for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) {
677 if (i->getCaseSuccessor() == BB2) {
678 // Remove this entry.
679 BB2->removePredecessor(BB0);
680 i = SI->removeCase(i);
681 e = SI->case_end();
682 Updates.push_back({DominatorTree::Delete, BB0, BB2});
683 } else
684 ++i;
685 }
686
687 DTU.applyUpdates(Updates);
688 // flush PostDomTree
689 ASSERT_TRUE(DTU.getPostDomTree().verify());
690 ASSERT_FALSE(DTU.hasPendingPostDomTreeUpdates());
691 ASSERT_TRUE(DTU.hasPendingDomTreeUpdates());
692 // flush both trees
693 DTU.flush();
694 ASSERT_TRUE(DT.verify());
695}