LCOV - code coverage report
Current view: top level - include/llvm/Analysis - RegionInfoImpl.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 264 339 77.9 %
Date: 2018-10-20 13:21:21 Functions: 44 114 38.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13