//===----------------------------------------------------------------------===//
#include "llvm/Analysis/RegionInfo.h"
-#include "llvm/Analysis/RegionIterator.h"
-
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Assembly/Writer.h"
-
-#define DEBUG_TYPE "region"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-
-#include <set>
+#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
+#include <iterator>
+#include <set>
using namespace llvm;
+#define DEBUG_TYPE "region"
+
// Always verify if expensive checking is enabled.
#ifdef XDEBUG
static bool VerifyRegionInfo = true;
// Only clean the cache for this Region. Caches of child Regions will be
// cleaned when the child Regions are deleted.
BBNodeMap.clear();
-
- for (iterator I = begin(), E = end(); I != E; ++I)
- delete *I;
}
void Region::replaceEntry(BasicBlock *BB) {
exit = BB;
}
+void Region::replaceEntryRecursive(BasicBlock *NewEntry) {
+ std::vector<Region *> RegionQueue;
+ BasicBlock *OldEntry = getEntry();
+
+ RegionQueue.push_back(this);
+ while (!RegionQueue.empty()) {
+ Region *R = RegionQueue.back();
+ RegionQueue.pop_back();
+
+ R->replaceEntry(NewEntry);
+ for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
+ if ((*RI)->getEntry() == OldEntry)
+ RegionQueue.push_back(RI->get());
+ }
+}
+
+void Region::replaceExitRecursive(BasicBlock *NewExit) {
+ std::vector<Region *> RegionQueue;
+ BasicBlock *OldExit = getExit();
+
+ RegionQueue.push_back(this);
+ while (!RegionQueue.empty()) {
+ Region *R = RegionQueue.back();
+ RegionQueue.pop_back();
+
+ R->replaceExit(NewExit);
+ for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
+ if ((*RI)->getExit() == OldExit)
+ RegionQueue.push_back(RI->get());
+ }
+}
+
bool Region::contains(const BasicBlock *B) const {
BasicBlock *BB = const_cast<BasicBlock*>(B);
- assert(DT->getNode(BB) && "BB not part of the dominance tree");
+ if (!DT->getNode(BB))
+ return false;
BasicBlock *entry = getEntry(), *exit = getExit();
// 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 (!L)
+ return getExit() == nullptr;
if (!contains(L->getHeader()))
return false;
Loop *Region::outermostLoopInRegion(Loop *L) const {
if (!contains(L))
- return 0;
+ return nullptr;
while (L && contains(L->getParentLoop())) {
L = L->getParentLoop();
BasicBlock *Region::getEnteringBlock() const {
BasicBlock *entry = getEntry();
BasicBlock *Pred;
- BasicBlock *enteringBlock = 0;
+ BasicBlock *enteringBlock = nullptr;
for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE;
++PI) {
Pred = *PI;
if (DT->getNode(Pred) && !contains(Pred)) {
if (enteringBlock)
- return 0;
+ return nullptr;
enteringBlock = Pred;
}
BasicBlock *Region::getExitingBlock() const {
BasicBlock *exit = getExit();
BasicBlock *Pred;
- BasicBlock *exitingBlock = 0;
+ BasicBlock *exitingBlock = nullptr;
if (!exit)
- return 0;
+ return nullptr;
for (pred_iterator PI = pred_begin(exit), PE = pred_end(exit); PI != PE;
++PI) {
Pred = *PI;
if (contains(Pred)) {
if (exitingBlock)
- return 0;
+ return nullptr;
exitingBlock = Pred;
}
if (getEntry()->getName().empty()) {
raw_string_ostream OS(entryName);
- WriteAsOperand(OS, getEntry(), false);
- entryName = OS.str();
+ getEntry()->printAsOperand(OS, false);
} else
- entryName = getEntry()->getNameStr();
+ entryName = getEntry()->getName();
if (getExit()) {
if (getExit()->getName().empty()) {
raw_string_ostream OS(exitName);
- WriteAsOperand(OS, getExit(), false);
- exitName = OS.str();
+ getExit()->printAsOperand(OS, false);
} else
- exitName = getExit()->getNameStr();
+ exitName = getExit()->getName();
} else
exitName = "<Function Return>";
verifyRegion();
}
-Region::block_iterator Region::block_begin() {
- return GraphTraits<FlatIt<Region*> >::nodes_begin(this);
-}
-
-Region::block_iterator Region::block_end() {
- return GraphTraits<FlatIt<Region*> >::nodes_end(this);
-}
-
-Region::const_block_iterator Region::block_begin() const {
- return GraphTraits<FlatIt<const Region*> >::nodes_begin(this);
-}
-
-Region::const_block_iterator Region::block_end() const {
- return GraphTraits<FlatIt<const Region*> >::nodes_end(this);
-}
-
Region::element_iterator Region::element_begin() {
return GraphTraits<Region*>::nodes_begin(this);
}
Region *R = RI->getRegionFor(BB);
if (!R || R == this)
- return 0;
+ return nullptr;
// If we pass the BB out of this region, that means our code is broken.
assert(contains(R) && "BB not in current region!");
R = R->getParent();
if (R->getEntry() != BB)
- return 0;
+ return nullptr;
return R;
}
void Region::transferChildrenTo(Region *To) {
for (iterator I = begin(), E = end(); I != E; ++I) {
(*I)->parent = To;
- To->children.push_back(*I);
+ To->children.push_back(std::move(*I));
}
children.clear();
}
void Region::addSubRegion(Region *SubRegion, bool moveChildren) {
- assert(SubRegion->parent == 0 && "SubRegion already has a parent!");
- assert(std::find(begin(), end(), SubRegion) == children.end()
- && "Subregion already exists!");
+ assert(!SubRegion->parent && "SubRegion already has a parent!");
+ assert(std::find_if(begin(), end(), [&](const std::unique_ptr<Region> &R) {
+ return R.get() == SubRegion;
+ }) == children.end() &&
+ "Subregion already exists!");
SubRegion->parent = this;
- children.push_back(SubRegion);
+ children.push_back(std::unique_ptr<Region>(SubRegion));
if (!moveChildren)
return;
RI->setRegionFor(BB, SubRegion);
}
- std::vector<Region*> Keep;
+ std::vector<std::unique_ptr<Region>> Keep;
for (iterator I = begin(), E = end(); I != E; ++I)
- if (SubRegion->contains(*I) && *I != SubRegion) {
- SubRegion->children.push_back(*I);
+ if (SubRegion->contains(I->get()) && I->get() != SubRegion) {
(*I)->parent = SubRegion;
+ SubRegion->children.push_back(std::move(*I));
} else
- Keep.push_back(*I);
+ Keep.push_back(std::move(*I));
children.clear();
- children.insert(children.begin(), Keep.begin(), Keep.end());
+ children.insert(children.begin(),
+ std::move_iterator<RegionSet::iterator>(Keep.begin()),
+ std::move_iterator<RegionSet::iterator>(Keep.end()));
}
Region *Region::removeSubRegion(Region *Child) {
assert(Child->parent == this && "Child is not a child of this region!");
- Child->parent = 0;
- RegionSet::iterator I = std::find(children.begin(), children.end(), Child);
+ Child->parent = nullptr;
+ RegionSet::iterator I = std::find_if(
+ children.begin(), children.end(),
+ [&](const std::unique_ptr<Region> &R) { return R.get() == Child; });
assert(I != children.end() && "Region does not exit. Unable to remove.");
children.erase(children.begin()+(I-begin()));
return Child;
unsigned Region::getDepth() const {
unsigned Depth = 0;
- for (Region *R = parent; R != 0; R = R->parent)
+ for (Region *R = parent; R != nullptr; R = R->parent)
++Depth;
return Depth;
unsigned NumSuccessors = exit->getTerminator()->getNumSuccessors();
if (NumSuccessors == 0)
- return NULL;
+ return nullptr;
for (pred_iterator PI = pred_begin(getExit()), PE = pred_end(getExit());
PI != PE; ++PI)
if (!DT->dominates(getEntry(), *PI))
- return NULL;
+ return nullptr;
Region *R = RI->getRegionFor(exit);
if (exit->getTerminator()->getNumSuccessors() == 1)
return new Region(getEntry(), *succ_begin(exit), RI, DT);
else
- return NULL;
+ return nullptr;
}
while (R->getParent() && R->getParent()->getEntry() == exit)
for (pred_iterator PI = pred_begin(getExit()), PE = pred_end(getExit());
PI != PE; ++PI)
if (!DT->dominates(R->getExit(), *PI))
- return NULL;
+ return nullptr;
return new Region(getEntry(), R->getExit(), RI, DT);
}
OS.indent(level*2 + 2);
if (Style == PrintBB) {
- for (const_block_iterator I = block_begin(), E = block_end(); I!=E; ++I)
- OS << **I << ", "; // TODO: remove the last ","
+ for (const auto &BB : blocks())
+ OS << BB->getName() << ", "; // TODO: remove the last ","
} else if (Style == PrintRN) {
for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I)
OS << **I << ", "; // TODO: remove the last ",
OS.indent(level*2) << "} \n";
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void Region::dump() const {
print(dbgs(), true, getDepth(), printStyle.getValue());
}
+#endif
void Region::clearNodeCache() {
// Free the cached nodes.
assert(entry && exit && "entry and exit must not be null!");
if (isTrivialRegion(entry, exit))
- return 0;
+ return nullptr;
Region *region = new Region(entry, exit, this, DT);
BBtoRegion.insert(std::make_pair(entry, region));
if (!N)
return;
- Region *lastRegion= 0;
+ Region *lastRegion= nullptr;
BasicBlock *lastExit = entry;
// As only a BasicBlock that postdominates entry can finish a region, walk the
// This basic block is a start block of a region. It is already in the
// BBtoRegion relation. Only the child basic blocks have to be updated.
if (it != BBtoRegion.end()) {
- Region *newRegion = it->second;;
+ Region *newRegion = it->second;
region->addSubRegion(getTopMostParent(newRegion));
region = newRegion;
} else {
BBtoRegion.clear();
if (TopLevelRegion)
delete TopLevelRegion;
- TopLevelRegion = 0;
+ TopLevelRegion = nullptr;
}
RegionInfo::RegionInfo() : FunctionPass(ID) {
initializeRegionInfoPass(*PassRegistry::getPassRegistry());
- TopLevelRegion = 0;
+ TopLevelRegion = nullptr;
}
RegionInfo::~RegionInfo() {
bool RegionInfo::runOnFunction(Function &F) {
releaseMemory();
- DT = &getAnalysis<DominatorTree>();
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
PDT = &getAnalysis<PostDominatorTree>();
DF = &getAnalysis<DominanceFrontier>();
- TopLevelRegion = new Region(&F.getEntryBlock(), 0, this, DT, 0);
+ TopLevelRegion = new Region(&F.getEntryBlock(), nullptr, this, DT, nullptr);
updateStatistics(TopLevelRegion);
Calculate(F);
void RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
- AU.addRequiredTransitive<DominatorTree>();
+ AU.addRequiredTransitive<DominatorTreeWrapperPass>();
AU.addRequired<PostDominatorTree>();
AU.addRequired<DominanceFrontier>();
}
Region *RegionInfo::getRegionFor(BasicBlock *BB) const {
BBtoRegionMap::const_iterator I=
BBtoRegion.find(BB);
- return I != BBtoRegion.end() ? I->second : 0;
+ return I != BBtoRegion.end() ? I->second : nullptr;
}
void RegionInfo::setRegionFor(BasicBlock *BB, Region *R) {
}
BasicBlock *RegionInfo::getMaxRegionExit(BasicBlock *BB) const {
- BasicBlock *Exit = NULL;
+ BasicBlock *Exit = nullptr;
while (true) {
// Get largest region that starts at BB.
char RegionInfo::ID = 0;
INITIALIZE_PASS_BEGIN(RegionInfo, "regions",
"Detect single entry single exit regions", true, true)
-INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
INITIALIZE_PASS_DEPENDENCY(DominanceFrontier)
INITIALIZE_PASS_END(RegionInfo, "regions",