llvm.org GIT mirror llvm / bfd4fdf
[Dominators] Remove the DeferredDominance class Summary: After converting all existing passes to use the new DomTreeUpdater interface, there isn't any usage of the original DeferredDominance class. Thus, we can safely remove it from the codebase. Reviewers: kuhar, brzycki, dmgreen, davide, grosser Reviewed By: kuhar, brzycki Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D49747 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339502 91177308-0d34-0410-b5e6-96231b3b80d8 Chijun Sima 2 years ago
4 changed file(s) with 0 addition(s) and 623 deletion(s). Raw diff Collapse all Expand all
275275
276276 void print(raw_ostream &OS, const Module *M = nullptr) const override;
277277 };
278
279 //===-------------------------------------
280 /// Class to defer updates to a DominatorTree.
281 ///
282 /// Definition: Applying updates to every edge insertion and deletion is
283 /// expensive and not necessary. When one needs the DominatorTree for analysis
284 /// they can request a flush() to perform a larger batch update. This has the
285 /// advantage of the DominatorTree inspecting the set of updates to find
286 /// duplicates or unnecessary subtree updates.
287 ///
288 /// The scope of DeferredDominance operates at a Function level.
289 ///
290 /// It is not necessary for the user to scrub the updates for duplicates or
291 /// updates that point to the same block (Delete, BB_A, BB_A). Performance
292 /// can be gained if the caller attempts to batch updates before submitting
293 /// to applyUpdates(ArrayRef) in cases where duplicate edge requests will
294 /// occur.
295 ///
296 /// It is required for the state of the LLVM IR to be applied *before*
297 /// submitting updates. The update routines must analyze the current state
298 /// between a pair of (From, To) basic blocks to determine if the update
299 /// needs to be queued.
300 /// Example (good):
301 /// TerminatorInstructionBB->removeFromParent();
302 /// DDT->deleteEdge(BB, Successor);
303 /// Example (bad):
304 /// DDT->deleteEdge(BB, Successor);
305 /// TerminatorInstructionBB->removeFromParent();
306 class DeferredDominance {
307 public:
308 DeferredDominance(DominatorTree &DT_) : DT(DT_) {}
309
310 /// Queues multiple updates and discards duplicates.
311 void applyUpdates(ArrayRef Updates);
312
313 /// Helper method for a single edge insertion. It's almost always
314 /// better to batch updates and call applyUpdates to quickly remove duplicate
315 /// edges. This is best used when there is only a single insertion needed to
316 /// update Dominators.
317 void insertEdge(BasicBlock *From, BasicBlock *To);
318
319 /// Helper method for a single edge deletion. It's almost always better
320 /// to batch updates and call applyUpdates to quickly remove duplicate edges.
321 /// This is best used when there is only a single deletion needed to update
322 /// Dominators.
323 void deleteEdge(BasicBlock *From, BasicBlock *To);
324
325 /// Delays the deletion of a basic block until a flush() event.
326 void deleteBB(BasicBlock *DelBB);
327
328 /// Returns true if DelBB is awaiting deletion at a flush() event.
329 bool pendingDeletedBB(BasicBlock *DelBB);
330
331 /// Returns true if pending DT updates are queued for a flush() event.
332 bool pending();
333
334 /// Flushes all pending updates and block deletions. Returns a
335 /// correct DominatorTree reference to be used by the caller for analysis.
336 DominatorTree &flush();
337
338 /// Drops all internal state and forces a (slow) recalculation of the
339 /// DominatorTree based on the current state of the LLVM IR in F. This should
340 /// only be used in corner cases such as the Entry block of F being deleted.
341 void recalculate(Function &F);
342
343 /// Debug method to help view the state of pending updates.
344 LLVM_DUMP_METHOD void dump() const;
345
346 private:
347 DominatorTree &DT;
348 SmallVector PendUpdates;
349 SmallPtrSet DeletedBBs;
350
351 /// Apply an update (Kind, From, To) to the internal queued updates. The
352 /// update is only added when determined to be necessary. Checks for
353 /// self-domination, unnecessary updates, duplicate requests, and balanced
354 /// pairs of requests are all performed. Returns true if the update is
355 /// queued and false if it is discarded.
356 bool applyUpdate(DominatorTree::UpdateKind Kind, BasicBlock *From,
357 BasicBlock *To);
358
359 /// Performs all pending basic block deletions. We have to defer the deletion
360 /// of these blocks until after the DominatorTree updates are applied. The
361 /// internal workings of the DominatorTree code expect every update's From
362 /// and To blocks to exist and to be a member of the same Function.
363 bool flushDelBB();
364 };
365
366278 } // end namespace llvm
367279
368280 #endif // LLVM_IR_DOMINATORS_H
371371 DT.print(OS);
372372 }
373373
374 //===----------------------------------------------------------------------===//
375 // DeferredDominance Implementation
376 //===----------------------------------------------------------------------===//
377 //
378 // The implementation details of the DeferredDominance class which allows
379 // one to queue updates to a DominatorTree.
380 //
381 //===----------------------------------------------------------------------===//
382
383 /// Queues multiple updates and discards duplicates.
384 void DeferredDominance::applyUpdates(
385 ArrayRef Updates) {
386 SmallVector Seen;
387 for (auto U : Updates)
388 // Avoid duplicates to applyUpdate() to save on analysis.
389 if (std::none_of(Seen.begin(), Seen.end(),
390 [U](DominatorTree::UpdateType S) { return S == U; })) {
391 Seen.push_back(U);
392 applyUpdate(U.getKind(), U.getFrom(), U.getTo());
393 }
394 }
395
396 /// Helper method for a single edge insertion. It's almost always better
397 /// to batch updates and call applyUpdates to quickly remove duplicate edges.
398 /// This is best used when there is only a single insertion needed to update
399 /// Dominators.
400 void DeferredDominance::insertEdge(BasicBlock *From, BasicBlock *To) {
401 applyUpdate(DominatorTree::Insert, From, To);
402 }
403
404 /// Helper method for a single edge deletion. It's almost always better
405 /// to batch updates and call applyUpdates to quickly remove duplicate edges.
406 /// This is best used when there is only a single deletion needed to update
407 /// Dominators.
408 void DeferredDominance::deleteEdge(BasicBlock *From, BasicBlock *To) {
409 applyUpdate(DominatorTree::Delete, From, To);
410 }
411
412 /// Delays the deletion of a basic block until a flush() event.
413 void DeferredDominance::deleteBB(BasicBlock *DelBB) {
414 assert(DelBB && "Invalid push_back of nullptr DelBB.");
415 assert(pred_empty(DelBB) && "DelBB has one or more predecessors.");
416 // DelBB is unreachable and all its instructions are dead.
417 while (!DelBB->empty()) {
418 Instruction &I = DelBB->back();
419 // Replace used instructions with an arbitrary value (undef).
420 if (!I.use_empty())
421 I.replaceAllUsesWith(llvm::UndefValue::get(I.getType()));
422 DelBB->getInstList().pop_back();
423 }
424 // Make sure DelBB has a valid terminator instruction. As long as DelBB is a
425 // Child of Function F it must contain valid IR.
426 new UnreachableInst(DelBB->getContext(), DelBB);
427 DeletedBBs.insert(DelBB);
428 }
429
430 /// Returns true if DelBB is awaiting deletion at a flush() event.
431 bool DeferredDominance::pendingDeletedBB(BasicBlock *DelBB) {
432 if (DeletedBBs.empty())
433 return false;
434 return DeletedBBs.count(DelBB) != 0;
435 }
436
437 /// Returns true if pending DT updates are queued for a flush() event.
438 bool DeferredDominance::pending() { return !PendUpdates.empty(); }
439
440 /// Flushes all pending updates and block deletions. Returns a
441 /// correct DominatorTree reference to be used by the caller for analysis.
442 DominatorTree &DeferredDominance::flush() {
443 // Updates to DT must happen before blocks are deleted below. Otherwise the
444 // DT traversal will encounter badref blocks and assert.
445 if (!PendUpdates.empty()) {
446 DT.applyUpdates(PendUpdates);
447 PendUpdates.clear();
448 }
449 flushDelBB();
450 return DT;
451 }
452
453 /// Drops all internal state and forces a (slow) recalculation of the
454 /// DominatorTree based on the current state of the LLVM IR in F. This should
455 /// only be used in corner cases such as the Entry block of F being deleted.
456 void DeferredDominance::recalculate(Function &F) {
457 // flushDelBB must be flushed before the recalculation. The state of the IR
458 // must be consistent before the DT traversal algorithm determines the
459 // actual DT.
460 if (flushDelBB() || !PendUpdates.empty()) {
461 DT.recalculate(F);
462 PendUpdates.clear();
463 }
464 }
465
466 /// Debug method to help view the state of pending updates.
467 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
468 LLVM_DUMP_METHOD void DeferredDominance::dump() const {
469 raw_ostream &OS = llvm::dbgs();
470 OS << "PendUpdates:\n";
471 int I = 0;
472 for (auto U : PendUpdates) {
473 OS << " " << I << " : ";
474 ++I;
475 if (U.getKind() == DominatorTree::Insert)
476 OS << "Insert, ";
477 else
478 OS << "Delete, ";
479 BasicBlock *From = U.getFrom();
480 if (From) {
481 auto S = From->getName();
482 if (!From->hasName())
483 S = "(no name)";
484 OS << S << "(" << From << "), ";
485 } else {
486 OS << "(badref), ";
487 }
488 BasicBlock *To = U.getTo();
489 if (To) {
490 auto S = To->getName();
491 if (!To->hasName())
492 S = "(no_name)";
493 OS << S << "(" << To << ")\n";
494 } else {
495 OS << "(badref)\n";
496 }
497 }
498 OS << "DeletedBBs:\n";
499 I = 0;
500 for (auto BB : DeletedBBs) {
501 OS << " " << I << " : ";
502 ++I;
503 if (BB->hasName())
504 OS << BB->getName() << "(";
505 else
506 OS << "(no_name)(";
507 OS << BB << ")\n";
508 }
509 }
510 #endif
511
512 /// Apply an update (Kind, From, To) to the internal queued updates. The
513 /// update is only added when determined to be necessary. Checks for
514 /// self-domination, unnecessary updates, duplicate requests, and balanced
515 /// pairs of requests are all performed. Returns true if the update is
516 /// queued and false if it is discarded.
517 bool DeferredDominance::applyUpdate(DominatorTree::UpdateKind Kind,
518 BasicBlock *From, BasicBlock *To) {
519 if (From == To)
520 return false; // Cannot dominate self; discard update.
521
522 // Discard updates by inspecting the current state of successors of From.
523 // Since applyUpdate() must be called *after* the Terminator of From is
524 // altered we can determine if the update is unnecessary.
525 bool HasEdge = std::any_of(succ_begin(From), succ_end(From),
526 [To](BasicBlock *B) { return B == To; });
527 if (Kind == DominatorTree::Insert && !HasEdge)
528 return false; // Unnecessary Insert: edge does not exist in IR.
529 if (Kind == DominatorTree::Delete && HasEdge)
530 return false; // Unnecessary Delete: edge still exists in IR.
531
532 // Analyze pending updates to determine if the update is unnecessary.
533 DominatorTree::UpdateType Update = {Kind, From, To};
534 DominatorTree::UpdateType Invert = {Kind != DominatorTree::Insert
535 ? DominatorTree::Insert
536 : DominatorTree::Delete,
537 From, To};
538 for (auto I = PendUpdates.begin(), E = PendUpdates.end(); I != E; ++I) {
539 if (Update == *I)
540 return false; // Discard duplicate updates.
541 if (Invert == *I) {
542 // Update and Invert are both valid (equivalent to a no-op). Remove
543 // Invert from PendUpdates and discard the Update.
544 PendUpdates.erase(I);
545 return false;
546 }
547 }
548 PendUpdates.push_back(Update); // Save the valid update.
549 return true;
550 }
551
552 /// Performs all pending basic block deletions. We have to defer the deletion
553 /// of these blocks until after the DominatorTree updates are applied. The
554 /// internal workings of the DominatorTree code expect every update's From
555 /// and To blocks to exist and to be a member of the same Function.
556 bool DeferredDominance::flushDelBB() {
557 if (DeletedBBs.empty())
558 return false;
559 for (auto *BB : DeletedBBs)
560 BB->eraseFromParent();
561 DeletedBBs.clear();
562 return true;
563 }
1414 ConstantsTest.cpp
1515 DebugInfoTest.cpp
1616 DebugTypeODRUniquingTest.cpp
17 DeferredDominanceTest.cpp
1817 DominatorTreeTest.cpp
1918 DominatorTreeBatchUpdatesTest.cpp
2019 DomTreeUpdaterTest.cpp
+0
-344
unittests/IR/DeferredDominanceTest.cpp less more
None //===- llvm/unittests/IR/DeferredDominanceTest.cpp - DDT unit tests -------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/AsmParser/Parser.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/Dominators.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "gtest/gtest.h"
17
18 using namespace llvm;
19
20 static std::unique_ptr makeLLVMModule(LLVMContext &Context,
21 StringRef ModuleStr) {
22 SMDiagnostic Err;
23 std::unique_ptr M = parseAssemblyString(ModuleStr, Err, Context);
24 assert(M && "Bad LLVM IR?");
25 return M;
26 }
27
28 TEST(DeferredDominance, BasicOperations) {
29 StringRef FuncName = "f";
30 StringRef ModuleString =
31 "define i32 @f(i32 %i, i32 *%p) {\n"
32 " bb0:\n"
33 " store i32 %i, i32 *%p\n"
34 " switch i32 %i, label %bb1 [\n"
35 " i32 0, label %bb2\n"
36 " i32 1, label %bb2\n"
37 " i32 2, label %bb3\n"
38 " ]\n"
39 " bb1:\n"
40 " ret i32 1\n"
41 " bb2:\n"
42 " ret i32 2\n"
43 " bb3:\n"
44 " ret i32 3\n"
45 "}\n";
46 // Make the module.
47 LLVMContext Context;
48 std::unique_ptr M = makeLLVMModule(Context, ModuleString);
49 Function *F = M->getFunction(FuncName);
50 ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << ".";
51
52 // Make the DDT.
53 DominatorTree DT(*F);
54 DeferredDominance DDT(DT);
55 ASSERT_TRUE(DDT.flush().verify());
56
57 Function::iterator FI = F->begin();
58 BasicBlock *BB0 = &*FI++;
59 BasicBlock *BB1 = &*FI++;
60 BasicBlock *BB2 = &*FI++;
61 BasicBlock *BB3 = &*FI++;
62
63 // Test discards of invalid self-domination updates. These use the single
64 // short-hand interface but are still queued inside DDT.
65 DDT.deleteEdge(BB0, BB0);
66 DDT.insertEdge(BB1, BB1);
67
68 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
69 // entries are discarded.
70 std::vector Updates;
71 Updates.reserve(4);
72 Updates.push_back({DominatorTree::Delete, BB0, BB3});
73 Updates.push_back({DominatorTree::Delete, BB0, BB3});
74
75 // Unnecessary Insert: no edge bb1 -> bb2 after change to bb0.
76 Updates.push_back({DominatorTree::Insert, BB1, BB2});
77 // Unnecessary Delete: edge exists bb0 -> bb1 after change to bb0.
78 Updates.push_back({DominatorTree::Delete, BB0, BB1});
79
80 // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2.
81 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u);
82 BB0->getTerminator()->eraseFromParent();
83 BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0);
84 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
85
86 // Deletion of a BasicBlock is an immediate event. We remove all uses to the
87 // contained Instructions and change the Terminator to "unreachable" when
88 // queued for deletion. Its parent is still F until DDT.flush() is called. We
89 // don't defer this action because it can cause problems for other transforms
90 // or analysis as it's part of the actual CFG. We only defer updates to the
91 // DominatorTree. This code will crash if it is placed before the
92 // BranchInst::Create() call above.
93 ASSERT_FALSE(isa(BB3->getTerminator()));
94 EXPECT_FALSE(DDT.pendingDeletedBB(BB3));
95 DDT.deleteBB(BB3);
96 EXPECT_TRUE(DDT.pendingDeletedBB(BB3));
97 ASSERT_TRUE(isa(BB3->getTerminator()));
98 EXPECT_EQ(BB3->getParent(), F);
99
100 // Verify. Updates to DDT must be applied *after* all changes to the CFG
101 // (including block deletion).
102 DDT.applyUpdates(Updates);
103 ASSERT_TRUE(DDT.flush().verify());
104 }
105
106 TEST(DeferredDominance, PairedUpdate) {
107 StringRef FuncName = "f";
108 StringRef ModuleString =
109 "define i32 @f(i32 %i, i32 *%p) {\n"
110 " bb0:\n"
111 " store i32 %i, i32 *%p\n"
112 " switch i32 %i, label %bb1 [\n"
113 " i32 0, label %bb2\n"
114 " i32 1, label %bb2\n"
115 " ]\n"
116 " bb1:\n"
117 " ret i32 1\n"
118 " bb2:\n"
119 " ret i32 2\n"
120 "}\n";
121 // Make the module.
122 LLVMContext Context;
123 std::unique_ptr M = makeLLVMModule(Context, ModuleString);
124 Function *F = M->getFunction(FuncName);
125 ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << ".";
126
127 // Make the DDT.
128 DominatorTree DT(*F);
129 DeferredDominance DDT(DT);
130 ASSERT_TRUE(DDT.flush().verify());
131
132 Function::iterator FI = F->begin();
133 BasicBlock *BB0 = &*FI++;
134 BasicBlock *BB1 = &*FI++;
135 BasicBlock *BB2 = &*FI++;
136
137 // CFG Change: only edge from bb0 is bb0 -> bb1.
138 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u);
139 BB0->getTerminator()->eraseFromParent();
140 BranchInst::Create(BB1, BB0);
141 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
142
143 // Must be done after the CFG change. The applyUpdate() routine analyzes the
144 // current state of the CFG.
145 DDT.deleteEdge(BB0, BB2);
146
147 // CFG Change: bb0 now has bb0 -> bb1 and bb0 -> bb2.
148 // With this change no dominance has been altered from the original IR. DT
149 // doesn't care if the type of TerminatorInstruction changed, only if the
150 // unique edges have.
151 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
152 BB0->getTerminator()->eraseFromParent();
153 BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0);
154 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
155
156 // Must be done after the CFG change. The applyUpdate() routine analyzes the
157 // current state of the CFG. This DDT update pairs with the previous one and
158 // is cancelled out before ever applying updates to DT.
159 DDT.insertEdge(BB0, BB2);
160
161 // Test the empty DeletedBB list.
162 EXPECT_FALSE(DDT.pendingDeletedBB(BB0));
163 EXPECT_FALSE(DDT.pendingDeletedBB(BB1));
164 EXPECT_FALSE(DDT.pendingDeletedBB(BB2));
165
166 // The DT has no changes, this flush() simply returns a reference to the
167 // internal DT calculated at the beginning of this test.
168 ASSERT_TRUE(DDT.flush().verify());
169 }
170
171 TEST(DeferredDominance, ReplaceEntryBB) {
172 StringRef FuncName = "f";
173 StringRef ModuleString =
174 "define i32 @f() {\n"
175 "bb0:\n"
176 " br label %bb1\n"
177 " bb1:\n"
178 " ret i32 1\n"
179 "}\n";
180 // Make the module.
181 LLVMContext Context;
182 std::unique_ptr M = makeLLVMModule(Context, ModuleString);
183 Function *F = M->getFunction(FuncName);
184 ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << ".";
185
186 // Make the DDT.
187 DominatorTree DT(*F);
188 DeferredDominance DDT(DT);
189 ASSERT_TRUE(DDT.flush().verify());
190
191 Function::iterator FI = F->begin();
192 BasicBlock *BB0 = &*FI++;
193 BasicBlock *BB1 = &*FI++;
194
195 // Add a block as the new function entry BB. We also link it to BB0.
196 BasicBlock *NewEntry =
197 BasicBlock::Create(F->getContext(), "new_entry", F, BB0);
198 BranchInst::Create(BB0, NewEntry);
199 EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
200 EXPECT_TRUE(&F->getEntryBlock() == NewEntry);
201
202 // Insert the new edge between new_eentry -> bb0. Without this the
203 // recalculate() call below will not actually recalculate the DT as there
204 // are no changes pending and no blocks deleted.
205 DDT.insertEdge(NewEntry, BB0);
206
207 // Changing the Entry BB requires a full recalulation.
208 DDT.recalculate(*F);
209 ASSERT_TRUE(DDT.flush().verify());
210
211 // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1.
212 EXPECT_EQ(NewEntry->getTerminator()->getNumSuccessors(), 1u);
213 NewEntry->getTerminator()->eraseFromParent();
214 BranchInst::Create(BB1, NewEntry);
215 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
216
217 // Update the DDT. At this point bb0 now has no predecessors but is still a
218 // Child of F.
219 DDT.applyUpdates({{DominatorTree::Delete, NewEntry, BB0},
220 {DominatorTree::Insert, NewEntry, BB1}});
221 ASSERT_TRUE(DDT.flush().verify());
222
223 // Now remove bb0 from F.
224 ASSERT_FALSE(isa(BB0->getTerminator()));
225 EXPECT_FALSE(DDT.pendingDeletedBB(BB0));
226 DDT.deleteBB(BB0);
227 EXPECT_TRUE(DDT.pendingDeletedBB(BB0));
228 ASSERT_TRUE(isa(BB0->getTerminator()));
229 EXPECT_EQ(BB0->getParent(), F);
230
231 // Perform a full recalculation of the DDT. It is not necessary here but we
232 // do this to test the case when there are no pending DT updates but there are
233 // pending deleted BBs.
234 DDT.recalculate(*F);
235 ASSERT_TRUE(DDT.flush().verify());
236 }
237
238 TEST(DeferredDominance, InheritedPreds) {
239 StringRef FuncName = "f";
240 StringRef ModuleString =
241 "define i32 @f(i32 %i, i32 *%p) {\n"
242 " bb0:\n"
243 " store i32 %i, i32 *%p\n"
244 " switch i32 %i, label %bb1 [\n"
245 " i32 2, label %bb2\n"
246 " i32 3, label %bb3\n"
247 " ]\n"
248 " bb1:\n"
249 " br label %bb3\n"
250 " bb2:\n"
251 " br label %bb3\n"
252 " bb3:\n"
253 " ret i32 3\n"
254 "}\n";
255 // Make the module.
256 LLVMContext Context;
257 std::unique_ptr M = makeLLVMModule(Context, ModuleString);
258 Function *F = M->getFunction(FuncName);
259 ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << ".";
260
261 // Make the DDT.
262 DominatorTree DT(*F);
263 DeferredDominance DDT(DT);
264 ASSERT_TRUE(DDT.flush().verify());
265
266 Function::iterator FI = F->begin();
267 BasicBlock *BB0 = &*FI++;
268 BasicBlock *BB1 = &*FI++;
269 BasicBlock *BB2 = &*FI++;
270 BasicBlock *BB3 = &*FI++;
271
272 // There are several CFG locations where we have:
273 //
274 // pred1..predN
275 // | |
276 // +> curr <+ converted into: pred1..predN curr
277 // | | |
278 // v +> succ <+
279 // succ
280 //
281 // There is a specific shape of this we have to be careful of:
282 //
283 // pred1..predN
284 // || |
285 // |+> curr <+ converted into: pred1..predN curr
286 // | | | |
287 // | v +> succ <+
288 // +-> succ
289 //
290 // While the final CFG form is functionally identical the updates to
291 // DDT are not. In the first case we must have DDT.insertEdge(Pred1, Succ)
292 // while in the latter case we must *NOT* have DDT.insertEdge(Pred1, Succ).
293
294 // CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to
295 // remove bb2.
296 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u);
297 BB0->getTerminator()->eraseFromParent();
298 BranchInst::Create(BB1, BB3, ConstantInt::getTrue(F->getContext()), BB0);
299 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
300
301 // Remove bb2 from F. This has to happen before the call to applyUpdates() for
302 // DDT to detect there is no longer an edge between bb2 -> bb3. The deleteBB()
303 // method converts bb2's TI into "unreachable".
304 ASSERT_FALSE(isa(BB2->getTerminator()));
305 EXPECT_FALSE(DDT.pendingDeletedBB(BB2));
306 DDT.deleteBB(BB2);
307 EXPECT_TRUE(DDT.pendingDeletedBB(BB2));
308 ASSERT_TRUE(isa(BB2->getTerminator()));
309 EXPECT_EQ(BB2->getParent(), F);
310
311 // Queue up the DDT updates.
312 std::vector Updates;
313 Updates.reserve(4);
314 Updates.push_back({DominatorTree::Delete, BB0, BB2});
315 Updates.push_back({DominatorTree::Delete, BB2, BB3});
316
317 // Handle the specific shape case next.
318 // CFG Change: bb0 now only branches to bb3. We are preparing to remove bb1.
319 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
320 BB0->getTerminator()->eraseFromParent();
321 BranchInst::Create(BB3, BB0);
322 EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
323
324 // Remove bb1 from F. This has to happen before the call to applyUpdates() for
325 // DDT to detect there is no longer an edge between bb1 -> bb3. The deleteBB()
326 // method converts bb1's TI into "unreachable".
327 ASSERT_FALSE(isa(BB1->getTerminator()));
328 EXPECT_FALSE(DDT.pendingDeletedBB(BB1));
329 DDT.deleteBB(BB1);
330 EXPECT_TRUE(DDT.pendingDeletedBB(BB1));
331 ASSERT_TRUE(isa(BB1->getTerminator()));
332 EXPECT_EQ(BB1->getParent(), F);
333
334 // Update the DDT. In this case we don't call DDT.insertEdge(BB0, BB3) because
335 // the edge previously existed at the start of this test when DT was first
336 // created.
337 Updates.push_back({DominatorTree::Delete, BB0, BB1});
338 Updates.push_back({DominatorTree::Delete, BB1, BB3});
339
340 // Verify everything.
341 DDT.applyUpdates(Updates);
342 ASSERT_TRUE(DDT.flush().verify());
343 }