Add function to query RegionInfo about loops.
authorTobias Grosser <grosser@fim.uni-passau.de>
Tue, 27 Jul 2010 04:17:13 +0000 (04:17 +0000)
committerTobias Grosser <grosser@fim.uni-passau.de>
Tue, 27 Jul 2010 04:17:13 +0000 (04:17 +0000)
* 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

include/llvm/Analysis/RegionInfo.h
lib/Analysis/RegionInfo.cpp

index c4ac1eb29c1f1664701cd13d05a3d37ebb2f459e..a54509f5e8e3b3da82b7119f87684cf6957f4c3f 100644 (file)
@@ -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.
index 71e3e554cf1fa206c6df1d39229a2cf086e47cb5..0ea92cb012b49dc167647bc04807d00603253e5c 100644 (file)
@@ -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!");