File indexing completed on 2026-05-10 08:43:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef LLVM_ANALYSIS_REGIONINFOIMPL_H
0012 #define LLVM_ANALYSIS_REGIONINFOIMPL_H
0013
0014 #include "llvm/ADT/GraphTraits.h"
0015 #include "llvm/ADT/PostOrderIterator.h"
0016 #include "llvm/ADT/STLExtras.h"
0017 #include "llvm/ADT/SmallVector.h"
0018 #include "llvm/Analysis/LoopInfo.h"
0019 #include "llvm/Analysis/PostDominators.h"
0020 #include "llvm/Analysis/RegionInfo.h"
0021 #include "llvm/Analysis/RegionIterator.h"
0022 #include "llvm/Config/llvm-config.h"
0023 #include "llvm/Support/Debug.h"
0024 #include "llvm/Support/ErrorHandling.h"
0025 #include <algorithm>
0026 #include <cassert>
0027 #include <iterator>
0028 #include <memory>
0029 #include <set>
0030 #include <string>
0031 #include <type_traits>
0032 #include <vector>
0033
0034 #define DEBUG_TYPE "region"
0035
0036 namespace llvm {
0037 class raw_ostream;
0038
0039
0040
0041 template <class Tr>
0042 RegionBase<Tr>::RegionBase(BlockT *Entry, BlockT *Exit,
0043 typename Tr::RegionInfoT *RInfo, DomTreeT *dt,
0044 RegionT *Parent)
0045 : RegionNodeBase<Tr>(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
0046
0047 template <class Tr>
0048 RegionBase<Tr>::~RegionBase() {
0049
0050
0051 BBNodeMap.clear();
0052 }
0053
0054 template <class Tr>
0055 void RegionBase<Tr>::replaceEntry(BlockT *BB) {
0056 this->entry.setPointer(BB);
0057 }
0058
0059 template <class Tr>
0060 void RegionBase<Tr>::replaceExit(BlockT *BB) {
0061 assert(exit && "No exit to replace!");
0062 exit = BB;
0063 }
0064
0065 template <class Tr>
0066 void RegionBase<Tr>::replaceEntryRecursive(BlockT *NewEntry) {
0067 std::vector<RegionT *> RegionQueue;
0068 BlockT *OldEntry = getEntry();
0069
0070 RegionQueue.push_back(static_cast<RegionT *>(this));
0071 while (!RegionQueue.empty()) {
0072 RegionT *R = RegionQueue.back();
0073 RegionQueue.pop_back();
0074
0075 R->replaceEntry(NewEntry);
0076 for (std::unique_ptr<RegionT> &Child : *R) {
0077 if (Child->getEntry() == OldEntry)
0078 RegionQueue.push_back(Child.get());
0079 }
0080 }
0081 }
0082
0083 template <class Tr>
0084 void RegionBase<Tr>::replaceExitRecursive(BlockT *NewExit) {
0085 std::vector<RegionT *> RegionQueue;
0086 BlockT *OldExit = getExit();
0087
0088 RegionQueue.push_back(static_cast<RegionT *>(this));
0089 while (!RegionQueue.empty()) {
0090 RegionT *R = RegionQueue.back();
0091 RegionQueue.pop_back();
0092
0093 R->replaceExit(NewExit);
0094 for (std::unique_ptr<RegionT> &Child : *R) {
0095 if (Child->getExit() == OldExit)
0096 RegionQueue.push_back(Child.get());
0097 }
0098 }
0099 }
0100
0101 template <class Tr>
0102 bool RegionBase<Tr>::contains(const BlockT *B) const {
0103 BlockT *BB = const_cast<BlockT *>(B);
0104
0105 if (!DT->getNode(BB))
0106 return false;
0107
0108 BlockT *entry = getEntry(), *exit = getExit();
0109
0110
0111 if (!exit)
0112 return true;
0113
0114 return (DT->dominates(entry, BB) &&
0115 !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
0116 }
0117
0118 template <class Tr>
0119 bool RegionBase<Tr>::contains(const LoopT *L) const {
0120
0121
0122
0123 if (!L)
0124 return getExit() == nullptr;
0125
0126 if (!contains(L->getHeader()))
0127 return false;
0128
0129 SmallVector<BlockT *, 8> ExitingBlocks;
0130 L->getExitingBlocks(ExitingBlocks);
0131
0132 for (BlockT *BB : ExitingBlocks) {
0133 if (!contains(BB))
0134 return false;
0135 }
0136
0137 return true;
0138 }
0139
0140 template <class Tr>
0141 typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopT *L) const {
0142 if (!contains(L))
0143 return nullptr;
0144
0145 while (L && contains(L->getParentLoop())) {
0146 L = L->getParentLoop();
0147 }
0148
0149 return L;
0150 }
0151
0152 template <class Tr>
0153 typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopInfoT *LI,
0154 BlockT *BB) const {
0155 assert(LI && BB && "LI and BB cannot be null!");
0156 LoopT *L = LI->getLoopFor(BB);
0157 return outermostLoopInRegion(L);
0158 }
0159
0160 template <class Tr>
0161 typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getEnteringBlock() const {
0162 auto isEnteringBlock = [&](BlockT *Pred, bool AllowRepeats) -> BlockT * {
0163 assert(!AllowRepeats && "Unexpected parameter value.");
0164 return DT->getNode(Pred) && !contains(Pred) ? Pred : nullptr;
0165 };
0166 return find_singleton<BlockT>(llvm::inverse_children<BlockT *>(getEntry()),
0167 isEnteringBlock);
0168 }
0169
0170 template <class Tr>
0171 bool RegionBase<Tr>::getExitingBlocks(
0172 SmallVectorImpl<BlockT *> &Exitings) const {
0173 bool CoverAll = true;
0174
0175 if (!exit)
0176 return CoverAll;
0177
0178 for (BlockT *Pred : llvm::inverse_children<BlockT *>(exit)) {
0179 if (contains(Pred)) {
0180 Exitings.push_back(Pred);
0181 continue;
0182 }
0183
0184 CoverAll = false;
0185 }
0186
0187 return CoverAll;
0188 }
0189
0190 template <class Tr>
0191 typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getExitingBlock() const {
0192 BlockT *exit = getExit();
0193 if (!exit)
0194 return nullptr;
0195
0196 auto isContained = [&](BlockT *Pred, bool AllowRepeats) -> BlockT * {
0197 assert(!AllowRepeats && "Unexpected parameter value.");
0198 return contains(Pred) ? Pred : nullptr;
0199 };
0200 return find_singleton<BlockT>(llvm::inverse_children<BlockT *>(exit),
0201 isContained);
0202 }
0203
0204 template <class Tr>
0205 bool RegionBase<Tr>::isSimple() const {
0206 return !isTopLevelRegion() && getEnteringBlock() && getExitingBlock();
0207 }
0208
0209 template <class Tr>
0210 std::string RegionBase<Tr>::getNameStr() const {
0211 std::string exitName;
0212 std::string entryName;
0213
0214 if (getEntry()->getName().empty()) {
0215 raw_string_ostream OS(entryName);
0216
0217 getEntry()->printAsOperand(OS, false);
0218 } else
0219 entryName = std::string(getEntry()->getName());
0220
0221 if (getExit()) {
0222 if (getExit()->getName().empty()) {
0223 raw_string_ostream OS(exitName);
0224
0225 getExit()->printAsOperand(OS, false);
0226 } else
0227 exitName = std::string(getExit()->getName());
0228 } else
0229 exitName = "<Function Return>";
0230
0231 return entryName + " => " + exitName;
0232 }
0233
0234 template <class Tr>
0235 void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const {
0236 if (!contains(BB))
0237 report_fatal_error("Broken region found: enumerated BB not in region!");
0238
0239 BlockT *entry = getEntry(), *exit = getExit();
0240
0241 for (BlockT *Succ : llvm::children<BlockT *>(BB)) {
0242 if (!contains(Succ) && exit != Succ)
0243 report_fatal_error("Broken region found: edges leaving the region must go "
0244 "to the exit node!");
0245 }
0246
0247 if (entry != BB) {
0248 for (BlockT *Pred : llvm::inverse_children<BlockT *>(BB)) {
0249
0250
0251 if (!contains(Pred) && DT->isReachableFromEntry(Pred))
0252 report_fatal_error("Broken region found: edges entering the region must "
0253 "go to the entry node!");
0254 }
0255 }
0256 }
0257
0258 template <class Tr>
0259 void RegionBase<Tr>::verifyWalk(BlockT *BB, std::set<BlockT *> *visited) const {
0260 BlockT *exit = getExit();
0261
0262 visited->insert(BB);
0263
0264 verifyBBInRegion(BB);
0265
0266 for (BlockT *Succ : llvm::children<BlockT *>(BB)) {
0267 if (Succ != exit && visited->find(Succ) == visited->end())
0268 verifyWalk(Succ, visited);
0269 }
0270 }
0271
0272 template <class Tr>
0273 void RegionBase<Tr>::verifyRegion() const {
0274
0275
0276
0277 if (!RegionInfoBase<Tr>::VerifyRegionInfo)
0278 return;
0279
0280 std::set<BlockT *> visited;
0281 verifyWalk(getEntry(), &visited);
0282 }
0283
0284 template <class Tr>
0285 void RegionBase<Tr>::verifyRegionNest() const {
0286 for (const std::unique_ptr<RegionT> &R : *this)
0287 R->verifyRegionNest();
0288
0289 verifyRegion();
0290 }
0291
0292 template <class Tr>
0293 typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_begin() {
0294 return GraphTraits<RegionT *>::nodes_begin(static_cast<RegionT *>(this));
0295 }
0296
0297 template <class Tr>
0298 typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_end() {
0299 return GraphTraits<RegionT *>::nodes_end(static_cast<RegionT *>(this));
0300 }
0301
0302 template <class Tr>
0303 typename RegionBase<Tr>::const_element_iterator
0304 RegionBase<Tr>::element_begin() const {
0305 return GraphTraits<const RegionT *>::nodes_begin(
0306 static_cast<const RegionT *>(this));
0307 }
0308
0309 template <class Tr>
0310 typename RegionBase<Tr>::const_element_iterator
0311 RegionBase<Tr>::element_end() const {
0312 return GraphTraits<const RegionT *>::nodes_end(
0313 static_cast<const RegionT *>(this));
0314 }
0315
0316 template <class Tr>
0317 typename Tr::RegionT *RegionBase<Tr>::getSubRegionNode(BlockT *BB) const {
0318 using RegionT = typename Tr::RegionT;
0319
0320 RegionT *R = RI->getRegionFor(BB);
0321
0322 if (!R || R == this)
0323 return nullptr;
0324
0325
0326 assert(contains(R) && "BB not in current region!");
0327
0328 while (contains(R->getParent()) && R->getParent() != this)
0329 R = R->getParent();
0330
0331 if (R->getEntry() != BB)
0332 return nullptr;
0333
0334 return R;
0335 }
0336
0337 template <class Tr>
0338 typename Tr::RegionNodeT *RegionBase<Tr>::getBBNode(BlockT *BB) const {
0339 assert(contains(BB) && "Can get BB node out of this region!");
0340
0341 auto [at, Inserted] = BBNodeMap.try_emplace(BB);
0342 if (Inserted) {
0343 auto Deconst = const_cast<RegionBase<Tr> *>(this);
0344 at->second =
0345 std::make_unique<RegionNodeT>(static_cast<RegionT *>(Deconst), BB);
0346 }
0347 return at->second.get();
0348 }
0349
0350 template <class Tr>
0351 typename Tr::RegionNodeT *RegionBase<Tr>::getNode(BlockT *BB) const {
0352 assert(contains(BB) && "Can get BB node out of this region!");
0353 if (RegionT *Child = getSubRegionNode(BB))
0354 return Child->getNode();
0355
0356 return getBBNode(BB);
0357 }
0358
0359 template <class Tr>
0360 void RegionBase<Tr>::transferChildrenTo(RegionT *To) {
0361 for (std::unique_ptr<RegionT> &R : *this) {
0362 R->parent = To;
0363 To->children.push_back(std::move(R));
0364 }
0365 children.clear();
0366 }
0367
0368 template <class Tr>
0369 void RegionBase<Tr>::addSubRegion(RegionT *SubRegion, bool moveChildren) {
0370 assert(!SubRegion->parent && "SubRegion already has a parent!");
0371 assert(llvm::none_of(*this,
0372 [&](const std::unique_ptr<RegionT> &R) {
0373 return R.get() == SubRegion;
0374 }) &&
0375 "Subregion already exists!");
0376
0377 SubRegion->parent = static_cast<RegionT *>(this);
0378 children.push_back(std::unique_ptr<RegionT>(SubRegion));
0379
0380 if (!moveChildren)
0381 return;
0382
0383 assert(SubRegion->children.empty() &&
0384 "SubRegions that contain children are not supported");
0385
0386 for (RegionNodeT *Element : elements()) {
0387 if (!Element->isSubRegion()) {
0388 BlockT *BB = Element->template getNodeAs<BlockT>();
0389
0390 if (SubRegion->contains(BB))
0391 RI->setRegionFor(BB, SubRegion);
0392 }
0393 }
0394
0395 std::vector<std::unique_ptr<RegionT>> Keep;
0396 for (std::unique_ptr<RegionT> &R : *this) {
0397 if (SubRegion->contains(R.get()) && R.get() != SubRegion) {
0398 R->parent = SubRegion;
0399 SubRegion->children.push_back(std::move(R));
0400 } else
0401 Keep.push_back(std::move(R));
0402 }
0403
0404 children.clear();
0405 children.insert(
0406 children.begin(),
0407 std::move_iterator<typename RegionSet::iterator>(Keep.begin()),
0408 std::move_iterator<typename RegionSet::iterator>(Keep.end()));
0409 }
0410
0411 template <class Tr>
0412 typename Tr::RegionT *RegionBase<Tr>::removeSubRegion(RegionT *Child) {
0413 assert(Child->parent == this && "Child is not a child of this region!");
0414 Child->parent = nullptr;
0415 typename RegionSet::iterator I =
0416 llvm::find_if(children, [&](const std::unique_ptr<RegionT> &R) {
0417 return R.get() == Child;
0418 });
0419 assert(I != children.end() && "Region does not exit. Unable to remove.");
0420 children.erase(children.begin() + (I - begin()));
0421 return Child;
0422 }
0423
0424 template <class Tr>
0425 unsigned RegionBase<Tr>::getDepth() const {
0426 unsigned Depth = 0;
0427
0428 for (RegionT *R = getParent(); R != nullptr; R = R->getParent())
0429 ++Depth;
0430
0431 return Depth;
0432 }
0433
0434 template <class Tr>
0435 typename Tr::RegionT *RegionBase<Tr>::getExpandedRegion() const {
0436 unsigned NumSuccessors = Tr::getNumSuccessors(exit);
0437
0438 if (NumSuccessors == 0)
0439 return nullptr;
0440
0441 RegionT *R = RI->getRegionFor(exit);
0442
0443 if (R->getEntry() != exit) {
0444 for (BlockT *Pred : llvm::inverse_children<BlockT *>(getExit()))
0445 if (!contains(Pred))
0446 return nullptr;
0447 if (Tr::getNumSuccessors(exit) == 1)
0448 return new RegionT(getEntry(), *BlockTraits::child_begin(exit), RI, DT);
0449 return nullptr;
0450 }
0451
0452 while (R->getParent() && R->getParent()->getEntry() == exit)
0453 R = R->getParent();
0454
0455 for (BlockT *Pred : llvm::inverse_children<BlockT *>(getExit())) {
0456 if (!(contains(Pred) || R->contains(Pred)))
0457 return nullptr;
0458 }
0459
0460 return new RegionT(getEntry(), R->getExit(), RI, DT);
0461 }
0462
0463 template <class Tr>
0464 void RegionBase<Tr>::print(raw_ostream &OS, bool print_tree, unsigned level,
0465 PrintStyle Style) const {
0466 if (print_tree)
0467 OS.indent(level * 2) << '[' << level << "] " << getNameStr();
0468 else
0469 OS.indent(level * 2) << getNameStr();
0470
0471 OS << '\n';
0472
0473 if (Style != PrintNone) {
0474 OS.indent(level * 2) << "{\n";
0475 OS.indent(level * 2 + 2);
0476
0477 if (Style == PrintBB) {
0478 for (const auto *BB : blocks())
0479 OS << BB->getName() << ", ";
0480 } else if (Style == PrintRN) {
0481 for (const RegionNodeT *Element : elements()) {
0482 OS << *Element << ", ";
0483 }
0484 }
0485
0486 OS << '\n';
0487 }
0488
0489 if (print_tree) {
0490 for (const std::unique_ptr<RegionT> &R : *this)
0491 R->print(OS, print_tree, level + 1, Style);
0492 }
0493
0494 if (Style != PrintNone)
0495 OS.indent(level * 2) << "} \n";
0496 }
0497
0498 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0499 template <class Tr>
0500 void RegionBase<Tr>::dump() const {
0501 print(dbgs(), true, getDepth(), RegionInfoBase<Tr>::printStyle);
0502 }
0503 #endif
0504
0505 template <class Tr>
0506 void RegionBase<Tr>::clearNodeCache() {
0507 BBNodeMap.clear();
0508 for (std::unique_ptr<RegionT> &R : *this)
0509 R->clearNodeCache();
0510 }
0511
0512
0513
0514
0515
0516 template <class Tr>
0517 RegionInfoBase<Tr>::RegionInfoBase() = default;
0518
0519 template <class Tr>
0520 RegionInfoBase<Tr>::~RegionInfoBase() {
0521 releaseMemory();
0522 }
0523
0524 template <class Tr>
0525 void RegionInfoBase<Tr>::verifyBBMap(const RegionT *R) const {
0526 assert(R && "Re must be non-null");
0527 for (const typename Tr::RegionNodeT *Element : R->elements()) {
0528 if (Element->isSubRegion()) {
0529 const RegionT *SR = Element->template getNodeAs<RegionT>();
0530 verifyBBMap(SR);
0531 } else {
0532 BlockT *BB = Element->template getNodeAs<BlockT>();
0533 if (getRegionFor(BB) != R)
0534 report_fatal_error("BB map does not match region nesting");
0535 }
0536 }
0537 }
0538
0539 template <class Tr>
0540 bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry,
0541 BlockT *exit) const {
0542 for (BlockT *P : llvm::inverse_children<BlockT *>(BB)) {
0543 if (DT->dominates(entry, P) && !DT->dominates(exit, P))
0544 return false;
0545 }
0546
0547 return true;
0548 }
0549
0550 template <class Tr>
0551 bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const {
0552 assert(entry && exit && "entry and exit must not be null!");
0553
0554 using DST = typename DomFrontierT::DomSetType;
0555
0556 DST *entrySuccs = &DF->find(entry)->second;
0557
0558
0559
0560 if (!DT->dominates(entry, exit)) {
0561 for (BlockT *successor : *entrySuccs) {
0562 if (successor != exit && successor != entry)
0563 return false;
0564 }
0565
0566 return true;
0567 }
0568
0569 DST *exitSuccs = &DF->find(exit)->second;
0570
0571
0572 for (BlockT *Succ : *entrySuccs) {
0573 if (Succ == exit || Succ == entry)
0574 continue;
0575 if (!exitSuccs->contains(Succ))
0576 return false;
0577 if (!isCommonDomFrontier(Succ, entry, exit))
0578 return false;
0579 }
0580
0581
0582 for (BlockT *Succ : *exitSuccs) {
0583 if (DT->properlyDominates(entry, Succ) && Succ != exit)
0584 return false;
0585 }
0586
0587 return true;
0588 }
0589
0590 template <class Tr>
0591 void RegionInfoBase<Tr>::insertShortCut(BlockT *entry, BlockT *exit,
0592 BBtoBBMap *ShortCut) const {
0593 assert(entry && exit && "entry and exit must not be null!");
0594
0595 typename BBtoBBMap::iterator e = ShortCut->find(exit);
0596
0597 if (e == ShortCut->end())
0598
0599 (*ShortCut)[entry] = exit;
0600 else {
0601
0602
0603
0604 BlockT *BB = e->second;
0605 (*ShortCut)[entry] = BB;
0606 }
0607 }
0608
0609 template <class Tr>
0610 typename Tr::DomTreeNodeT *
0611 RegionInfoBase<Tr>::getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const {
0612 typename BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
0613
0614 if (e == ShortCut->end())
0615 return N->getIDom();
0616
0617 return PDT->getNode(e->second)->getIDom();
0618 }
0619
0620 template <class Tr>
0621 bool RegionInfoBase<Tr>::isTrivialRegion(BlockT *entry, BlockT *exit) const {
0622 assert(entry && exit && "entry and exit must not be null!");
0623
0624 unsigned num_successors =
0625 BlockTraits::child_end(entry) - BlockTraits::child_begin(entry);
0626
0627 if (num_successors <= 1 && exit == *(BlockTraits::child_begin(entry)))
0628 return true;
0629
0630 return false;
0631 }
0632
0633 template <class Tr>
0634 typename Tr::RegionT *RegionInfoBase<Tr>::createRegion(BlockT *entry,
0635 BlockT *exit) {
0636 assert(entry && exit && "entry and exit must not be null!");
0637
0638 if (isTrivialRegion(entry, exit))
0639 return nullptr;
0640
0641 RegionT *region =
0642 new RegionT(entry, exit, static_cast<RegionInfoT *>(this), DT);
0643 BBtoRegion.insert({entry, region});
0644
0645 region->verifyRegion();
0646
0647 updateStatistics(region);
0648 return region;
0649 }
0650
0651 template <class Tr>
0652 void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry,
0653 BBtoBBMap *ShortCut) {
0654 assert(entry);
0655
0656 DomTreeNodeT *N = PDT->getNode(entry);
0657 if (!N)
0658 return;
0659
0660 RegionT *lastRegion = nullptr;
0661 BlockT *lastExit = entry;
0662
0663
0664
0665 while ((N = getNextPostDom(N, ShortCut))) {
0666 BlockT *exit = N->getBlock();
0667
0668 if (!exit)
0669 break;
0670
0671 if (isRegion(entry, exit)) {
0672 RegionT *newRegion = createRegion(entry, exit);
0673
0674 if (lastRegion)
0675 newRegion->addSubRegion(lastRegion);
0676
0677 lastRegion = newRegion;
0678 lastExit = exit;
0679 }
0680
0681
0682 if (!DT->dominates(entry, exit))
0683 break;
0684 }
0685
0686
0687
0688 if (lastExit != entry)
0689 insertShortCut(entry, lastExit, ShortCut);
0690 }
0691
0692 template <class Tr>
0693 void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) {
0694 using FuncPtrT = std::add_pointer_t<FuncT>;
0695
0696 BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F);
0697 DomTreeNodeT *N = DT->getNode(entry);
0698
0699
0700
0701
0702
0703 for (auto DomNode : post_order(N))
0704 findRegionsWithEntry(DomNode->getBlock(), ShortCut);
0705 }
0706
0707 template <class Tr>
0708 typename Tr::RegionT *RegionInfoBase<Tr>::getTopMostParent(RegionT *region) {
0709 while (region->getParent())
0710 region = region->getParent();
0711
0712 return region;
0713 }
0714
0715 template <class Tr>
0716 void RegionInfoBase<Tr>::buildRegionsTree(DomTreeNodeT *N, RegionT *region) {
0717 BlockT *BB = N->getBlock();
0718
0719
0720 while (BB == region->getExit())
0721 region = region->getParent();
0722
0723 typename BBtoRegionMap::iterator it = BBtoRegion.find(BB);
0724
0725
0726
0727 if (it != BBtoRegion.end()) {
0728 RegionT *newRegion = it->second;
0729 region->addSubRegion(getTopMostParent(newRegion));
0730 region = newRegion;
0731 } else {
0732 BBtoRegion[BB] = region;
0733 }
0734
0735 for (DomTreeNodeBase<BlockT> *C : *N) {
0736 buildRegionsTree(C, region);
0737 }
0738 }
0739
0740 #ifdef EXPENSIVE_CHECKS
0741 template <class Tr>
0742 bool RegionInfoBase<Tr>::VerifyRegionInfo = true;
0743 #else
0744 template <class Tr>
0745 bool RegionInfoBase<Tr>::VerifyRegionInfo = false;
0746 #endif
0747
0748 template <class Tr>
0749 typename Tr::RegionT::PrintStyle RegionInfoBase<Tr>::printStyle =
0750 RegionBase<Tr>::PrintNone;
0751
0752 template <class Tr>
0753 void RegionInfoBase<Tr>::print(raw_ostream &OS) const {
0754 OS << "Region tree:\n";
0755 TopLevelRegion->print(OS, true, 0, printStyle);
0756 OS << "End region tree\n";
0757 }
0758
0759 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0760 template <class Tr>
0761 void RegionInfoBase<Tr>::dump() const { print(dbgs()); }
0762 #endif
0763
0764 template <class Tr> void RegionInfoBase<Tr>::releaseMemory() {
0765 BBtoRegion.clear();
0766 if (TopLevelRegion) {
0767 delete TopLevelRegion;
0768 TopLevelRegion = nullptr;
0769 }
0770 }
0771
0772 template <class Tr>
0773 void RegionInfoBase<Tr>::verifyAnalysis() const {
0774
0775
0776 if (!RegionInfoBase<Tr>::VerifyRegionInfo)
0777 return;
0778
0779 TopLevelRegion->verifyRegionNest();
0780
0781 verifyBBMap(TopLevelRegion);
0782 }
0783
0784
0785 template <class Tr>
0786 typename Tr::RegionT *RegionInfoBase<Tr>::getRegionFor(BlockT *BB) const {
0787 return BBtoRegion.lookup(BB);
0788 }
0789
0790 template <class Tr>
0791 void RegionInfoBase<Tr>::setRegionFor(BlockT *BB, RegionT *R) {
0792 BBtoRegion[BB] = R;
0793 }
0794
0795 template <class Tr>
0796 typename Tr::RegionT *RegionInfoBase<Tr>::operator[](BlockT *BB) const {
0797 return getRegionFor(BB);
0798 }
0799
0800 template <class Tr>
0801 typename RegionInfoBase<Tr>::BlockT *
0802 RegionInfoBase<Tr>::getMaxRegionExit(BlockT *BB) const {
0803 BlockT *Exit = nullptr;
0804
0805 while (true) {
0806
0807 RegionT *R = getRegionFor(BB);
0808 while (R && R->getParent() && R->getParent()->getEntry() == BB)
0809 R = R->getParent();
0810
0811
0812 if (R && R->getEntry() == BB)
0813 Exit = R->getExit();
0814 else if (std::next(BlockTraits::child_begin(BB)) ==
0815 BlockTraits::child_end(BB))
0816 Exit = *BlockTraits::child_begin(BB);
0817 else
0818 return Exit;
0819
0820
0821 RegionT *ExitR = getRegionFor(Exit);
0822 while (ExitR && ExitR->getParent() &&
0823 ExitR->getParent()->getEntry() == Exit)
0824 ExitR = ExitR->getParent();
0825
0826 for (BlockT *Pred : llvm::inverse_children<BlockT *>(Exit)) {
0827 if (!R->contains(Pred) && !ExitR->contains(Pred))
0828 break;
0829 }
0830
0831
0832 if (DT->dominates(Exit, BB))
0833 break;
0834
0835 BB = Exit;
0836 }
0837
0838 return Exit;
0839 }
0840
0841 template <class Tr>
0842 typename Tr::RegionT *RegionInfoBase<Tr>::getCommonRegion(RegionT *A,
0843 RegionT *B) const {
0844 assert(A && B && "One of the Regions is NULL");
0845
0846 if (A->contains(B))
0847 return A;
0848
0849 while (!B->contains(A))
0850 B = B->getParent();
0851
0852 return B;
0853 }
0854
0855 template <class Tr>
0856 typename Tr::RegionT *
0857 RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const {
0858 RegionT *ret = Regions.pop_back_val();
0859
0860 for (RegionT *R : Regions)
0861 ret = getCommonRegion(ret, R);
0862
0863 return ret;
0864 }
0865
0866 template <class Tr>
0867 typename Tr::RegionT *
0868 RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const {
0869 RegionT *ret = getRegionFor(BBs.back());
0870 BBs.pop_back();
0871
0872 for (BlockT *BB : BBs)
0873 ret = getCommonRegion(ret, getRegionFor(BB));
0874
0875 return ret;
0876 }
0877
0878 template <class Tr>
0879 void RegionInfoBase<Tr>::calculate(FuncT &F) {
0880 using FuncPtrT = std::add_pointer_t<FuncT>;
0881
0882
0883
0884
0885 BBtoBBMap ShortCut;
0886
0887 scanForRegions(F, &ShortCut);
0888 BlockT *BB = GraphTraits<FuncPtrT>::getEntryNode(&F);
0889 buildRegionsTree(DT->getNode(BB), TopLevelRegion);
0890 }
0891
0892 }
0893
0894 #undef DEBUG_TYPE
0895
0896 #endif