1 //==- 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 
22 using namespace llvm;
23 
makeLLVMModule(LLVMContext & Context,StringRef ModuleStr)24 static 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 
TEST(DomTreeUpdater,EagerUpdateBasicOperations)32 TEST(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_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());
66 
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.";
74 
75   DTU.insertEdgeRelaxed(BB0, BB0);
76   DTU.deleteEdgeRelaxed(BB0, BB0);
77 
78   // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
79   // entries are discarded.
80   std::vector<DominatorTree::UpdateType> Updates;
81   Updates.reserve(4);
82   Updates.push_back({DominatorTree::Delete, BB0, BB3});
83   Updates.push_back({DominatorTree::Delete, BB0, BB3});
84 
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});
89 
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) {
95       SI->removeCase(i);
96       break;
97     }
98   }
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());
107 
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);
112 
113   // DTU working with Eager UpdateStrategy does not need to flush.
114   ASSERT_TRUE(DT.verify());
115   ASSERT_TRUE(PDT.verify());
116 
117   // Test callback utils.
118   ASSERT_EQ(BB3->getParent(), F);
119   DTU.callbackDeleteBB(BB3,
120                        [&F](BasicBlock *BB) { ASSERT_NE(BB->getParent(), F); });
121 
122   ASSERT_TRUE(DT.verify());
123   ASSERT_TRUE(PDT.verify());
124   ASSERT_FALSE(DTU.hasPendingUpdates());
125 
126   // Unnecessary flush() test
127   DTU.flush();
128   EXPECT_TRUE(DT.verify());
129   EXPECT_TRUE(PDT.verify());
130 
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);
138       e = SI->case_end();
139     } else
140       ++i;
141   }
142   ASSERT_FALSE(DT.verify());
143   ASSERT_FALSE(PDT.verify());
144   DTU.recalculate(*F);
145   ASSERT_TRUE(DT.verify());
146   ASSERT_TRUE(PDT.verify());
147 }
148 
TEST(DomTreeUpdater,EagerUpdateReplaceEntryBB)149 TEST(DomTreeUpdater, EagerUpdateReplaceEntryBB) {
150   StringRef FuncName = "f";
151   StringRef ModuleString = R"(
152                            define i32 @f() {
153                            bb0:
154                               br label %bb1
155                             bb1:
156                               ret i32 1
157                            }
158                            )";
159   // Make the module.
160   LLVMContext Context;
161   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
162   Function *F = M->getFunction(FuncName);
163 
164   // Make the DTU.
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());
174 
175   Function::iterator FI = F->begin();
176   BasicBlock *BB0 = &*FI++;
177   BasicBlock *BB1 = &*FI++;
178 
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);
185 
186   DTU.insertEdgeRelaxed(NewEntry, BB0);
187 
188   // Changing the Entry BB requires a full recalculation of DomTree.
189   DTU.recalculate(*F);
190   ASSERT_TRUE(DT.verify());
191   ASSERT_TRUE(PDT.verify());
192 
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);
198 
199   // Update the DTU. At this point bb0 now has no predecessors but is still a
200   // Child of F.
201   DTU.applyUpdates({{DominatorTree::Delete, NewEntry, BB0},
202                     {DominatorTree::Insert, NewEntry, BB1}});
203   ASSERT_TRUE(DT.verify());
204   ASSERT_TRUE(PDT.verify());
205 
206   // Now remove bb0 from F.
207   ASSERT_FALSE(isa<UnreachableInst>(BB0->getTerminator()));
208   EXPECT_FALSE(DTU.isBBPendingDeletion(BB0));
209   DTU.deleteBB(BB0);
210   ASSERT_TRUE(DT.verify());
211   ASSERT_TRUE(PDT.verify());
212 }
213 
TEST(DomTreeUpdater,LazyUpdateDTBasicOperations)214 TEST(DomTreeUpdater, LazyUpdateDTBasicOperations) {
215   StringRef FuncName = "f";
216   StringRef ModuleString = R"(
217                            define i32 @f(i32 %i, i32 *%p) {
218                             bb0:
219                               store i32 %i, i32 *%p
220                               switch i32 %i, label %bb1 [
221                                 i32 0, label %bb2
222                                 i32 1, label %bb2
223                                 i32 2, label %bb3
224                               ]
225                             bb1:
226                               ret i32 1
227                             bb2:
228                               ret i32 2
229                             bb3:
230                               ret i32 3
231                            }
232                            )";
233   // Make the module.
234   LLVMContext Context;
235   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
236   Function *F = M->getFunction(FuncName);
237 
238   // Make the DTU.
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());
247 
248   Function::iterator FI = F->begin();
249   BasicBlock *BB0 = &*FI++;
250   BasicBlock *BB1 = &*FI++;
251   BasicBlock *BB2 = &*FI++;
252   BasicBlock *BB3 = &*FI++;
253 
254   // Test discards of self-domination update.
255   DTU.deleteEdge(BB0, BB0);
256   ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
257 
258   // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
259   // entries are discarded.
260   std::vector<DominatorTree::UpdateType> Updates;
261   Updates.reserve(4);
262   Updates.push_back({DominatorTree::Delete, BB0, BB3});
263   Updates.push_back({DominatorTree::Delete, BB0, BB3});
264 
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});
269 
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);
275 
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());
280 
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.
291 
292   ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
293   EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
294   EXPECT_FALSE(DTU.hasPendingDeletedBB());
295   DTU.deleteBB(BB3);
296   EXPECT_TRUE(DTU.isBBPendingDeletion(BB3));
297   EXPECT_TRUE(DTU.hasPendingDeletedBB());
298   ASSERT_TRUE(isa<UnreachableInst>(BB3->getTerminator()));
299   EXPECT_EQ(BB3->getParent(), F);
300   DTU.recalculate(*F);
301   EXPECT_FALSE(DTU.hasPendingDeletedBB());
302 }
303 
TEST(DomTreeUpdater,LazyUpdateDTInheritedPreds)304 TEST(DomTreeUpdater, LazyUpdateDTInheritedPreds) {
305   StringRef FuncName = "f";
306   StringRef ModuleString = R"(
307                            define i32 @f(i32 %i, i32 *%p) {
308                             bb0:
309                               store i32 %i, i32 *%p
310                               switch i32 %i, label %bb1 [
311                                 i32 2, label %bb2
312                                 i32 3, label %bb3
313                               ]
314                             bb1:
315                               br label %bb3
316                             bb2:
317                               br label %bb3
318                             bb3:
319                               ret i32 3
320                            }
321                            )";
322   // Make the module.
323   LLVMContext Context;
324   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
325   Function *F = M->getFunction(FuncName);
326 
327   // Make the DTU.
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());
336 
337   Function::iterator FI = F->begin();
338   BasicBlock *BB0 = &*FI++;
339   BasicBlock *BB1 = &*FI++;
340   BasicBlock *BB2 = &*FI++;
341   BasicBlock *BB3 = &*FI++;
342 
343   // There are several CFG locations where we have:
344   //
345   //   pred1..predN
346   //    |        |
347   //    +> curr <+    converted into:   pred1..predN curr
348   //        |                            |        |
349   //        v                            +> succ <+
350   //       succ
351   //
352   // There is a specific shape of this we have to be careful of:
353   //
354   //   pred1..predN
355   //   ||        |
356   //   |+> curr <+    converted into:   pred1..predN curr
357   //   |    |                            |        |
358   //   |    v                            +> succ <+
359   //   +-> succ
360   //
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).
364 
365   // CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to
366   // remove bb2.
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);
371 
372   // Test callback utils.
373   std::vector<BasicBlock *> BasicBlocks;
374   BasicBlocks.push_back(BB1);
375   BasicBlocks.push_back(BB2);
376   auto Eraser = [&](BasicBlock *BB) {
377     BasicBlocks.erase(
378         std::remove_if(BasicBlocks.begin(), BasicBlocks.end(),
379                        [&](const BasicBlock *i) { return i == BB; }),
380         BasicBlocks.end());
381   };
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);
392 
393   // Queue up the DTU updates.
394   std::vector<DominatorTree::UpdateType> Updates;
395   Updates.reserve(4);
396   Updates.push_back({DominatorTree::Delete, BB0, BB2});
397   Updates.push_back({DominatorTree::Delete, BB2, BB3});
398 
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);
405 
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);
415 
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
418   // created.
419   Updates.push_back({DominatorTree::Delete, BB0, BB1});
420   Updates.push_back({DominatorTree::Delete, BB1, BB3});
421 
422   // Verify everything.
423   DTU.applyUpdates(Updates);
424   ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
425   DTU.flush();
426   ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(0));
427   ASSERT_TRUE(DT.verify());
428 }
429 
TEST(DomTreeUpdater,LazyUpdateBasicOperations)430 TEST(DomTreeUpdater, LazyUpdateBasicOperations) {
431   StringRef FuncName = "f";
432   StringRef ModuleString = R"(
433                            define i32 @f(i32 %i, i32 *%p) {
434                             bb0:
435                               store i32 %i, i32 *%p
436                               switch i32 %i, label %bb1 [
437                                 i32 0, label %bb2
438                                 i32 1, label %bb2
439                                 i32 2, label %bb3
440                               ]
441                             bb1:
442                               ret i32 1
443                             bb2:
444                               ret i32 2
445                             bb3:
446                               ret i32 3
447                            }
448                            )";
449   // Make the module.
450   LLVMContext Context;
451   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
452   Function *F = M->getFunction(FuncName);
453 
454   // Make the DTU.
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());
464 
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);
472 
473   // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
474   // entries are discarded.
475   std::vector<DominatorTree::UpdateType> Updates;
476   Updates.reserve(4);
477   Updates.push_back({DominatorTree::Delete, BB0, BB3});
478   Updates.push_back({DominatorTree::Delete, BB0, BB3});
479 
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});
484 
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);
490 
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);
505 
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);
520 }
521 
TEST(DomTreeUpdater,LazyUpdateReplaceEntryBB)522 TEST(DomTreeUpdater, LazyUpdateReplaceEntryBB) {
523   StringRef FuncName = "f";
524   StringRef ModuleString = R"(
525                            define i32 @f() {
526                            bb0:
527                               br label %bb1
528                             bb1:
529                               ret i32 1
530                            }
531                            )";
532   // Make the module.
533   LLVMContext Context;
534   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
535   Function *F = M->getFunction(FuncName);
536 
537   // Make the DTU.
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());
547 
548   Function::iterator FI = F->begin();
549   BasicBlock *BB0 = &*FI++;
550   BasicBlock *BB1 = &*FI++;
551 
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);
558 
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);
563 
564   // Changing the Entry BB requires a full recalculation.
565   DTU.recalculate(*F);
566   ASSERT_TRUE(DTU.getDomTree().verify());
567   ASSERT_TRUE(DTU.getPostDomTree().verify());
568 
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);
574 
575   // Update the DTU. At this point bb0 now has no predecessors but is still a
576   // Child of F.
577   DTU.applyUpdates({{DominatorTree::Delete, NewEntry, BB0},
578                     {DominatorTree::Insert, NewEntry, BB1}});
579   DTU.flush();
580   ASSERT_TRUE(DT.verify());
581   ASSERT_TRUE(PDT.verify());
582 
583   // Now remove bb0 from F.
584   ASSERT_FALSE(isa<UnreachableInst>(BB0->getTerminator()));
585   EXPECT_FALSE(DTU.isBBPendingDeletion(BB0));
586   DTU.deleteBB(BB0);
587   EXPECT_TRUE(DTU.isBBPendingDeletion(BB0));
588   ASSERT_TRUE(isa<UnreachableInst>(BB0->getTerminator()));
589   EXPECT_EQ(BB0->getParent(), F);
590 
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());
595   DTU.recalculate(*F);
596   ASSERT_FALSE(DTU.hasPendingDeletedBB());
597 }
598 
TEST(DomTreeUpdater,LazyUpdateStepTest)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) {
605                             bb0:
606                               store i32 %i, i32 *%p
607                               switch i32 %i, label %bb1 [
608                                 i32 0, label %bb1
609                                 i32 1, label %bb2
610                                 i32 2, label %bb3
611                                 i32 3, label %bb1
612                               ]
613                             bb1:
614                               ret i32 1
615                             bb2:
616                               ret i32 2
617                             bb3:
618                               ret i32 3
619                            }
620                            )";
621   // Make the module.
622   LLVMContext Context;
623   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
624   Function *F = M->getFunction(FuncName);
625 
626   // Make the DomTreeUpdater.
627   DominatorTree DT(*F);
628   PostDominatorTree PDT(*F);
629   DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
630 
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());
638 
639   Function::iterator FI = F->begin();
640   BasicBlock *BB0 = &*FI++;
641   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.";
646 
647   // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
648   // entries are discarded.
649   std::vector<DominatorTree::UpdateType> Updates;
650   Updates.reserve(1);
651   Updates.push_back({DominatorTree::Delete, BB0, BB3});
652 
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) {
658       SI->removeCase(i);
659       break;
660     }
661   }
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);
669 
670   // Only flush DomTree.
671   ASSERT_TRUE(DTU.getDomTree().verify());
672   ASSERT_TRUE(DTU.hasPendingPostDomTreeUpdates());
673   ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
674 
675   ASSERT_EQ(BB3->getParent(), F);
676   DTU.deleteBB(BB3);
677 
678   Updates.clear();
679 
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);
687       e = SI->case_end();
688       Updates.push_back({DominatorTree::Delete, BB0, BB2});
689     } else
690       ++i;
691   }
692 
693   DTU.applyUpdates(Updates);
694   // flush PostDomTree
695   ASSERT_TRUE(DTU.getPostDomTree().verify());
696   ASSERT_FALSE(DTU.hasPendingPostDomTreeUpdates());
697   ASSERT_TRUE(DTU.hasPendingDomTreeUpdates());
698   // flush both trees
699   DTU.flush();
700   ASSERT_TRUE(DT.verify());
701 }
702