LLVM API Documentation
00001 //===- RegionInfoImpl.h - SESE region detection analysis --------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // Detects single entry single exit regions in the control flow graph. 00010 //===----------------------------------------------------------------------===// 00011 00012 #ifndef LLVM_ANALYSIS_REGIONINFOIMPL_H 00013 #define LLVM_ANALYSIS_REGIONINFOIMPL_H 00014 00015 #include "llvm/Analysis/RegionInfo.h" 00016 #include "llvm/ADT/PostOrderIterator.h" 00017 #include "llvm/Analysis/DominanceFrontier.h" 00018 #include "llvm/Analysis/LoopInfo.h" 00019 #include "llvm/Analysis/PostDominators.h" 00020 #include "llvm/Analysis/RegionIterator.h" 00021 #include "llvm/Support/CommandLine.h" 00022 #include "llvm/Support/Debug.h" 00023 #include "llvm/Support/ErrorHandling.h" 00024 #include <algorithm> 00025 #include <iterator> 00026 #include <set> 00027 00028 namespace llvm { 00029 00030 #define DEBUG_TYPE "region" 00031 00032 //===----------------------------------------------------------------------===// 00033 /// RegionBase Implementation 00034 template <class Tr> 00035 RegionBase<Tr>::RegionBase(BlockT *Entry, BlockT *Exit, 00036 typename Tr::RegionInfoT *RInfo, DomTreeT *dt, 00037 RegionT *Parent) 00038 : RegionNodeBase<Tr>(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {} 00039 00040 template <class Tr> 00041 RegionBase<Tr>::~RegionBase() { 00042 // Free the cached nodes. 00043 for (typename BBNodeMapT::iterator it = BBNodeMap.begin(), 00044 ie = BBNodeMap.end(); 00045 it != ie; ++it) 00046 delete it->second; 00047 00048 // Only clean the cache for this Region. Caches of child Regions will be 00049 // cleaned when the child Regions are deleted. 00050 BBNodeMap.clear(); 00051 } 00052 00053 template <class Tr> 00054 void RegionBase<Tr>::replaceEntry(BlockT *BB) { 00055 this->entry.setPointer(BB); 00056 } 00057 00058 template <class Tr> 00059 void RegionBase<Tr>::replaceExit(BlockT *BB) { 00060 assert(exit && "No exit to replace!"); 00061 exit = BB; 00062 } 00063 00064 template <class Tr> 00065 void RegionBase<Tr>::replaceEntryRecursive(BlockT *NewEntry) { 00066 std::vector<RegionT *> RegionQueue; 00067 BlockT *OldEntry = getEntry(); 00068 00069 RegionQueue.push_back(static_cast<RegionT *>(this)); 00070 while (!RegionQueue.empty()) { 00071 RegionT *R = RegionQueue.back(); 00072 RegionQueue.pop_back(); 00073 00074 R->replaceEntry(NewEntry); 00075 for (typename RegionT::const_iterator RI = R->begin(), RE = R->end(); 00076 RI != RE; ++RI) { 00077 if ((*RI)->getEntry() == OldEntry) 00078 RegionQueue.push_back(RI->get()); 00079 } 00080 } 00081 } 00082 00083 template <class Tr> 00084 void RegionBase<Tr>::replaceExitRecursive(BlockT *NewExit) { 00085 std::vector<RegionT *> RegionQueue; 00086 BlockT *OldExit = getExit(); 00087 00088 RegionQueue.push_back(static_cast<RegionT *>(this)); 00089 while (!RegionQueue.empty()) { 00090 RegionT *R = RegionQueue.back(); 00091 RegionQueue.pop_back(); 00092 00093 R->replaceExit(NewExit); 00094 for (typename RegionT::const_iterator RI = R->begin(), RE = R->end(); 00095 RI != RE; ++RI) { 00096 if ((*RI)->getExit() == OldExit) 00097 RegionQueue.push_back(RI->get()); 00098 } 00099 } 00100 } 00101 00102 template <class Tr> 00103 bool RegionBase<Tr>::contains(const BlockT *B) const { 00104 BlockT *BB = const_cast<BlockT *>(B); 00105 00106 if (!DT->getNode(BB)) 00107 return false; 00108 00109 BlockT *entry = getEntry(), *exit = getExit(); 00110 00111 // Toplevel region. 00112 if (!exit) 00113 return true; 00114 00115 return (DT->dominates(entry, BB) && 00116 !(DT->dominates(exit, BB) && DT->dominates(entry, exit))); 00117 } 00118 00119 template <class Tr> 00120 bool RegionBase<Tr>::contains(const LoopT *L) const { 00121 // BBs that are not part of any loop are element of the Loop 00122 // described by the NULL pointer. This loop is not part of any region, 00123 // except if the region describes the whole function. 00124 if (!L) 00125 return getExit() == nullptr; 00126 00127 if (!contains(L->getHeader())) 00128 return false; 00129 00130 SmallVector<BlockT *, 8> ExitingBlocks; 00131 L->getExitingBlocks(ExitingBlocks); 00132 00133 for (BlockT *BB : ExitingBlocks) { 00134 if (!contains(BB)) 00135 return false; 00136 } 00137 00138 return true; 00139 } 00140 00141 template <class Tr> 00142 typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopT *L) const { 00143 if (!contains(L)) 00144 return nullptr; 00145 00146 while (L && contains(L->getParentLoop())) { 00147 L = L->getParentLoop(); 00148 } 00149 00150 return L; 00151 } 00152 00153 template <class Tr> 00154 typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopInfoT *LI, 00155 BlockT *BB) const { 00156 assert(LI && BB && "LI and BB cannot be null!"); 00157 LoopT *L = LI->getLoopFor(BB); 00158 return outermostLoopInRegion(L); 00159 } 00160 00161 template <class Tr> 00162 typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getEnteringBlock() const { 00163 BlockT *entry = getEntry(); 00164 BlockT *Pred; 00165 BlockT *enteringBlock = nullptr; 00166 00167 for (PredIterTy PI = InvBlockTraits::child_begin(entry), 00168 PE = InvBlockTraits::child_end(entry); 00169 PI != PE; ++PI) { 00170 Pred = *PI; 00171 if (DT->getNode(Pred) && !contains(Pred)) { 00172 if (enteringBlock) 00173 return nullptr; 00174 00175 enteringBlock = Pred; 00176 } 00177 } 00178 00179 return enteringBlock; 00180 } 00181 00182 template <class Tr> 00183 typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getExitingBlock() const { 00184 BlockT *exit = getExit(); 00185 BlockT *Pred; 00186 BlockT *exitingBlock = nullptr; 00187 00188 if (!exit) 00189 return nullptr; 00190 00191 for (PredIterTy PI = InvBlockTraits::child_begin(exit), 00192 PE = InvBlockTraits::child_end(exit); 00193 PI != PE; ++PI) { 00194 Pred = *PI; 00195 if (contains(Pred)) { 00196 if (exitingBlock) 00197 return nullptr; 00198 00199 exitingBlock = Pred; 00200 } 00201 } 00202 00203 return exitingBlock; 00204 } 00205 00206 template <class Tr> 00207 bool RegionBase<Tr>::isSimple() const { 00208 return !isTopLevelRegion() && getEnteringBlock() && getExitingBlock(); 00209 } 00210 00211 template <class Tr> 00212 std::string RegionBase<Tr>::getNameStr() const { 00213 std::string exitName; 00214 std::string entryName; 00215 00216 if (getEntry()->getName().empty()) { 00217 raw_string_ostream OS(entryName); 00218 00219 getEntry()->printAsOperand(OS, false); 00220 } else 00221 entryName = getEntry()->getName(); 00222 00223 if (getExit()) { 00224 if (getExit()->getName().empty()) { 00225 raw_string_ostream OS(exitName); 00226 00227 getExit()->printAsOperand(OS, false); 00228 } else 00229 exitName = getExit()->getName(); 00230 } else 00231 exitName = "<Function Return>"; 00232 00233 return entryName + " => " + exitName; 00234 } 00235 00236 template <class Tr> 00237 void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const { 00238 if (!contains(BB)) 00239 llvm_unreachable("Broken region found!"); 00240 00241 BlockT *entry = getEntry(), *exit = getExit(); 00242 00243 for (SuccIterTy SI = BlockTraits::child_begin(BB), 00244 SE = BlockTraits::child_end(BB); 00245 SI != SE; ++SI) { 00246 if (!contains(*SI) && exit != *SI) 00247 llvm_unreachable("Broken region found!"); 00248 } 00249 00250 if (entry != BB) { 00251 for (PredIterTy SI = InvBlockTraits::child_begin(BB), 00252 SE = InvBlockTraits::child_end(BB); 00253 SI != SE; ++SI) { 00254 if (!contains(*SI)) 00255 llvm_unreachable("Broken region found!"); 00256 } 00257 } 00258 } 00259 00260 template <class Tr> 00261 void RegionBase<Tr>::verifyWalk(BlockT *BB, std::set<BlockT *> *visited) const { 00262 BlockT *exit = getExit(); 00263 00264 visited->insert(BB); 00265 00266 verifyBBInRegion(BB); 00267 00268 for (SuccIterTy SI = BlockTraits::child_begin(BB), 00269 SE = BlockTraits::child_end(BB); 00270 SI != SE; ++SI) { 00271 if (*SI != exit && visited->find(*SI) == visited->end()) 00272 verifyWalk(*SI, visited); 00273 } 00274 } 00275 00276 template <class Tr> 00277 void RegionBase<Tr>::verifyRegion() const { 00278 // Only do verification when user wants to, otherwise this expensive check 00279 // will be invoked by PMDataManager::verifyPreservedAnalysis when 00280 // a regionpass (marked PreservedAll) finish. 00281 if (!RegionInfoBase<Tr>::VerifyRegionInfo) 00282 return; 00283 00284 std::set<BlockT *> visited; 00285 verifyWalk(getEntry(), &visited); 00286 } 00287 00288 template <class Tr> 00289 void RegionBase<Tr>::verifyRegionNest() const { 00290 for (typename RegionT::const_iterator RI = begin(), RE = end(); RI != RE; 00291 ++RI) 00292 (*RI)->verifyRegionNest(); 00293 00294 verifyRegion(); 00295 } 00296 00297 template <class Tr> 00298 typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_begin() { 00299 return GraphTraits<RegionT *>::nodes_begin(static_cast<RegionT *>(this)); 00300 } 00301 00302 template <class Tr> 00303 typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_end() { 00304 return GraphTraits<RegionT *>::nodes_end(static_cast<RegionT *>(this)); 00305 } 00306 00307 template <class Tr> 00308 typename RegionBase<Tr>::const_element_iterator 00309 RegionBase<Tr>::element_begin() const { 00310 return GraphTraits<const RegionT *>::nodes_begin( 00311 static_cast<const RegionT *>(this)); 00312 } 00313 00314 template <class Tr> 00315 typename RegionBase<Tr>::const_element_iterator 00316 RegionBase<Tr>::element_end() const { 00317 return GraphTraits<const RegionT *>::nodes_end( 00318 static_cast<const RegionT *>(this)); 00319 } 00320 00321 template <class Tr> 00322 typename Tr::RegionT *RegionBase<Tr>::getSubRegionNode(BlockT *BB) const { 00323 typedef typename Tr::RegionT RegionT; 00324 RegionT *R = RI->getRegionFor(BB); 00325 00326 if (!R || R == this) 00327 return nullptr; 00328 00329 // If we pass the BB out of this region, that means our code is broken. 00330 assert(contains(R) && "BB not in current region!"); 00331 00332 while (contains(R->getParent()) && R->getParent() != this) 00333 R = R->getParent(); 00334 00335 if (R->getEntry() != BB) 00336 return nullptr; 00337 00338 return R; 00339 } 00340 00341 template <class Tr> 00342 typename Tr::RegionNodeT *RegionBase<Tr>::getBBNode(BlockT *BB) const { 00343 assert(contains(BB) && "Can get BB node out of this region!"); 00344 00345 typename BBNodeMapT::const_iterator at = BBNodeMap.find(BB); 00346 00347 if (at != BBNodeMap.end()) 00348 return at->second; 00349 00350 auto Deconst = const_cast<RegionBase<Tr> *>(this); 00351 RegionNodeT *NewNode = new RegionNodeT(static_cast<RegionT *>(Deconst), BB); 00352 BBNodeMap.insert(std::make_pair(BB, NewNode)); 00353 return NewNode; 00354 } 00355 00356 template <class Tr> 00357 typename Tr::RegionNodeT *RegionBase<Tr>::getNode(BlockT *BB) const { 00358 assert(contains(BB) && "Can get BB node out of this region!"); 00359 if (RegionT *Child = getSubRegionNode(BB)) 00360 return Child->getNode(); 00361 00362 return getBBNode(BB); 00363 } 00364 00365 template <class Tr> 00366 void RegionBase<Tr>::transferChildrenTo(RegionT *To) { 00367 for (iterator I = begin(), E = end(); I != E; ++I) { 00368 (*I)->parent = To; 00369 To->children.push_back(std::move(*I)); 00370 } 00371 children.clear(); 00372 } 00373 00374 template <class Tr> 00375 void RegionBase<Tr>::addSubRegion(RegionT *SubRegion, bool moveChildren) { 00376 assert(!SubRegion->parent && "SubRegion already has a parent!"); 00377 assert(std::find_if(begin(), end(), [&](const std::unique_ptr<RegionT> &R) { 00378 return R.get() == SubRegion; 00379 }) == children.end() && 00380 "Subregion already exists!"); 00381 00382 SubRegion->parent = static_cast<RegionT *>(this); 00383 children.push_back(std::unique_ptr<RegionT>(SubRegion)); 00384 00385 if (!moveChildren) 00386 return; 00387 00388 assert(SubRegion->children.empty() && 00389 "SubRegions that contain children are not supported"); 00390 00391 for (element_iterator I = element_begin(), E = element_end(); I != E; ++I) { 00392 if (!(*I)->isSubRegion()) { 00393 BlockT *BB = (*I)->template getNodeAs<BlockT>(); 00394 00395 if (SubRegion->contains(BB)) 00396 RI->setRegionFor(BB, SubRegion); 00397 } 00398 } 00399 00400 std::vector<std::unique_ptr<RegionT>> Keep; 00401 for (iterator I = begin(), E = end(); I != E; ++I) { 00402 if (SubRegion->contains(I->get()) && I->get() != SubRegion) { 00403 (*I)->parent = SubRegion; 00404 SubRegion->children.push_back(std::move(*I)); 00405 } else 00406 Keep.push_back(std::move(*I)); 00407 } 00408 00409 children.clear(); 00410 children.insert( 00411 children.begin(), 00412 std::move_iterator<typename RegionSet::iterator>(Keep.begin()), 00413 std::move_iterator<typename RegionSet::iterator>(Keep.end())); 00414 } 00415 00416 template <class Tr> 00417 typename Tr::RegionT *RegionBase<Tr>::removeSubRegion(RegionT *Child) { 00418 assert(Child->parent == this && "Child is not a child of this region!"); 00419 Child->parent = nullptr; 00420 typename RegionSet::iterator I = std::find_if( 00421 children.begin(), children.end(), 00422 [&](const std::unique_ptr<RegionT> &R) { return R.get() == Child; }); 00423 assert(I != children.end() && "Region does not exit. Unable to remove."); 00424 children.erase(children.begin() + (I - begin())); 00425 return Child; 00426 } 00427 00428 template <class Tr> 00429 unsigned RegionBase<Tr>::getDepth() const { 00430 unsigned Depth = 0; 00431 00432 for (RegionT *R = getParent(); R != nullptr; R = R->getParent()) 00433 ++Depth; 00434 00435 return Depth; 00436 } 00437 00438 template <class Tr> 00439 typename Tr::RegionT *RegionBase<Tr>::getExpandedRegion() const { 00440 unsigned NumSuccessors = Tr::getNumSuccessors(exit); 00441 00442 if (NumSuccessors == 0) 00443 return nullptr; 00444 00445 for (PredIterTy PI = InvBlockTraits::child_begin(getExit()), 00446 PE = InvBlockTraits::child_end(getExit()); 00447 PI != PE; ++PI) { 00448 if (!DT->dominates(getEntry(), *PI)) 00449 return nullptr; 00450 } 00451 00452 RegionT *R = RI->getRegionFor(exit); 00453 00454 if (R->getEntry() != exit) { 00455 if (Tr::getNumSuccessors(exit) == 1) 00456 return new RegionT(getEntry(), *BlockTraits::child_begin(exit), RI, DT); 00457 return nullptr; 00458 } 00459 00460 while (R->getParent() && R->getParent()->getEntry() == exit) 00461 R = R->getParent(); 00462 00463 if (!DT->dominates(getEntry(), R->getExit())) { 00464 for (PredIterTy PI = InvBlockTraits::child_begin(getExit()), 00465 PE = InvBlockTraits::child_end(getExit()); 00466 PI != PE; ++PI) { 00467 if (!DT->dominates(R->getExit(), *PI)) 00468 return nullptr; 00469 } 00470 } 00471 00472 return new RegionT(getEntry(), R->getExit(), RI, DT); 00473 } 00474 00475 template <class Tr> 00476 void RegionBase<Tr>::print(raw_ostream &OS, bool print_tree, unsigned level, 00477 PrintStyle Style) const { 00478 if (print_tree) 00479 OS.indent(level * 2) << '[' << level << "] " << getNameStr(); 00480 else 00481 OS.indent(level * 2) << getNameStr(); 00482 00483 OS << '\n'; 00484 00485 if (Style != PrintNone) { 00486 OS.indent(level * 2) << "{\n"; 00487 OS.indent(level * 2 + 2); 00488 00489 if (Style == PrintBB) { 00490 for (const auto &BB : blocks()) 00491 OS << BB->getName() << ", "; // TODO: remove the last "," 00492 } else if (Style == PrintRN) { 00493 for (const_element_iterator I = element_begin(), E = element_end(); 00494 I != E; ++I) { 00495 OS << **I << ", "; // TODO: remove the last ", 00496 } 00497 } 00498 00499 OS << '\n'; 00500 } 00501 00502 if (print_tree) { 00503 for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI) 00504 (*RI)->print(OS, print_tree, level + 1, Style); 00505 } 00506 00507 if (Style != PrintNone) 00508 OS.indent(level * 2) << "} \n"; 00509 } 00510 00511 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 00512 template <class Tr> 00513 void RegionBase<Tr>::dump() const { 00514 print(dbgs(), true, getDepth(), RegionInfoBase<Tr>::printStyle); 00515 } 00516 #endif 00517 00518 template <class Tr> 00519 void RegionBase<Tr>::clearNodeCache() { 00520 // Free the cached nodes. 00521 for (typename BBNodeMapT::iterator I = BBNodeMap.begin(), 00522 IE = BBNodeMap.end(); 00523 I != IE; ++I) 00524 delete I->second; 00525 00526 BBNodeMap.clear(); 00527 for (typename RegionT::iterator RI = begin(), RE = end(); RI != RE; ++RI) 00528 (*RI)->clearNodeCache(); 00529 } 00530 00531 //===----------------------------------------------------------------------===// 00532 // RegionInfoBase implementation 00533 // 00534 00535 template <class Tr> 00536 RegionInfoBase<Tr>::RegionInfoBase() 00537 : TopLevelRegion(nullptr) {} 00538 00539 template <class Tr> 00540 RegionInfoBase<Tr>::~RegionInfoBase() { 00541 releaseMemory(); 00542 } 00543 00544 template <class Tr> 00545 bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry, 00546 BlockT *exit) const { 00547 for (PredIterTy PI = InvBlockTraits::child_begin(BB), 00548 PE = InvBlockTraits::child_end(BB); 00549 PI != PE; ++PI) { 00550 BlockT *P = *PI; 00551 if (DT->dominates(entry, P) && !DT->dominates(exit, P)) 00552 return false; 00553 } 00554 00555 return true; 00556 } 00557 00558 template <class Tr> 00559 bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const { 00560 assert(entry && exit && "entry and exit must not be null!"); 00561 typedef typename DomFrontierT::DomSetType DST; 00562 00563 DST *entrySuccs = &DF->find(entry)->second; 00564 00565 // Exit is the header of a loop that contains the entry. In this case, 00566 // the dominance frontier must only contain the exit. 00567 if (!DT->dominates(entry, exit)) { 00568 for (typename DST::iterator SI = entrySuccs->begin(), 00569 SE = entrySuccs->end(); 00570 SI != SE; ++SI) { 00571 if (*SI != exit && *SI != entry) 00572 return false; 00573 } 00574 00575 return true; 00576 } 00577 00578 DST *exitSuccs = &DF->find(exit)->second; 00579 00580 // Do not allow edges leaving the region. 00581 for (typename DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end(); 00582 SI != SE; ++SI) { 00583 if (*SI == exit || *SI == entry) 00584 continue; 00585 if (exitSuccs->find(*SI) == exitSuccs->end()) 00586 return false; 00587 if (!isCommonDomFrontier(*SI, entry, exit)) 00588 return false; 00589 } 00590 00591 // Do not allow edges pointing into the region. 00592 for (typename DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end(); 00593 SI != SE; ++SI) { 00594 if (DT->properlyDominates(entry, *SI) && *SI != exit) 00595 return false; 00596 } 00597 00598 return true; 00599 } 00600 00601 template <class Tr> 00602 void RegionInfoBase<Tr>::insertShortCut(BlockT *entry, BlockT *exit, 00603 BBtoBBMap *ShortCut) const { 00604 assert(entry && exit && "entry and exit must not be null!"); 00605 00606 typename BBtoBBMap::iterator e = ShortCut->find(exit); 00607 00608 if (e == ShortCut->end()) 00609 // No further region at exit available. 00610 (*ShortCut)[entry] = exit; 00611 else { 00612 // We found a region e that starts at exit. Therefore (entry, e->second) 00613 // is also a region, that is larger than (entry, exit). Insert the 00614 // larger one. 00615 BlockT *BB = e->second; 00616 (*ShortCut)[entry] = BB; 00617 } 00618 } 00619 00620 template <class Tr> 00621 typename Tr::DomTreeNodeT * 00622 RegionInfoBase<Tr>::getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const { 00623 typename BBtoBBMap::iterator e = ShortCut->find(N->getBlock()); 00624 00625 if (e == ShortCut->end()) 00626 return N->getIDom(); 00627 00628 return PDT->getNode(e->second)->getIDom(); 00629 } 00630 00631 template <class Tr> 00632 bool RegionInfoBase<Tr>::isTrivialRegion(BlockT *entry, BlockT *exit) const { 00633 assert(entry && exit && "entry and exit must not be null!"); 00634 00635 unsigned num_successors = 00636 BlockTraits::child_end(entry) - BlockTraits::child_begin(entry); 00637 00638 if (num_successors <= 1 && exit == *(BlockTraits::child_begin(entry))) 00639 return true; 00640 00641 return false; 00642 } 00643 00644 template <class Tr> 00645 typename Tr::RegionT *RegionInfoBase<Tr>::createRegion(BlockT *entry, 00646 BlockT *exit) { 00647 assert(entry && exit && "entry and exit must not be null!"); 00648 00649 if (isTrivialRegion(entry, exit)) 00650 return nullptr; 00651 00652 RegionT *region = 00653 new RegionT(entry, exit, static_cast<RegionInfoT *>(this), DT); 00654 BBtoRegion.insert(std::make_pair(entry, region)); 00655 00656 #ifdef XDEBUG 00657 region->verifyRegion(); 00658 #else 00659 DEBUG(region->verifyRegion()); 00660 #endif 00661 00662 updateStatistics(region); 00663 return region; 00664 } 00665 00666 template <class Tr> 00667 void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry, 00668 BBtoBBMap *ShortCut) { 00669 assert(entry); 00670 00671 DomTreeNodeT *N = PDT->getNode(entry); 00672 if (!N) 00673 return; 00674 00675 RegionT *lastRegion = nullptr; 00676 BlockT *lastExit = entry; 00677 00678 // As only a BasicBlock that postdominates entry can finish a region, walk the 00679 // post dominance tree upwards. 00680 while ((N = getNextPostDom(N, ShortCut))) { 00681 BlockT *exit = N->getBlock(); 00682 00683 if (!exit) 00684 break; 00685 00686 if (isRegion(entry, exit)) { 00687 RegionT *newRegion = createRegion(entry, exit); 00688 00689 if (lastRegion) 00690 newRegion->addSubRegion(lastRegion); 00691 00692 lastRegion = newRegion; 00693 lastExit = exit; 00694 } 00695 00696 // This can never be a region, so stop the search. 00697 if (!DT->dominates(entry, exit)) 00698 break; 00699 } 00700 00701 // Tried to create regions from entry to lastExit. Next time take a 00702 // shortcut from entry to lastExit. 00703 if (lastExit != entry) 00704 insertShortCut(entry, lastExit, ShortCut); 00705 } 00706 00707 template <class Tr> 00708 void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) { 00709 typedef typename std::add_pointer<FuncT>::type FuncPtrT; 00710 BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F); 00711 DomTreeNodeT *N = DT->getNode(entry); 00712 00713 // Iterate over the dominance tree in post order to start with the small 00714 // regions from the bottom of the dominance tree. If the small regions are 00715 // detected first, detection of bigger regions is faster, as we can jump 00716 // over the small regions. 00717 for (po_iterator<DomTreeNodeT *> FI = po_begin(N), FE = po_end(N); FI != FE; 00718 ++FI) { 00719 findRegionsWithEntry(FI->getBlock(), ShortCut); 00720 } 00721 } 00722 00723 template <class Tr> 00724 typename Tr::RegionT *RegionInfoBase<Tr>::getTopMostParent(RegionT *region) { 00725 while (region->getParent()) 00726 region = region->getParent(); 00727 00728 return region; 00729 } 00730 00731 template <class Tr> 00732 void RegionInfoBase<Tr>::buildRegionsTree(DomTreeNodeT *N, RegionT *region) { 00733 BlockT *BB = N->getBlock(); 00734 00735 // Passed region exit 00736 while (BB == region->getExit()) 00737 region = region->getParent(); 00738 00739 typename BBtoRegionMap::iterator it = BBtoRegion.find(BB); 00740 00741 // This basic block is a start block of a region. It is already in the 00742 // BBtoRegion relation. Only the child basic blocks have to be updated. 00743 if (it != BBtoRegion.end()) { 00744 RegionT *newRegion = it->second; 00745 region->addSubRegion(getTopMostParent(newRegion)); 00746 region = newRegion; 00747 } else { 00748 BBtoRegion[BB] = region; 00749 } 00750 00751 for (typename DomTreeNodeT::iterator CI = N->begin(), CE = N->end(); CI != CE; 00752 ++CI) { 00753 buildRegionsTree(*CI, region); 00754 } 00755 } 00756 00757 #ifdef XDEBUG 00758 template <class Tr> 00759 bool RegionInfoBase<Tr>::VerifyRegionInfo = true; 00760 #else 00761 template <class Tr> 00762 bool RegionInfoBase<Tr>::VerifyRegionInfo = false; 00763 #endif 00764 00765 template <class Tr> 00766 typename Tr::RegionT::PrintStyle RegionInfoBase<Tr>::printStyle = 00767 RegionBase<Tr>::PrintNone; 00768 00769 template <class Tr> 00770 void RegionInfoBase<Tr>::print(raw_ostream &OS) const { 00771 OS << "Region tree:\n"; 00772 TopLevelRegion->print(OS, true, 0, printStyle); 00773 OS << "End region tree\n"; 00774 } 00775 00776 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 00777 template <class Tr> 00778 void RegionInfoBase<Tr>::dump() const { print(dbgs()); } 00779 #endif 00780 00781 template <class Tr> 00782 void RegionInfoBase<Tr>::releaseMemory() { 00783 BBtoRegion.clear(); 00784 if (TopLevelRegion) 00785 delete TopLevelRegion; 00786 TopLevelRegion = nullptr; 00787 } 00788 00789 template <class Tr> 00790 void RegionInfoBase<Tr>::verifyAnalysis() const { 00791 TopLevelRegion->verifyRegionNest(); 00792 } 00793 00794 // Region pass manager support. 00795 template <class Tr> 00796 typename Tr::RegionT *RegionInfoBase<Tr>::getRegionFor(BlockT *BB) const { 00797 typename BBtoRegionMap::const_iterator I = BBtoRegion.find(BB); 00798 return I != BBtoRegion.end() ? I->second : nullptr; 00799 } 00800 00801 template <class Tr> 00802 void RegionInfoBase<Tr>::setRegionFor(BlockT *BB, RegionT *R) { 00803 BBtoRegion[BB] = R; 00804 } 00805 00806 template <class Tr> 00807 typename Tr::RegionT *RegionInfoBase<Tr>::operator[](BlockT *BB) const { 00808 return getRegionFor(BB); 00809 } 00810 00811 template <class Tr> 00812 typename RegionInfoBase<Tr>::BlockT * 00813 RegionInfoBase<Tr>::getMaxRegionExit(BlockT *BB) const { 00814 BlockT *Exit = nullptr; 00815 00816 while (true) { 00817 // Get largest region that starts at BB. 00818 RegionT *R = getRegionFor(BB); 00819 while (R && R->getParent() && R->getParent()->getEntry() == BB) 00820 R = R->getParent(); 00821 00822 // Get the single exit of BB. 00823 if (R && R->getEntry() == BB) 00824 Exit = R->getExit(); 00825 else if (++BlockTraits::child_begin(BB) == BlockTraits::child_end(BB)) 00826 Exit = *BlockTraits::child_begin(BB); 00827 else // No single exit exists. 00828 return Exit; 00829 00830 // Get largest region that starts at Exit. 00831 RegionT *ExitR = getRegionFor(Exit); 00832 while (ExitR && ExitR->getParent() && 00833 ExitR->getParent()->getEntry() == Exit) 00834 ExitR = ExitR->getParent(); 00835 00836 for (PredIterTy PI = InvBlockTraits::child_begin(Exit), 00837 PE = InvBlockTraits::child_end(Exit); 00838 PI != PE; ++PI) { 00839 if (!R->contains(*PI) && !ExitR->contains(*PI)) 00840 break; 00841 } 00842 00843 // This stops infinite cycles. 00844 if (DT->dominates(Exit, BB)) 00845 break; 00846 00847 BB = Exit; 00848 } 00849 00850 return Exit; 00851 } 00852 00853 template <class Tr> 00854 typename Tr::RegionT *RegionInfoBase<Tr>::getCommonRegion(RegionT *A, 00855 RegionT *B) const { 00856 assert(A && B && "One of the Regions is NULL"); 00857 00858 if (A->contains(B)) 00859 return A; 00860 00861 while (!B->contains(A)) 00862 B = B->getParent(); 00863 00864 return B; 00865 } 00866 00867 template <class Tr> 00868 typename Tr::RegionT * 00869 RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const { 00870 RegionT *ret = Regions.back(); 00871 Regions.pop_back(); 00872 00873 for (RegionT *R : Regions) 00874 ret = getCommonRegion(ret, R); 00875 00876 return ret; 00877 } 00878 00879 template <class Tr> 00880 typename Tr::RegionT * 00881 RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const { 00882 RegionT *ret = getRegionFor(BBs.back()); 00883 BBs.pop_back(); 00884 00885 for (BlockT *BB : BBs) 00886 ret = getCommonRegion(ret, getRegionFor(BB)); 00887 00888 return ret; 00889 } 00890 00891 template <class Tr> 00892 void RegionInfoBase<Tr>::splitBlock(BlockT *NewBB, BlockT *OldBB) { 00893 RegionT *R = getRegionFor(OldBB); 00894 00895 setRegionFor(NewBB, R); 00896 00897 while (R->getEntry() == OldBB && !R->isTopLevelRegion()) { 00898 R->replaceEntry(NewBB); 00899 R = R->getParent(); 00900 } 00901 00902 setRegionFor(OldBB, R); 00903 } 00904 00905 template <class Tr> 00906 void RegionInfoBase<Tr>::calculate(FuncT &F) { 00907 typedef typename std::add_pointer<FuncT>::type FuncPtrT; 00908 00909 // ShortCut a function where for every BB the exit of the largest region 00910 // starting with BB is stored. These regions can be threated as single BBS. 00911 // This improves performance on linear CFGs. 00912 BBtoBBMap ShortCut; 00913 00914 scanForRegions(F, &ShortCut); 00915 BlockT *BB = GraphTraits<FuncPtrT>::getEntryNode(&F); 00916 buildRegionsTree(DT->getNode(BB), TopLevelRegion); 00917 } 00918 00919 #undef DEBUG_TYPE 00920 00921 } // end namespace llvm 00922 00923 #endif