1 //===- RegionInfoImpl.h - SESE region detection analysis --------*- C++ -*-===// 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 // Detects single entry single exit regions in the control flow graph. 9 //===----------------------------------------------------------------------===// 10 11 #ifndef LLVM_ANALYSIS_REGIONINFOIMPL_H 12 #define LLVM_ANALYSIS_REGIONINFOIMPL_H 13 14 #include "llvm/ADT/GraphTraits.h" 15 #include "llvm/ADT/PostOrderIterator.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/Analysis/LoopInfo.h" 19 #include "llvm/Analysis/PostDominators.h" 20 #include "llvm/Analysis/RegionInfo.h" 21 #include "llvm/Analysis/RegionIterator.h" 22 #include "llvm/Config/llvm-config.h" 23 #include "llvm/Support/Debug.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include <algorithm> 26 #include <cassert> 27 #include <iterator> 28 #include <memory> 29 #include <set> 30 #include <string> 31 #include <type_traits> 32 #include <vector> 33 34 #define DEBUG_TYPE "region" 35 36 namespace llvm { 37 class raw_ostream; 38 39 //===----------------------------------------------------------------------===// 40 /// RegionBase Implementation 41 template <class Tr> 42 RegionBase<Tr>::RegionBase(BlockT *Entry, BlockT *Exit, 43 typename Tr::RegionInfoT *RInfo, DomTreeT *dt, 44 RegionT *Parent) 45 : RegionNodeBase<Tr>(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {} 46 47 template <class Tr> 48 RegionBase<Tr>::~RegionBase() { 49 // Only clean the cache for this Region. Caches of child Regions will be 50 // cleaned when the child Regions are deleted. 51 BBNodeMap.clear(); 52 } 53 54 template <class Tr> 55 void RegionBase<Tr>::replaceEntry(BlockT *BB) { 56 this->entry.setPointer(BB); 57 } 58 59 template <class Tr> 60 void RegionBase<Tr>::replaceExit(BlockT *BB) { 61 assert(exit && "No exit to replace!"); 62 exit = BB; 63 } 64 65 template <class Tr> 66 void RegionBase<Tr>::replaceEntryRecursive(BlockT *NewEntry) { 67 std::vector<RegionT *> RegionQueue; 68 BlockT *OldEntry = getEntry(); 69 70 RegionQueue.push_back(static_cast<RegionT *>(this)); 71 while (!RegionQueue.empty()) { 72 RegionT *R = RegionQueue.back(); 73 RegionQueue.pop_back(); 74 75 R->replaceEntry(NewEntry); 76 for (std::unique_ptr<RegionT> &Child : *R) { 77 if (Child->getEntry() == OldEntry) 78 RegionQueue.push_back(Child.get()); 79 } 80 } 81 } 82 83 template <class Tr> 84 void RegionBase<Tr>::replaceExitRecursive(BlockT *NewExit) { 85 std::vector<RegionT *> RegionQueue; 86 BlockT *OldExit = getExit(); 87 88 RegionQueue.push_back(static_cast<RegionT *>(this)); 89 while (!RegionQueue.empty()) { 90 RegionT *R = RegionQueue.back(); 91 RegionQueue.pop_back(); 92 93 R->replaceExit(NewExit); 94 for (std::unique_ptr<RegionT> &Child : *R) { 95 if (Child->getExit() == OldExit) 96 RegionQueue.push_back(Child.get()); 97 } 98 } 99 } 100 101 template <class Tr> 102 bool RegionBase<Tr>::contains(const BlockT *B) const { 103 BlockT *BB = const_cast<BlockT *>(B); 104 105 if (!DT->getNode(BB)) 106 return false; 107 108 BlockT *entry = getEntry(), *exit = getExit(); 109 110 // Toplevel region. 111 if (!exit) 112 return true; 113 114 return (DT->dominates(entry, BB) && 115 !(DT->dominates(exit, BB) && DT->dominates(entry, exit))); 116 } 117 118 template <class Tr> 119 bool RegionBase<Tr>::contains(const LoopT *L) const { 120 // BBs that are not part of any loop are element of the Loop 121 // described by the NULL pointer. This loop is not part of any region, 122 // except if the region describes the whole function. 123 if (!L) 124 return getExit() == nullptr; 125 126 if (!contains(L->getHeader())) 127 return false; 128 129 SmallVector<BlockT *, 8> ExitingBlocks; 130 L->getExitingBlocks(ExitingBlocks); 131 132 for (BlockT *BB : ExitingBlocks) { 133 if (!contains(BB)) 134 return false; 135 } 136 137 return true; 138 } 139 140 template <class Tr> 141 typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopT *L) const { 142 if (!contains(L)) 143 return nullptr; 144 145 while (L && contains(L->getParentLoop())) { 146 L = L->getParentLoop(); 147 } 148 149 return L; 150 } 151 152 template <class Tr> 153 typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopInfoT *LI, 154 BlockT *BB) const { 155 assert(LI && BB && "LI and BB cannot be null!"); 156 LoopT *L = LI->getLoopFor(BB); 157 return outermostLoopInRegion(L); 158 } 159 160 template <class Tr> 161 typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getEnteringBlock() const { 162 auto isEnteringBlock = [&](BlockT *Pred, bool AllowRepeats) -> BlockT * { 163 assert(!AllowRepeats && "Unexpected parameter value."); 164 return DT->getNode(Pred) && !contains(Pred) ? Pred : nullptr; 165 }; 166 return find_singleton<BlockT>(llvm::inverse_children<BlockT *>(getEntry()), 167 isEnteringBlock); 168 } 169 170 template <class Tr> 171 bool RegionBase<Tr>::getExitingBlocks( 172 SmallVectorImpl<BlockT *> &Exitings) const { 173 bool CoverAll = true; 174 175 if (!exit) 176 return CoverAll; 177 178 for (BlockT *Pred : llvm::inverse_children<BlockT *>(exit)) { 179 if (contains(Pred)) { 180 Exitings.push_back(Pred); 181 continue; 182 } 183 184 CoverAll = false; 185 } 186 187 return CoverAll; 188 } 189 190 template <class Tr> 191 typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getExitingBlock() const { 192 BlockT *exit = getExit(); 193 if (!exit) 194 return nullptr; 195 196 auto isContained = [&](BlockT *Pred, bool AllowRepeats) -> BlockT * { 197 assert(!AllowRepeats && "Unexpected parameter value."); 198 return contains(Pred) ? Pred : nullptr; 199 }; 200 return find_singleton<BlockT>(llvm::inverse_children<BlockT *>(exit), 201 isContained); 202 } 203 204 template <class Tr> 205 bool RegionBase<Tr>::isSimple() const { 206 return !isTopLevelRegion() && getEnteringBlock() && getExitingBlock(); 207 } 208 209 template <class Tr> 210 std::string RegionBase<Tr>::getNameStr() const { 211 std::string exitName; 212 std::string entryName; 213 214 if (getEntry()->getName().empty()) { 215 raw_string_ostream OS(entryName); 216 217 getEntry()->printAsOperand(OS, false); 218 } else 219 entryName = std::string(getEntry()->getName()); 220 221 if (getExit()) { 222 if (getExit()->getName().empty()) { 223 raw_string_ostream OS(exitName); 224 225 getExit()->printAsOperand(OS, false); 226 } else 227 exitName = std::string(getExit()->getName()); 228 } else 229 exitName = "<Function Return>"; 230 231 return entryName + " => " + exitName; 232 } 233 234 template <class Tr> 235 void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const { 236 if (!contains(BB)) 237 report_fatal_error("Broken region found: enumerated BB not in region!"); 238 239 BlockT *entry = getEntry(), *exit = getExit(); 240 241 for (BlockT *Succ : llvm::children<BlockT *>(BB)) { 242 if (!contains(Succ) && exit != Succ) 243 report_fatal_error("Broken region found: edges leaving the region must go " 244 "to the exit node!"); 245 } 246 247 if (entry != BB) { 248 for (BlockT *Pred : llvm::inverse_children<BlockT *>(BB)) { 249 // Allow predecessors that are unreachable, as these are ignored during 250 // region analysis. 251 if (!contains(Pred) && DT->isReachableFromEntry(Pred)) 252 report_fatal_error("Broken region found: edges entering the region must " 253 "go to the entry node!"); 254 } 255 } 256 } 257 258 template <class Tr> 259 void RegionBase<Tr>::verifyWalk(BlockT *BB, std::set<BlockT *> *visited) const { 260 BlockT *exit = getExit(); 261 262 visited->insert(BB); 263 264 verifyBBInRegion(BB); 265 266 for (BlockT *Succ : llvm::children<BlockT *>(BB)) { 267 if (Succ != exit && visited->find(Succ) == visited->end()) 268 verifyWalk(Succ, visited); 269 } 270 } 271 272 template <class Tr> 273 void RegionBase<Tr>::verifyRegion() const { 274 // Only do verification when user wants to, otherwise this expensive check 275 // will be invoked by PMDataManager::verifyPreservedAnalysis when 276 // a regionpass (marked PreservedAll) finish. 277 if (!RegionInfoBase<Tr>::VerifyRegionInfo) 278 return; 279 280 std::set<BlockT *> visited; 281 verifyWalk(getEntry(), &visited); 282 } 283 284 template <class Tr> 285 void RegionBase<Tr>::verifyRegionNest() const { 286 for (const std::unique_ptr<RegionT> &R : *this) 287 R->verifyRegionNest(); 288 289 verifyRegion(); 290 } 291 292 template <class Tr> 293 typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_begin() { 294 return GraphTraits<RegionT *>::nodes_begin(static_cast<RegionT *>(this)); 295 } 296 297 template <class Tr> 298 typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_end() { 299 return GraphTraits<RegionT *>::nodes_end(static_cast<RegionT *>(this)); 300 } 301 302 template <class Tr> 303 typename RegionBase<Tr>::const_element_iterator 304 RegionBase<Tr>::element_begin() const { 305 return GraphTraits<const RegionT *>::nodes_begin( 306 static_cast<const RegionT *>(this)); 307 } 308 309 template <class Tr> 310 typename RegionBase<Tr>::const_element_iterator 311 RegionBase<Tr>::element_end() const { 312 return GraphTraits<const RegionT *>::nodes_end( 313 static_cast<const RegionT *>(this)); 314 } 315 316 template <class Tr> 317 typename Tr::RegionT *RegionBase<Tr>::getSubRegionNode(BlockT *BB) const { 318 using RegionT = typename Tr::RegionT; 319 320 RegionT *R = RI->getRegionFor(BB); 321 322 if (!R || R == this) 323 return nullptr; 324 325 // If we pass the BB out of this region, that means our code is broken. 326 assert(contains(R) && "BB not in current region!"); 327 328 while (contains(R->getParent()) && R->getParent() != this) 329 R = R->getParent(); 330 331 if (R->getEntry() != BB) 332 return nullptr; 333 334 return R; 335 } 336 337 template <class Tr> 338 typename Tr::RegionNodeT *RegionBase<Tr>::getBBNode(BlockT *BB) const { 339 assert(contains(BB) && "Can get BB node out of this region!"); 340 341 auto [at, Inserted] = BBNodeMap.try_emplace(BB); 342 if (Inserted) { 343 auto Deconst = const_cast<RegionBase<Tr> *>(this); 344 at->second = 345 std::make_unique<RegionNodeT>(static_cast<RegionT *>(Deconst), BB); 346 } 347 return at->second.get(); 348 } 349 350 template <class Tr> 351 typename Tr::RegionNodeT *RegionBase<Tr>::getNode(BlockT *BB) const { 352 assert(contains(BB) && "Can get BB node out of this region!"); 353 if (RegionT *Child = getSubRegionNode(BB)) 354 return Child->getNode(); 355 356 return getBBNode(BB); 357 } 358 359 template <class Tr> 360 void RegionBase<Tr>::transferChildrenTo(RegionT *To) { 361 for (std::unique_ptr<RegionT> &R : *this) { 362 R->parent = To; 363 To->children.push_back(std::move(R)); 364 } 365 children.clear(); 366 } 367 368 template <class Tr> 369 void RegionBase<Tr>::addSubRegion(RegionT *SubRegion, bool moveChildren) { 370 assert(!SubRegion->parent && "SubRegion already has a parent!"); 371 assert(llvm::none_of(*this, 372 [&](const std::unique_ptr<RegionT> &R) { 373 return R.get() == SubRegion; 374 }) && 375 "Subregion already exists!"); 376 377 SubRegion->parent = static_cast<RegionT *>(this); 378 children.push_back(std::unique_ptr<RegionT>(SubRegion)); 379 380 if (!moveChildren) 381 return; 382 383 assert(SubRegion->children.empty() && 384 "SubRegions that contain children are not supported"); 385 386 for (RegionNodeT *Element : elements()) { 387 if (!Element->isSubRegion()) { 388 BlockT *BB = Element->template getNodeAs<BlockT>(); 389 390 if (SubRegion->contains(BB)) 391 RI->setRegionFor(BB, SubRegion); 392 } 393 } 394 395 std::vector<std::unique_ptr<RegionT>> Keep; 396 for (std::unique_ptr<RegionT> &R : *this) { 397 if (SubRegion->contains(R.get()) && R.get() != SubRegion) { 398 R->parent = SubRegion; 399 SubRegion->children.push_back(std::move(R)); 400 } else 401 Keep.push_back(std::move(R)); 402 } 403 404 children.clear(); 405 children.insert( 406 children.begin(), 407 std::move_iterator<typename RegionSet::iterator>(Keep.begin()), 408 std::move_iterator<typename RegionSet::iterator>(Keep.end())); 409 } 410 411 template <class Tr> 412 typename Tr::RegionT *RegionBase<Tr>::removeSubRegion(RegionT *Child) { 413 assert(Child->parent == this && "Child is not a child of this region!"); 414 Child->parent = nullptr; 415 typename RegionSet::iterator I = 416 llvm::find_if(children, [&](const std::unique_ptr<RegionT> &R) { 417 return R.get() == Child; 418 }); 419 assert(I != children.end() && "Region does not exit. Unable to remove."); 420 children.erase(children.begin() + (I - begin())); 421 return Child; 422 } 423 424 template <class Tr> 425 unsigned RegionBase<Tr>::getDepth() const { 426 unsigned Depth = 0; 427 428 for (RegionT *R = getParent(); R != nullptr; R = R->getParent()) 429 ++Depth; 430 431 return Depth; 432 } 433 434 template <class Tr> 435 typename Tr::RegionT *RegionBase<Tr>::getExpandedRegion() const { 436 unsigned NumSuccessors = Tr::getNumSuccessors(exit); 437 438 if (NumSuccessors == 0) 439 return nullptr; 440 441 RegionT *R = RI->getRegionFor(exit); 442 443 if (R->getEntry() != exit) { 444 for (BlockT *Pred : llvm::inverse_children<BlockT *>(getExit())) 445 if (!contains(Pred)) 446 return nullptr; 447 if (Tr::getNumSuccessors(exit) == 1) 448 return new RegionT(getEntry(), *BlockTraits::child_begin(exit), RI, DT); 449 return nullptr; 450 } 451 452 while (R->getParent() && R->getParent()->getEntry() == exit) 453 R = R->getParent(); 454 455 for (BlockT *Pred : llvm::inverse_children<BlockT *>(getExit())) { 456 if (!(contains(Pred) || R->contains(Pred))) 457 return nullptr; 458 } 459 460 return new RegionT(getEntry(), R->getExit(), RI, DT); 461 } 462 463 template <class Tr> 464 void RegionBase<Tr>::print(raw_ostream &OS, bool print_tree, unsigned level, 465 PrintStyle Style) const { 466 if (print_tree) 467 OS.indent(level * 2) << '[' << level << "] " << getNameStr(); 468 else 469 OS.indent(level * 2) << getNameStr(); 470 471 OS << '\n'; 472 473 if (Style != PrintNone) { 474 OS.indent(level * 2) << "{\n"; 475 OS.indent(level * 2 + 2); 476 477 if (Style == PrintBB) { 478 for (const auto *BB : blocks()) 479 OS << BB->getName() << ", "; // TODO: remove the last "," 480 } else if (Style == PrintRN) { 481 for (const RegionNodeT *Element : elements()) { 482 OS << *Element << ", "; // TODO: remove the last ", 483 } 484 } 485 486 OS << '\n'; 487 } 488 489 if (print_tree) { 490 for (const std::unique_ptr<RegionT> &R : *this) 491 R->print(OS, print_tree, level + 1, Style); 492 } 493 494 if (Style != PrintNone) 495 OS.indent(level * 2) << "} \n"; 496 } 497 498 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 499 template <class Tr> 500 void RegionBase<Tr>::dump() const { 501 print(dbgs(), true, getDepth(), RegionInfoBase<Tr>::printStyle); 502 } 503 #endif 504 505 template <class Tr> 506 void RegionBase<Tr>::clearNodeCache() { 507 BBNodeMap.clear(); 508 for (std::unique_ptr<RegionT> &R : *this) 509 R->clearNodeCache(); 510 } 511 512 //===----------------------------------------------------------------------===// 513 // RegionInfoBase implementation 514 // 515 516 template <class Tr> 517 RegionInfoBase<Tr>::RegionInfoBase() = default; 518 519 template <class Tr> 520 RegionInfoBase<Tr>::~RegionInfoBase() { 521 releaseMemory(); 522 } 523 524 template <class Tr> 525 void RegionInfoBase<Tr>::verifyBBMap(const RegionT *R) const { 526 assert(R && "Re must be non-null"); 527 for (const typename Tr::RegionNodeT *Element : R->elements()) { 528 if (Element->isSubRegion()) { 529 const RegionT *SR = Element->template getNodeAs<RegionT>(); 530 verifyBBMap(SR); 531 } else { 532 BlockT *BB = Element->template getNodeAs<BlockT>(); 533 if (getRegionFor(BB) != R) 534 report_fatal_error("BB map does not match region nesting"); 535 } 536 } 537 } 538 539 template <class Tr> 540 bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry, 541 BlockT *exit) const { 542 for (BlockT *P : llvm::inverse_children<BlockT *>(BB)) { 543 if (DT->dominates(entry, P) && !DT->dominates(exit, P)) 544 return false; 545 } 546 547 return true; 548 } 549 550 template <class Tr> 551 bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const { 552 assert(entry && exit && "entry and exit must not be null!"); 553 554 using DST = typename DomFrontierT::DomSetType; 555 556 DST *entrySuccs = &DF->find(entry)->second; 557 558 // Exit is the header of a loop that contains the entry. In this case, 559 // the dominance frontier must only contain the exit. 560 if (!DT->dominates(entry, exit)) { 561 for (BlockT *successor : *entrySuccs) { 562 if (successor != exit && successor != entry) 563 return false; 564 } 565 566 return true; 567 } 568 569 DST *exitSuccs = &DF->find(exit)->second; 570 571 // Do not allow edges leaving the region. 572 for (BlockT *Succ : *entrySuccs) { 573 if (Succ == exit || Succ == entry) 574 continue; 575 if (!exitSuccs->contains(Succ)) 576 return false; 577 if (!isCommonDomFrontier(Succ, entry, exit)) 578 return false; 579 } 580 581 // Do not allow edges pointing into the region. 582 for (BlockT *Succ : *exitSuccs) { 583 if (DT->properlyDominates(entry, Succ) && Succ != exit) 584 return false; 585 } 586 587 return true; 588 } 589 590 template <class Tr> 591 void RegionInfoBase<Tr>::insertShortCut(BlockT *entry, BlockT *exit, 592 BBtoBBMap *ShortCut) const { 593 assert(entry && exit && "entry and exit must not be null!"); 594 595 typename BBtoBBMap::iterator e = ShortCut->find(exit); 596 597 if (e == ShortCut->end()) 598 // No further region at exit available. 599 (*ShortCut)[entry] = exit; 600 else { 601 // We found a region e that starts at exit. Therefore (entry, e->second) 602 // is also a region, that is larger than (entry, exit). Insert the 603 // larger one. 604 BlockT *BB = e->second; 605 (*ShortCut)[entry] = BB; 606 } 607 } 608 609 template <class Tr> 610 typename Tr::DomTreeNodeT * 611 RegionInfoBase<Tr>::getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const { 612 typename BBtoBBMap::iterator e = ShortCut->find(N->getBlock()); 613 614 if (e == ShortCut->end()) 615 return N->getIDom(); 616 617 return PDT->getNode(e->second)->getIDom(); 618 } 619 620 template <class Tr> 621 bool RegionInfoBase<Tr>::isTrivialRegion(BlockT *entry, BlockT *exit) const { 622 assert(entry && exit && "entry and exit must not be null!"); 623 624 unsigned num_successors = 625 BlockTraits::child_end(entry) - BlockTraits::child_begin(entry); 626 627 if (num_successors <= 1 && exit == *(BlockTraits::child_begin(entry))) 628 return true; 629 630 return false; 631 } 632 633 template <class Tr> 634 typename Tr::RegionT *RegionInfoBase<Tr>::createRegion(BlockT *entry, 635 BlockT *exit) { 636 assert(entry && exit && "entry and exit must not be null!"); 637 638 if (isTrivialRegion(entry, exit)) 639 return nullptr; 640 641 RegionT *region = 642 new RegionT(entry, exit, static_cast<RegionInfoT *>(this), DT); 643 BBtoRegion.insert({entry, region}); 644 645 region->verifyRegion(); 646 647 updateStatistics(region); 648 return region; 649 } 650 651 template <class Tr> 652 void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry, 653 BBtoBBMap *ShortCut) { 654 assert(entry); 655 656 DomTreeNodeT *N = PDT->getNode(entry); 657 if (!N) 658 return; 659 660 RegionT *lastRegion = nullptr; 661 BlockT *lastExit = entry; 662 663 // As only a BasicBlock that postdominates entry can finish a region, walk the 664 // post dominance tree upwards. 665 while ((N = getNextPostDom(N, ShortCut))) { 666 BlockT *exit = N->getBlock(); 667 668 if (!exit) 669 break; 670 671 if (isRegion(entry, exit)) { 672 RegionT *newRegion = createRegion(entry, exit); 673 674 if (lastRegion) 675 newRegion->addSubRegion(lastRegion); 676 677 lastRegion = newRegion; 678 lastExit = exit; 679 } 680 681 // This can never be a region, so stop the search. 682 if (!DT->dominates(entry, exit)) 683 break; 684 } 685 686 // Tried to create regions from entry to lastExit. Next time take a 687 // shortcut from entry to lastExit. 688 if (lastExit != entry) 689 insertShortCut(entry, lastExit, ShortCut); 690 } 691 692 template <class Tr> 693 void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) { 694 using FuncPtrT = std::add_pointer_t<FuncT>; 695 696 BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F); 697 DomTreeNodeT *N = DT->getNode(entry); 698 699 // Iterate over the dominance tree in post order to start with the small 700 // regions from the bottom of the dominance tree. If the small regions are 701 // detected first, detection of bigger regions is faster, as we can jump 702 // over the small regions. 703 for (auto DomNode : post_order(N)) 704 findRegionsWithEntry(DomNode->getBlock(), ShortCut); 705 } 706 707 template <class Tr> 708 typename Tr::RegionT *RegionInfoBase<Tr>::getTopMostParent(RegionT *region) { 709 while (region->getParent()) 710 region = region->getParent(); 711 712 return region; 713 } 714 715 template <class Tr> 716 void RegionInfoBase<Tr>::buildRegionsTree(DomTreeNodeT *N, RegionT *region) { 717 BlockT *BB = N->getBlock(); 718 719 // Passed region exit 720 while (BB == region->getExit()) 721 region = region->getParent(); 722 723 typename BBtoRegionMap::iterator it = BBtoRegion.find(BB); 724 725 // This basic block is a start block of a region. It is already in the 726 // BBtoRegion relation. Only the child basic blocks have to be updated. 727 if (it != BBtoRegion.end()) { 728 RegionT *newRegion = it->second; 729 region->addSubRegion(getTopMostParent(newRegion)); 730 region = newRegion; 731 } else { 732 BBtoRegion[BB] = region; 733 } 734 735 for (DomTreeNodeBase<BlockT> *C : *N) { 736 buildRegionsTree(C, region); 737 } 738 } 739 740 #ifdef EXPENSIVE_CHECKS 741 template <class Tr> 742 bool RegionInfoBase<Tr>::VerifyRegionInfo = true; 743 #else 744 template <class Tr> 745 bool RegionInfoBase<Tr>::VerifyRegionInfo = false; 746 #endif 747 748 template <class Tr> 749 typename Tr::RegionT::PrintStyle RegionInfoBase<Tr>::printStyle = 750 RegionBase<Tr>::PrintNone; 751 752 template <class Tr> 753 void RegionInfoBase<Tr>::print(raw_ostream &OS) const { 754 OS << "Region tree:\n"; 755 TopLevelRegion->print(OS, true, 0, printStyle); 756 OS << "End region tree\n"; 757 } 758 759 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 760 template <class Tr> 761 void RegionInfoBase<Tr>::dump() const { print(dbgs()); } 762 #endif 763 764 template <class Tr> void RegionInfoBase<Tr>::releaseMemory() { 765 BBtoRegion.clear(); 766 if (TopLevelRegion) { 767 delete TopLevelRegion; 768 TopLevelRegion = nullptr; 769 } 770 } 771 772 template <class Tr> 773 void RegionInfoBase<Tr>::verifyAnalysis() const { 774 // Do only verify regions if explicitely activated using EXPENSIVE_CHECKS or 775 // -verify-region-info 776 if (!RegionInfoBase<Tr>::VerifyRegionInfo) 777 return; 778 779 TopLevelRegion->verifyRegionNest(); 780 781 verifyBBMap(TopLevelRegion); 782 } 783 784 // Region pass manager support. 785 template <class Tr> 786 typename Tr::RegionT *RegionInfoBase<Tr>::getRegionFor(BlockT *BB) const { 787 return BBtoRegion.lookup(BB); 788 } 789 790 template <class Tr> 791 void RegionInfoBase<Tr>::setRegionFor(BlockT *BB, RegionT *R) { 792 BBtoRegion[BB] = R; 793 } 794 795 template <class Tr> 796 typename Tr::RegionT *RegionInfoBase<Tr>::operator[](BlockT *BB) const { 797 return getRegionFor(BB); 798 } 799 800 template <class Tr> 801 typename RegionInfoBase<Tr>::BlockT * 802 RegionInfoBase<Tr>::getMaxRegionExit(BlockT *BB) const { 803 BlockT *Exit = nullptr; 804 805 while (true) { 806 // Get largest region that starts at BB. 807 RegionT *R = getRegionFor(BB); 808 while (R && R->getParent() && R->getParent()->getEntry() == BB) 809 R = R->getParent(); 810 811 // Get the single exit of BB. 812 if (R && R->getEntry() == BB) 813 Exit = R->getExit(); 814 else if (std::next(BlockTraits::child_begin(BB)) == 815 BlockTraits::child_end(BB)) 816 Exit = *BlockTraits::child_begin(BB); 817 else // No single exit exists. 818 return Exit; 819 820 // Get largest region that starts at Exit. 821 RegionT *ExitR = getRegionFor(Exit); 822 while (ExitR && ExitR->getParent() && 823 ExitR->getParent()->getEntry() == Exit) 824 ExitR = ExitR->getParent(); 825 826 for (BlockT *Pred : llvm::inverse_children<BlockT *>(Exit)) { 827 if (!R->contains(Pred) && !ExitR->contains(Pred)) 828 break; 829 } 830 831 // This stops infinite cycles. 832 if (DT->dominates(Exit, BB)) 833 break; 834 835 BB = Exit; 836 } 837 838 return Exit; 839 } 840 841 template <class Tr> 842 typename Tr::RegionT *RegionInfoBase<Tr>::getCommonRegion(RegionT *A, 843 RegionT *B) const { 844 assert(A && B && "One of the Regions is NULL"); 845 846 if (A->contains(B)) 847 return A; 848 849 while (!B->contains(A)) 850 B = B->getParent(); 851 852 return B; 853 } 854 855 template <class Tr> 856 typename Tr::RegionT * 857 RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const { 858 RegionT *ret = Regions.pop_back_val(); 859 860 for (RegionT *R : Regions) 861 ret = getCommonRegion(ret, R); 862 863 return ret; 864 } 865 866 template <class Tr> 867 typename Tr::RegionT * 868 RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const { 869 RegionT *ret = getRegionFor(BBs.back()); 870 BBs.pop_back(); 871 872 for (BlockT *BB : BBs) 873 ret = getCommonRegion(ret, getRegionFor(BB)); 874 875 return ret; 876 } 877 878 template <class Tr> 879 void RegionInfoBase<Tr>::calculate(FuncT &F) { 880 using FuncPtrT = std::add_pointer_t<FuncT>; 881 882 // ShortCut a function where for every BB the exit of the largest region 883 // starting with BB is stored. These regions can be threated as single BBS. 884 // This improves performance on linear CFGs. 885 BBtoBBMap ShortCut; 886 887 scanForRegions(F, &ShortCut); 888 BlockT *BB = GraphTraits<FuncPtrT>::getEntryNode(&F); 889 buildRegionsTree(DT->getNode(BB), TopLevelRegion); 890 } 891 892 } // end namespace llvm 893 894 #undef DEBUG_TYPE 895 896 #endif // LLVM_ANALYSIS_REGIONINFOIMPL_H 897