From 1bec81a8889f58d47e505ccdfc365404868218d4 Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Tue, 27 Jul 2010 04:17:13 +0000 Subject: [PATCH] Add function to query RegionInfo about loops. * contains(Loop), * getOutermostLoop() * Improve getNameStr() to return a sensible name, if basic blocks are not named. llvm-svn: 109490 --- llvm/include/llvm/Analysis/RegionInfo.h | 43 ++++++++++++---- llvm/lib/Analysis/RegionInfo.cpp | 65 +++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/Analysis/RegionInfo.h b/llvm/include/llvm/Analysis/RegionInfo.h index c4ac1eb29c1f..a54509f5e8e3 100644 --- a/llvm/include/llvm/Analysis/RegionInfo.h +++ b/llvm/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 = ""; - - 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/llvm/lib/Analysis/RegionInfo.cpp b/llvm/lib/Analysis/RegionInfo.cpp index 71e3e554cf1f..0ea92cb012b4 100644 --- a/llvm/lib/Analysis/RegionInfo.cpp +++ b/llvm/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 ExitingBlocks; + L->getExitingBlocks(ExitingBlocks); + + for (SmallVectorImpl::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 = ""; + + return entryName + " => " + exitName; +} + void Region::verifyBBInRegion(BasicBlock *BB) const { if (!contains(BB)) llvm_unreachable("Broken region found!");