1 //==- llvm/unittests/IR/DomTreeUpdaterTest.cpp - DomTreeUpdater unit tests ===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
24 static std::unique_ptr
<Module
> makeLLVMModule(LLVMContext
&Context
,
25 StringRef ModuleStr
) {
27 std::unique_ptr
<Module
> M
= parseAssemblyString(ModuleStr
, Err
, Context
);
28 assert(M
&& "Bad LLVM IR?");
32 TEST(DomTreeUpdater
, EagerUpdateBasicOperations
) {
33 StringRef FuncName
= "f";
34 StringRef ModuleString
= R
"(
35 define i32 @f(i32 %i, i32 *%p) {
38 switch i32 %i, label %bb1 [
51 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
52 Function
*F
= M
->getFunction(FuncName
);
54 // Make the DomTreeUpdater.
56 PostDominatorTree
PDT(*F
);
57 DomTreeUpdater
DTU(DT
, PDT
, DomTreeUpdater::UpdateStrategy::Eager
);
59 ASSERT_TRUE(DTU
.hasDomTree());
60 ASSERT_TRUE(DTU
.hasPostDomTree());
61 ASSERT_TRUE(DTU
.isEager());
62 ASSERT_FALSE(DTU
.isLazy());
63 ASSERT_TRUE(DTU
.getDomTree().verify());
64 ASSERT_TRUE(DTU
.getPostDomTree().verify());
65 ASSERT_FALSE(DTU
.hasPendingUpdates());
67 Function::iterator FI
= F
->begin();
68 BasicBlock
*BB0
= &*FI
++;
69 BasicBlock
*BB1
= &*FI
++;
70 BasicBlock
*BB2
= &*FI
++;
71 BasicBlock
*BB3
= &*FI
++;
72 SwitchInst
*SI
= dyn_cast
<SwitchInst
>(BB0
->getTerminator());
73 ASSERT_NE(SI
, nullptr) << "Couldn't get SwitchInst.";
75 DTU
.insertEdgeRelaxed(BB0
, BB0
);
76 DTU
.deleteEdgeRelaxed(BB0
, BB0
);
78 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
79 // entries are discarded.
80 std::vector
<DominatorTree::UpdateType
> Updates
;
82 Updates
.push_back({DominatorTree::Delete
, BB0
, BB3
});
83 Updates
.push_back({DominatorTree::Delete
, BB0
, BB3
});
85 // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
86 Updates
.push_back({DominatorTree::Insert
, BB1
, BB2
});
87 // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
88 Updates
.push_back({DominatorTree::Delete
, BB0
, BB1
});
90 // CFG Change: remove edge bb0 -> bb3.
91 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 3u);
92 BB3
->removePredecessor(BB0
);
93 for (auto i
= SI
->case_begin(), e
= SI
->case_end(); i
!= e
; ++i
) {
94 if (i
->getCaseSuccessor() == BB3
) {
99 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 2u);
100 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
101 // contained Instructions and change the Terminator to "unreachable" when
102 // queued for deletion.
103 ASSERT_FALSE(isa
<UnreachableInst
>(BB3
->getTerminator()));
104 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB3
));
105 DTU
.applyUpdates(Updates
, /*ForceRemoveDuplicates*/ true);
106 ASSERT_FALSE(DTU
.hasPendingUpdates());
108 // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
109 DTU
.insertEdgeRelaxed(BB1
, BB2
);
110 // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
111 DTU
.deleteEdgeRelaxed(BB0
, BB1
);
113 // DTU working with Eager UpdateStrategy does not need to flush.
114 ASSERT_TRUE(DT
.verify());
115 ASSERT_TRUE(PDT
.verify());
117 // Test callback utils.
118 ASSERT_EQ(BB3
->getParent(), F
);
119 DTU
.callbackDeleteBB(BB3
,
120 [&F
](BasicBlock
*BB
) { ASSERT_NE(BB
->getParent(), F
); });
122 ASSERT_TRUE(DT
.verify());
123 ASSERT_TRUE(PDT
.verify());
124 ASSERT_FALSE(DTU
.hasPendingUpdates());
126 // Unnecessary flush() test
128 EXPECT_TRUE(DT
.verify());
129 EXPECT_TRUE(PDT
.verify());
131 // Remove all case branch to BB2 to test Eager recalculation.
132 // Code section from llvm::ConstantFoldTerminator
133 for (auto i
= SI
->case_begin(), e
= SI
->case_end(); i
!= e
;) {
134 if (i
->getCaseSuccessor() == BB2
) {
135 // Remove this entry.
136 BB2
->removePredecessor(BB0
);
137 i
= SI
->removeCase(i
);
142 ASSERT_FALSE(DT
.verify());
143 ASSERT_FALSE(PDT
.verify());
145 ASSERT_TRUE(DT
.verify());
146 ASSERT_TRUE(PDT
.verify());
149 TEST(DomTreeUpdater
, EagerUpdateReplaceEntryBB
) {
150 StringRef FuncName
= "f";
151 StringRef ModuleString
= R
"(
161 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
162 Function
*F
= M
->getFunction(FuncName
);
165 DominatorTree
DT(*F
);
166 PostDominatorTree
PDT(*F
);
167 DomTreeUpdater
DTU(DT
, PDT
, DomTreeUpdater::UpdateStrategy::Eager
);
168 ASSERT_TRUE(DTU
.hasDomTree());
169 ASSERT_TRUE(DTU
.hasPostDomTree());
170 ASSERT_TRUE(DTU
.isEager());
171 ASSERT_FALSE(DTU
.isLazy());
172 ASSERT_TRUE(DT
.verify());
173 ASSERT_TRUE(PDT
.verify());
175 Function::iterator FI
= F
->begin();
176 BasicBlock
*BB0
= &*FI
++;
177 BasicBlock
*BB1
= &*FI
++;
179 // Add a block as the new function entry BB. We also link it to BB0.
180 BasicBlock
*NewEntry
=
181 BasicBlock::Create(F
->getContext(), "new_entry", F
, BB0
);
182 BranchInst::Create(BB0
, NewEntry
);
183 EXPECT_EQ(F
->begin()->getName(), NewEntry
->getName());
184 EXPECT_TRUE(&F
->getEntryBlock() == NewEntry
);
186 DTU
.insertEdgeRelaxed(NewEntry
, BB0
);
188 // Changing the Entry BB requires a full recalculation of DomTree.
190 ASSERT_TRUE(DT
.verify());
191 ASSERT_TRUE(PDT
.verify());
193 // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1.
194 EXPECT_EQ(NewEntry
->getTerminator()->getNumSuccessors(), 1u);
195 NewEntry
->getTerminator()->eraseFromParent();
196 BranchInst::Create(BB1
, NewEntry
);
197 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 1u);
199 // Update the DTU. At this point bb0 now has no predecessors but is still a
201 DTU
.applyUpdates({{DominatorTree::Delete
, NewEntry
, BB0
},
202 {DominatorTree::Insert
, NewEntry
, BB1
}});
203 ASSERT_TRUE(DT
.verify());
204 ASSERT_TRUE(PDT
.verify());
206 // Now remove bb0 from F.
207 ASSERT_FALSE(isa
<UnreachableInst
>(BB0
->getTerminator()));
208 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB0
));
210 ASSERT_TRUE(DT
.verify());
211 ASSERT_TRUE(PDT
.verify());
214 TEST(DomTreeUpdater
, LazyUpdateDTBasicOperations
) {
215 StringRef FuncName
= "f";
216 StringRef ModuleString
= R
"(
217 define i32 @f(i32 %i, i32 *%p) {
219 store i32 %i, i32 *%p
220 switch i32 %i, label %bb1 [
235 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
236 Function
*F
= M
->getFunction(FuncName
);
239 DominatorTree
DT(*F
);
240 PostDominatorTree
*PDT
= nullptr;
241 DomTreeUpdater
DTU(&DT
, PDT
, DomTreeUpdater::UpdateStrategy::Lazy
);
242 ASSERT_TRUE(DTU
.hasDomTree());
243 ASSERT_FALSE(DTU
.hasPostDomTree());
244 ASSERT_FALSE(DTU
.isEager());
245 ASSERT_TRUE(DTU
.isLazy());
246 ASSERT_TRUE(DTU
.getDomTree().verify());
248 Function::iterator FI
= F
->begin();
249 BasicBlock
*BB0
= &*FI
++;
250 BasicBlock
*BB1
= &*FI
++;
251 BasicBlock
*BB2
= &*FI
++;
252 BasicBlock
*BB3
= &*FI
++;
254 // Test discards of self-domination update.
255 DTU
.deleteEdge(BB0
, BB0
);
256 ASSERT_FALSE(DTU
.hasPendingDomTreeUpdates());
258 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
259 // entries are discarded.
260 std::vector
<DominatorTree::UpdateType
> Updates
;
262 Updates
.push_back({DominatorTree::Delete
, BB0
, BB3
});
263 Updates
.push_back({DominatorTree::Delete
, BB0
, BB3
});
265 // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
266 Updates
.push_back({DominatorTree::Insert
, BB1
, BB2
});
267 // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
268 Updates
.push_back({DominatorTree::Delete
, BB0
, BB1
});
270 // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2.
271 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 4u);
272 BB0
->getTerminator()->eraseFromParent();
273 BranchInst::Create(BB1
, BB2
, ConstantInt::getTrue(F
->getContext()), BB0
);
274 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 2u);
276 // Verify. Updates to DTU must be applied *after* all changes to the CFG
277 // (including block deletion).
278 DTU
.applyUpdates(Updates
);
279 ASSERT_TRUE(DTU
.getDomTree().verify());
281 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
282 // contained Instructions and change the Terminator to "unreachable" when
283 // queued for deletion. Its parent is still F until all the pending updates
284 // are applied to all trees held by the DomTreeUpdater (DomTree/PostDomTree).
285 // We don't defer this action because it can cause problems for other
286 // transforms or analysis as it's part of the actual CFG. We only defer
287 // updates to the DominatorTrees. This code will crash if it is placed before
288 // the BranchInst::Create() call above. After a deletion of a BasicBlock. Only
289 // an explicit flush event can trigger the flushing of deleteBBs. Because some
290 // passes using Lazy UpdateStrategy rely on this behavior.
292 ASSERT_FALSE(isa
<UnreachableInst
>(BB3
->getTerminator()));
293 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB3
));
294 EXPECT_FALSE(DTU
.hasPendingDeletedBB());
296 EXPECT_TRUE(DTU
.isBBPendingDeletion(BB3
));
297 EXPECT_TRUE(DTU
.hasPendingDeletedBB());
298 ASSERT_TRUE(isa
<UnreachableInst
>(BB3
->getTerminator()));
299 EXPECT_EQ(BB3
->getParent(), F
);
301 EXPECT_FALSE(DTU
.hasPendingDeletedBB());
304 TEST(DomTreeUpdater
, LazyUpdateDTInheritedPreds
) {
305 StringRef FuncName
= "f";
306 StringRef ModuleString
= R
"(
307 define i32 @f(i32 %i, i32 *%p) {
309 store i32 %i, i32 *%p
310 switch i32 %i, label %bb1 [
324 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
325 Function
*F
= M
->getFunction(FuncName
);
328 DominatorTree
DT(*F
);
329 PostDominatorTree
*PDT
= nullptr;
330 DomTreeUpdater
DTU(&DT
, PDT
, DomTreeUpdater::UpdateStrategy::Lazy
);
331 ASSERT_TRUE(DTU
.hasDomTree());
332 ASSERT_FALSE(DTU
.hasPostDomTree());
333 ASSERT_FALSE(DTU
.isEager());
334 ASSERT_TRUE(DTU
.isLazy());
335 ASSERT_TRUE(DTU
.getDomTree().verify());
337 Function::iterator FI
= F
->begin();
338 BasicBlock
*BB0
= &*FI
++;
339 BasicBlock
*BB1
= &*FI
++;
340 BasicBlock
*BB2
= &*FI
++;
341 BasicBlock
*BB3
= &*FI
++;
343 // There are several CFG locations where we have:
347 // +> curr <+ converted into: pred1..predN curr
352 // There is a specific shape of this we have to be careful of:
356 // |+> curr <+ converted into: pred1..predN curr
361 // While the final CFG form is functionally identical the updates to
362 // DTU are not. In the first case we must have DTU.insertEdge(Pred1, Succ)
363 // while in the latter case we must *NOT* have DTU.insertEdge(Pred1, Succ).
365 // CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to
367 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 3u);
368 BB0
->getTerminator()->eraseFromParent();
369 BranchInst::Create(BB1
, BB3
, ConstantInt::getTrue(F
->getContext()), BB0
);
370 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 2u);
372 // Test callback utils.
373 std::vector
<BasicBlock
*> BasicBlocks
;
374 BasicBlocks
.push_back(BB1
);
375 BasicBlocks
.push_back(BB2
);
376 auto Eraser
= [&](BasicBlock
*BB
) {
378 std::remove_if(BasicBlocks
.begin(), BasicBlocks
.end(),
379 [&](const BasicBlock
*i
) { return i
== BB
; }),
382 ASSERT_EQ(BasicBlocks
.size(), static_cast<size_t>(2));
383 // Remove bb2 from F. This has to happen before the call to applyUpdates() for
384 // DTU to detect there is no longer an edge between bb2 -> bb3. The deleteBB()
385 // method converts bb2's TI into "unreachable".
386 ASSERT_FALSE(isa
<UnreachableInst
>(BB2
->getTerminator()));
387 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB2
));
388 DTU
.callbackDeleteBB(BB2
, Eraser
);
389 EXPECT_TRUE(DTU
.isBBPendingDeletion(BB2
));
390 ASSERT_TRUE(isa
<UnreachableInst
>(BB2
->getTerminator()));
391 EXPECT_EQ(BB2
->getParent(), F
);
393 // Queue up the DTU updates.
394 std::vector
<DominatorTree::UpdateType
> Updates
;
396 Updates
.push_back({DominatorTree::Delete
, BB0
, BB2
});
397 Updates
.push_back({DominatorTree::Delete
, BB2
, BB3
});
399 // Handle the specific shape case next.
400 // CFG Change: bb0 now only branches to bb3. We are preparing to remove bb1.
401 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 2u);
402 BB0
->getTerminator()->eraseFromParent();
403 BranchInst::Create(BB3
, BB0
);
404 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 1u);
406 // Remove bb1 from F. This has to happen before the call to applyUpdates() for
407 // DTU to detect there is no longer an edge between bb1 -> bb3. The deleteBB()
408 // method converts bb1's TI into "unreachable".
409 ASSERT_FALSE(isa
<UnreachableInst
>(BB1
->getTerminator()));
410 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB1
));
411 DTU
.callbackDeleteBB(BB1
, Eraser
);
412 EXPECT_TRUE(DTU
.isBBPendingDeletion(BB1
));
413 ASSERT_TRUE(isa
<UnreachableInst
>(BB1
->getTerminator()));
414 EXPECT_EQ(BB1
->getParent(), F
);
416 // Update the DTU. In this case we don't call DTU.insertEdge(BB0, BB3) because
417 // the edge previously existed at the start of this test when DT was first
419 Updates
.push_back({DominatorTree::Delete
, BB0
, BB1
});
420 Updates
.push_back({DominatorTree::Delete
, BB1
, BB3
});
422 // Verify everything.
423 DTU
.applyUpdates(Updates
);
424 ASSERT_EQ(BasicBlocks
.size(), static_cast<size_t>(2));
426 ASSERT_EQ(BasicBlocks
.size(), static_cast<size_t>(0));
427 ASSERT_TRUE(DT
.verify());
430 TEST(DomTreeUpdater
, LazyUpdateBasicOperations
) {
431 StringRef FuncName
= "f";
432 StringRef ModuleString
= R
"(
433 define i32 @f(i32 %i, i32 *%p) {
435 store i32 %i, i32 *%p
436 switch i32 %i, label %bb1 [
451 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
452 Function
*F
= M
->getFunction(FuncName
);
455 DominatorTree
DT(*F
);
456 PostDominatorTree
PDT(*F
);
457 DomTreeUpdater
DTU(&DT
, &PDT
, DomTreeUpdater::UpdateStrategy::Lazy
);
458 ASSERT_TRUE(DTU
.hasDomTree());
459 ASSERT_TRUE(DTU
.hasPostDomTree());
460 ASSERT_FALSE(DTU
.isEager());
461 ASSERT_TRUE(DTU
.isLazy());
462 ASSERT_TRUE(DTU
.getDomTree().verify());
463 ASSERT_TRUE(DTU
.getPostDomTree().verify());
465 Function::iterator FI
= F
->begin();
466 BasicBlock
*BB0
= &*FI
++;
467 BasicBlock
*BB1
= &*FI
++;
468 BasicBlock
*BB2
= &*FI
++;
469 BasicBlock
*BB3
= &*FI
++;
470 // Test discards of self-domination update.
471 DTU
.deleteEdge(BB0
, BB0
);
473 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
474 // entries are discarded.
475 std::vector
<DominatorTree::UpdateType
> Updates
;
477 Updates
.push_back({DominatorTree::Delete
, BB0
, BB3
});
478 Updates
.push_back({DominatorTree::Delete
, BB0
, BB3
});
480 // Unnecessary Insert: no edge bb1 -> bb2 after change to bb0.
481 Updates
.push_back({DominatorTree::Insert
, BB1
, BB2
});
482 // Unnecessary Delete: edge exists bb0 -> bb1 after change to bb0.
483 Updates
.push_back({DominatorTree::Delete
, BB0
, BB1
});
485 // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2.
486 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 4u);
487 BB0
->getTerminator()->eraseFromParent();
488 BranchInst::Create(BB1
, BB2
, ConstantInt::getTrue(F
->getContext()), BB0
);
489 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 2u);
491 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
492 // contained Instructions and change the Terminator to "unreachable" when
493 // queued for deletion. Its parent is still F until DTU.flushDomTree is
494 // called. We don't defer this action because it can cause problems for other
495 // transforms or analysis as it's part of the actual CFG. We only defer
496 // updates to the DominatorTree. This code will crash if it is placed before
497 // the BranchInst::Create() call above.
498 bool CallbackFlag
= false;
499 ASSERT_FALSE(isa
<UnreachableInst
>(BB3
->getTerminator()));
500 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB3
));
501 DTU
.callbackDeleteBB(BB3
, [&](BasicBlock
*) { CallbackFlag
= true; });
502 EXPECT_TRUE(DTU
.isBBPendingDeletion(BB3
));
503 ASSERT_TRUE(isa
<UnreachableInst
>(BB3
->getTerminator()));
504 EXPECT_EQ(BB3
->getParent(), F
);
506 // Verify. Updates to DTU must be applied *after* all changes to the CFG
507 // (including block deletion).
508 DTU
.applyUpdates(Updates
);
509 ASSERT_TRUE(DTU
.getDomTree().verify());
510 ASSERT_TRUE(DTU
.hasPendingUpdates());
511 ASSERT_TRUE(DTU
.hasPendingPostDomTreeUpdates());
512 ASSERT_FALSE(DTU
.hasPendingDomTreeUpdates());
513 ASSERT_TRUE(DTU
.hasPendingDeletedBB());
514 ASSERT_TRUE(DTU
.getPostDomTree().verify());
515 ASSERT_FALSE(DTU
.hasPendingUpdates());
516 ASSERT_FALSE(DTU
.hasPendingPostDomTreeUpdates());
517 ASSERT_FALSE(DTU
.hasPendingDomTreeUpdates());
518 ASSERT_FALSE(DTU
.hasPendingDeletedBB());
519 ASSERT_EQ(CallbackFlag
, true);
522 TEST(DomTreeUpdater
, LazyUpdateReplaceEntryBB
) {
523 StringRef FuncName
= "f";
524 StringRef ModuleString
= R
"(
534 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
535 Function
*F
= M
->getFunction(FuncName
);
538 DominatorTree
DT(*F
);
539 PostDominatorTree
PDT(*F
);
540 DomTreeUpdater
DTU(DT
, PDT
, DomTreeUpdater::UpdateStrategy::Lazy
);
541 ASSERT_TRUE(DTU
.hasDomTree());
542 ASSERT_TRUE(DTU
.hasPostDomTree());
543 ASSERT_FALSE(DTU
.isEager());
544 ASSERT_TRUE(DTU
.isLazy());
545 ASSERT_TRUE(DTU
.getDomTree().verify());
546 ASSERT_TRUE(DTU
.getPostDomTree().verify());
548 Function::iterator FI
= F
->begin();
549 BasicBlock
*BB0
= &*FI
++;
550 BasicBlock
*BB1
= &*FI
++;
552 // Add a block as the new function entry BB. We also link it to BB0.
553 BasicBlock
*NewEntry
=
554 BasicBlock::Create(F
->getContext(), "new_entry", F
, BB0
);
555 BranchInst::Create(BB0
, NewEntry
);
556 EXPECT_EQ(F
->begin()->getName(), NewEntry
->getName());
557 EXPECT_TRUE(&F
->getEntryBlock() == NewEntry
);
559 // Insert the new edge between new_entry -> bb0. Without this the
560 // recalculate() call below will not actually recalculate the DT as there
561 // are no changes pending and no blocks deleted.
562 DTU
.insertEdge(NewEntry
, BB0
);
564 // Changing the Entry BB requires a full recalculation.
566 ASSERT_TRUE(DTU
.getDomTree().verify());
567 ASSERT_TRUE(DTU
.getPostDomTree().verify());
569 // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1.
570 EXPECT_EQ(NewEntry
->getTerminator()->getNumSuccessors(), 1u);
571 NewEntry
->getTerminator()->eraseFromParent();
572 BranchInst::Create(BB1
, NewEntry
);
573 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 1u);
575 // Update the DTU. At this point bb0 now has no predecessors but is still a
577 DTU
.applyUpdates({{DominatorTree::Delete
, NewEntry
, BB0
},
578 {DominatorTree::Insert
, NewEntry
, BB1
}});
580 ASSERT_TRUE(DT
.verify());
581 ASSERT_TRUE(PDT
.verify());
583 // Now remove bb0 from F.
584 ASSERT_FALSE(isa
<UnreachableInst
>(BB0
->getTerminator()));
585 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB0
));
587 EXPECT_TRUE(DTU
.isBBPendingDeletion(BB0
));
588 ASSERT_TRUE(isa
<UnreachableInst
>(BB0
->getTerminator()));
589 EXPECT_EQ(BB0
->getParent(), F
);
591 // Perform a full recalculation of the DTU. It is not necessary here but we
592 // do this to test the case when there are no pending DT updates but there are
593 // pending deleted BBs.
594 ASSERT_TRUE(DTU
.hasPendingDeletedBB());
596 ASSERT_FALSE(DTU
.hasPendingDeletedBB());
599 TEST(DomTreeUpdater
, LazyUpdateStepTest
) {
600 // This test focus on testing a DTU holding both trees applying multiple
601 // updates and DT/PDT not flushed together.
602 StringRef FuncName
= "f";
603 StringRef ModuleString
= R
"(
604 define i32 @f(i32 %i, i32 *%p) {
606 store i32 %i, i32 *%p
607 switch i32 %i, label %bb1 [
623 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
624 Function
*F
= M
->getFunction(FuncName
);
626 // Make the DomTreeUpdater.
627 DominatorTree
DT(*F
);
628 PostDominatorTree
PDT(*F
);
629 DomTreeUpdater
DTU(DT
, PDT
, DomTreeUpdater::UpdateStrategy::Lazy
);
631 ASSERT_TRUE(DTU
.hasDomTree());
632 ASSERT_TRUE(DTU
.hasPostDomTree());
633 ASSERT_FALSE(DTU
.isEager());
634 ASSERT_TRUE(DTU
.isLazy());
635 ASSERT_TRUE(DTU
.getDomTree().verify());
636 ASSERT_TRUE(DTU
.getPostDomTree().verify());
637 ASSERT_FALSE(DTU
.hasPendingUpdates());
639 Function::iterator FI
= F
->begin();
640 BasicBlock
*BB0
= &*FI
++;
642 BasicBlock
*BB2
= &*FI
++;
643 BasicBlock
*BB3
= &*FI
++;
644 SwitchInst
*SI
= dyn_cast
<SwitchInst
>(BB0
->getTerminator());
645 ASSERT_NE(SI
, nullptr) << "Couldn't get SwitchInst.";
647 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
648 // entries are discarded.
649 std::vector
<DominatorTree::UpdateType
> Updates
;
651 Updates
.push_back({DominatorTree::Delete
, BB0
, BB3
});
653 // CFG Change: remove edge bb0 -> bb3.
654 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 5u);
655 BB3
->removePredecessor(BB0
);
656 for (auto i
= SI
->case_begin(), e
= SI
->case_end(); i
!= e
; ++i
) {
657 if (i
->getCaseIndex() == 2) {
662 EXPECT_EQ(BB0
->getTerminator()->getNumSuccessors(), 4u);
663 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
664 // contained Instructions and change the Terminator to "unreachable" when
665 // queued for deletion.
666 ASSERT_FALSE(isa
<UnreachableInst
>(BB3
->getTerminator()));
667 EXPECT_FALSE(DTU
.isBBPendingDeletion(BB3
));
668 DTU
.applyUpdates(Updates
);
670 // Only flush DomTree.
671 ASSERT_TRUE(DTU
.getDomTree().verify());
672 ASSERT_TRUE(DTU
.hasPendingPostDomTreeUpdates());
673 ASSERT_FALSE(DTU
.hasPendingDomTreeUpdates());
675 ASSERT_EQ(BB3
->getParent(), F
);
680 // Remove all case branch to BB2 to test Eager recalculation.
681 // Code section from llvm::ConstantFoldTerminator
682 for (auto i
= SI
->case_begin(), e
= SI
->case_end(); i
!= e
;) {
683 if (i
->getCaseSuccessor() == BB2
) {
684 // Remove this entry.
685 BB2
->removePredecessor(BB0
);
686 i
= SI
->removeCase(i
);
688 Updates
.push_back({DominatorTree::Delete
, BB0
, BB2
});
693 DTU
.applyUpdates(Updates
);
695 ASSERT_TRUE(DTU
.getPostDomTree().verify());
696 ASSERT_FALSE(DTU
.hasPendingPostDomTreeUpdates());
697 ASSERT_TRUE(DTU
.hasPendingDomTreeUpdates());
700 ASSERT_TRUE(DT
.verify());
703 TEST(DomTreeUpdater
, NoTreeTest
) {
704 StringRef FuncName
= "f";
705 StringRef ModuleString
= R
"(
713 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleString
);
714 Function
*F
= M
->getFunction(FuncName
);
717 DomTreeUpdater
DTU(nullptr, nullptr, DomTreeUpdater::UpdateStrategy::Lazy
);
718 ASSERT_FALSE(DTU
.hasDomTree());
719 ASSERT_FALSE(DTU
.hasPostDomTree());
720 Function::iterator FI
= F
->begin();
721 BasicBlock
*BB0
= &*FI
++;
722 // Test whether PendingDeletedBB is flushed after the recalculation.
724 ASSERT_TRUE(DTU
.hasPendingDeletedBB());
726 ASSERT_FALSE(DTU
.hasPendingDeletedBB());