diff options
author | Tobias Grosser <grosser@fim.uni-passau.de> | 2010-07-27 08:39:43 +0000 |
---|---|---|
committer | Tobias Grosser <grosser@fim.uni-passau.de> | 2010-07-27 08:39:43 +0000 |
commit | fc763867d56787fd618ae15d37471c227260506d (patch) | |
tree | 2ed3b243beca05c3c2ecf669beff391c147ed911 /llvm/lib/Analysis | |
parent | fd5c8329cf7eef9cc0eb1fad253a5f2d53d12ee9 (diff) | |
download | bcm5719-llvm-fc763867d56787fd618ae15d37471c227260506d.tar.gz bcm5719-llvm-fc763867d56787fd618ae15d37471c227260506d.zip |
RegionInfo: Add getMaxRegionExit()
getMaxRegionExit returns the exit of the maximal refined region starting
at a specific basic block.
llvm-svn: 109496
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/RegionInfo.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/RegionInfo.cpp b/llvm/lib/Analysis/RegionInfo.cpp index 0ea92cb012b..ac660e72f07 100644 --- a/llvm/lib/Analysis/RegionInfo.cpp +++ b/llvm/lib/Analysis/RegionInfo.cpp @@ -651,6 +651,45 @@ Region *RegionInfo::operator[](BasicBlock *BB) const { return getRegionFor(BB); } + +BasicBlock *RegionInfo::getMaxRegionExit(BasicBlock *BB) const { + BasicBlock *Exit = NULL; + + while (true) { + // Get largest region that starts at BB. + Region *R = getRegionFor(BB); + while (R && R->getParent() && R->getParent()->getEntry() == BB) + R = R->getParent(); + + // Get the single exit of BB. + if (R && R->getEntry() == BB) + Exit = R->getExit(); + else if (++succ_begin(BB) == succ_end(BB)) + Exit = *succ_begin(BB); + else // No single exit exists. + return Exit; + + // Get largest region that starts at Exit. + Region *ExitR = getRegionFor(Exit); + while (ExitR && ExitR->getParent() + && ExitR->getParent()->getEntry() == Exit) + ExitR = ExitR->getParent(); + + for (pred_iterator PI = pred_begin(Exit), PE = pred_end(Exit); PI != PE; + ++PI) + if (!R->contains(*PI) && !ExitR->contains(*PI)) + break; + + // This stops infinite cycles. + if (DT->dominates(Exit, BB)) + break; + + BB = Exit; + } + + return Exit; +} + Region* RegionInfo::getCommonRegion(Region *A, Region *B) const { assert (A && B && "One of the Regions is NULL"); |