aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Grosser <grosser@fim.uni-passau.de>2010-07-27 04:17:13 +0000
committerTobias Grosser <grosser@fim.uni-passau.de>2010-07-27 04:17:13 +0000
commit082d587d35a41ee06985d7867b72fb2632962281 (patch)
treeaa057955c7ba37f35f9b67830660639fbfe20911
parent81c7b19f0494b3995a564778f666025495033d86 (diff)
downloadexternal_llvm-082d587d35a41ee06985d7867b72fb2632962281.zip
external_llvm-082d587d35a41ee06985d7867b72fb2632962281.tar.gz
external_llvm-082d587d35a41ee06985d7867b72fb2632962281.tar.bz2
Add function to query RegionInfo about loops.
* contains(Loop), * getOutermostLoop() * Improve getNameStr() to return a sensible name, if basic blocks are not named. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109490 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Analysis/RegionInfo.h43
-rw-r--r--lib/Analysis/RegionInfo.cpp65
2 files changed, 98 insertions, 10 deletions
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index c4ac1eb..a54509f 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -37,6 +37,8 @@ namespace llvm {
class Region;
class RegionInfo;
class raw_ostream;
+class Loop;
+class LoopInfo;
/// @brief Marker class to iterate over the elements of a Region in flat mode.
///
@@ -287,16 +289,7 @@ public:
/// @brief Returns the name of the Region.
/// @return The Name of the Region.
- std::string getNameStr() const {
- std::string exitName;
-
- if (getExit())
- exitName = getExit()->getNameStr();
- else
- exitName = "<Function Return>";
-
- return getEntry()->getNameStr() + " => " + exitName;
- }
+ std::string getNameStr() const;
/// @brief Return the RegionInfo object, that belongs to this Region.
RegionInfo *getRegionInfo() const {
@@ -340,6 +333,36 @@ public:
return contains(Inst->getParent());
}
+ /// @brief Check if the region contains a loop.
+ ///
+ /// @param L The loop that might be contained in this region.
+ /// @return True if the loop is contained in the region otherwise false.
+ /// In case a NULL pointer is passed to this function the result
+ /// is false, except for the region that describes the whole function.
+ /// In that case true is returned.
+ bool contains(const Loop *L) const;
+
+ /// @brief Get the outermost loop in the region that contains a loop.
+ ///
+ /// Find for a Loop L the outermost loop OuterL that is a parent loop of L
+ /// and is itself contained in the region.
+ ///
+ /// @param L The loop the lookup is started.
+ /// @return The outermost loop in the region, NULL if such a loop does not
+ /// exist or if the region describes the whole function.
+ Loop *outermostLoopInRegion(Loop *L) const;
+
+ /// @brief Get the outermost loop in the region that contains a basic block.
+ ///
+ /// Find for a basic block BB the outermost loop L that contains BB and is
+ /// itself contained in the region.
+ ///
+ /// @param LI A pointer to a LoopInfo analysis.
+ /// @param BB The basic block surrounded by the loop.
+ /// @return The outermost loop in the region, NULL if such a loop does not
+ /// exist or if the region describes the whole function.
+ Loop *outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const;
+
/// @brief Get the subregion that starts at a BasicBlock
///
/// @param BB The BasicBlock the subregion should start.
diff --git a/lib/Analysis/RegionInfo.cpp b/lib/Analysis/RegionInfo.cpp
index 71e3e55..0ea92cb 100644
--- a/lib/Analysis/RegionInfo.cpp
+++ b/lib/Analysis/RegionInfo.cpp
@@ -17,6 +17,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Analysis/LoopInfo.h"
#define DEBUG_TYPE "region"
#include "llvm/Support/Debug.h"
@@ -81,6 +82,44 @@ bool Region::contains(const BasicBlock *B) const {
&& !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
}
+bool Region::contains(const Loop *L) const {
+ // BBs that are not part of any loop are element of the Loop
+ // described by the NULL pointer. This loop is not part of any region,
+ // except if the region describes the whole function.
+ if (L == 0)
+ return getExit() == 0;
+
+ if (!contains(L->getHeader()))
+ return false;
+
+ SmallVector<BasicBlock *, 8> ExitingBlocks;
+ L->getExitingBlocks(ExitingBlocks);
+
+ for (SmallVectorImpl<BasicBlock*>::iterator BI = ExitingBlocks.begin(),
+ BE = ExitingBlocks.end(); BI != BE; ++BI)
+ if (!contains(*BI))
+ return false;
+
+ return true;
+}
+
+Loop *Region::outermostLoopInRegion(Loop *L) const {
+ if (!contains(L))
+ return 0;
+
+ while (L && contains(L->getParentLoop())) {
+ L = L->getParentLoop();
+ }
+
+ return L;
+}
+
+Loop *Region::outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const {
+ assert(LI && BB && "LI and BB cannot be null!");
+ Loop *L = LI->getLoopFor(BB);
+ return outermostLoopInRegion(L);
+}
+
bool Region::isSimple() const {
bool isSimple = true;
bool found = false;
@@ -116,6 +155,32 @@ bool Region::isSimple() const {
return isSimple;
}
+std::string Region::getNameStr() const {
+ std::string exitName;
+ std::string entryName;
+
+ if (getEntry()->getName().empty()) {
+ raw_string_ostream OS(entryName);
+
+ WriteAsOperand(OS, getEntry(), false);
+ entryName = OS.str();
+ } else
+ entryName = getEntry()->getNameStr();
+
+ if (getExit()) {
+ if (getExit()->getName().empty()) {
+ raw_string_ostream OS(exitName);
+
+ WriteAsOperand(OS, getExit(), false);
+ exitName = OS.str();
+ } else
+ exitName = getExit()->getNameStr();
+ } else
+ exitName = "<Function Return>";
+
+ return entryName + " => " + exitName;
+}
+
void Region::verifyBBInRegion(BasicBlock *BB) const {
if (!contains(BB))
llvm_unreachable("Broken region found!");