mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
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
This commit is contained in:
parent
81c7b19f04
commit
082d587d35
@ -37,6 +37,8 @@ namespace llvm {
|
|||||||
class Region;
|
class Region;
|
||||||
class RegionInfo;
|
class RegionInfo;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
class Loop;
|
||||||
|
class LoopInfo;
|
||||||
|
|
||||||
/// @brief Marker class to iterate over the elements of a Region in flat mode.
|
/// @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.
|
/// @brief Returns the name of the Region.
|
||||||
/// @return The Name of the Region.
|
/// @return The Name of the Region.
|
||||||
std::string getNameStr() const {
|
std::string getNameStr() const;
|
||||||
std::string exitName;
|
|
||||||
|
|
||||||
if (getExit())
|
|
||||||
exitName = getExit()->getNameStr();
|
|
||||||
else
|
|
||||||
exitName = "<Function Return>";
|
|
||||||
|
|
||||||
return getEntry()->getNameStr() + " => " + exitName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Return the RegionInfo object, that belongs to this Region.
|
/// @brief Return the RegionInfo object, that belongs to this Region.
|
||||||
RegionInfo *getRegionInfo() const {
|
RegionInfo *getRegionInfo() const {
|
||||||
@ -340,6 +333,36 @@ public:
|
|||||||
return contains(Inst->getParent());
|
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
|
/// @brief Get the subregion that starts at a BasicBlock
|
||||||
///
|
///
|
||||||
/// @param BB The BasicBlock the subregion should start.
|
/// @param BB The BasicBlock the subregion should start.
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
|
|
||||||
#define DEBUG_TYPE "region"
|
#define DEBUG_TYPE "region"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
@ -81,6 +82,44 @@ bool Region::contains(const BasicBlock *B) const {
|
|||||||
&& !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
|
&& !(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 Region::isSimple() const {
|
||||||
bool isSimple = true;
|
bool isSimple = true;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -116,6 +155,32 @@ bool Region::isSimple() const {
|
|||||||
return isSimple;
|
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 {
|
void Region::verifyBBInRegion(BasicBlock *BB) const {
|
||||||
if (!contains(BB))
|
if (!contains(BB))
|
||||||
llvm_unreachable("Broken region found!");
|
llvm_unreachable("Broken region found!");
|
||||||
|
Loading…
Reference in New Issue
Block a user