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