summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Analysis/LoopInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Analysis/LoopInfo.cpp')
-rw-r--r--contrib/llvm/lib/Analysis/LoopInfo.cpp131
1 files changed, 80 insertions, 51 deletions
diff --git a/contrib/llvm/lib/Analysis/LoopInfo.cpp b/contrib/llvm/lib/Analysis/LoopInfo.cpp
index 30f7ef3..f449ce9 100644
--- a/contrib/llvm/lib/Analysis/LoopInfo.cpp
+++ b/contrib/llvm/lib/Analysis/LoopInfo.cpp
@@ -143,42 +143,47 @@ PHINode *Loop::getCanonicalInductionVariable() const {
return nullptr;
}
-bool Loop::isLCSSAForm(DominatorTree &DT) const {
- for (BasicBlock *BB : this->blocks()) {
- for (Instruction &I : *BB) {
- // Tokens can't be used in PHI nodes and live-out tokens prevent loop
- // optimizations, so for the purposes of considered LCSSA form, we
- // can ignore them.
- if (I.getType()->isTokenTy())
- continue;
+// Check that 'BB' doesn't have any uses outside of the 'L'
+static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB,
+ DominatorTree &DT) {
+ for (const Instruction &I : BB) {
+ // Tokens can't be used in PHI nodes and live-out tokens prevent loop
+ // optimizations, so for the purposes of considered LCSSA form, we
+ // can ignore them.
+ if (I.getType()->isTokenTy())
+ continue;
- for (Use &U : I.uses()) {
- Instruction *UI = cast<Instruction>(U.getUser());
- BasicBlock *UserBB = UI->getParent();
- if (PHINode *P = dyn_cast<PHINode>(UI))
- UserBB = P->getIncomingBlock(U);
-
- // Check the current block, as a fast-path, before checking whether
- // the use is anywhere in the loop. Most values are used in the same
- // block they are defined in. Also, blocks not reachable from the
- // entry are special; uses in them don't need to go through PHIs.
- if (UserBB != BB &&
- !contains(UserBB) &&
- DT.isReachableFromEntry(UserBB))
- return false;
- }
+ for (const Use &U : I.uses()) {
+ const Instruction *UI = cast<Instruction>(U.getUser());
+ const BasicBlock *UserBB = UI->getParent();
+ if (const PHINode *P = dyn_cast<PHINode>(UI))
+ UserBB = P->getIncomingBlock(U);
+
+ // Check the current block, as a fast-path, before checking whether
+ // the use is anywhere in the loop. Most values are used in the same
+ // block they are defined in. Also, blocks not reachable from the
+ // entry are special; uses in them don't need to go through PHIs.
+ if (UserBB != &BB && !L.contains(UserBB) &&
+ DT.isReachableFromEntry(UserBB))
+ return false;
}
}
-
return true;
}
-bool Loop::isRecursivelyLCSSAForm(DominatorTree &DT) const {
- if (!isLCSSAForm(DT))
- return false;
+bool Loop::isLCSSAForm(DominatorTree &DT) const {
+ // For each block we check that it doesn't have any uses outside of this loop.
+ return all_of(this->blocks(), [&](const BasicBlock *BB) {
+ return isBlockInLCSSAForm(*this, *BB, DT);
+ });
+}
- return std::all_of(begin(), end(), [&](const Loop *L) {
- return L->isRecursivelyLCSSAForm(DT);
+bool Loop::isRecursivelyLCSSAForm(DominatorTree &DT, const LoopInfo &LI) const {
+ // For each block we check that it doesn't have any uses outside of its
+ // innermost loop. This process will transitively guarantee that the current
+ // loop and all of the nested loops are in LCSSA form.
+ return all_of(this->blocks(), [&](const BasicBlock *BB) {
+ return isBlockInLCSSAForm(*LI.getLoopFor(BB), *BB, DT);
});
}
@@ -300,23 +305,40 @@ bool Loop::isAnnotatedParallel() const {
}
DebugLoc Loop::getStartLoc() const {
+ return getLocRange().getStart();
+}
+
+Loop::LocRange Loop::getLocRange() const {
// If we have a debug location in the loop ID, then use it.
- if (MDNode *LoopID = getLoopID())
- for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i)
- if (DILocation *L = dyn_cast<DILocation>(LoopID->getOperand(i)))
- return DebugLoc(L);
+ if (MDNode *LoopID = getLoopID()) {
+ DebugLoc Start;
+ // We use the first DebugLoc in the header as the start location of the loop
+ // and if there is a second DebugLoc in the header we use it as end location
+ // of the loop.
+ for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) {
+ if (DILocation *L = dyn_cast<DILocation>(LoopID->getOperand(i))) {
+ if (!Start)
+ Start = DebugLoc(L);
+ else
+ return LocRange(Start, DebugLoc(L));
+ }
+ }
+
+ if (Start)
+ return LocRange(Start);
+ }
// Try the pre-header first.
if (BasicBlock *PHeadBB = getLoopPreheader())
if (DebugLoc DL = PHeadBB->getTerminator()->getDebugLoc())
- return DL;
+ return LocRange(DL);
// If we have no pre-header or there are no instructions with debug
// info in it, try the header.
if (BasicBlock *HeadBB = getHeader())
- return HeadBB->getTerminator()->getDebugLoc();
+ return LocRange(HeadBB->getTerminator()->getDebugLoc());
- return DebugLoc();
+ return LocRange();
}
bool Loop::hasDedicatedExits() const {
@@ -366,8 +388,7 @@ Loop::getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const {
// In case of multiple edges from current block to exit block, collect
// only one edge in ExitBlocks. Use switchExitBlocks to keep track of
// duplicate edges.
- if (std::find(SwitchExitBlocks.begin(), SwitchExitBlocks.end(), Successor)
- == SwitchExitBlocks.end()) {
+ if (!is_contained(SwitchExitBlocks, Successor)) {
SwitchExitBlocks.push_back(Successor);
ExitBlocks.push_back(Successor);
}
@@ -387,6 +408,10 @@ BasicBlock *Loop::getUniqueExitBlock() const {
LLVM_DUMP_METHOD void Loop::dump() const {
print(dbgs());
}
+
+LLVM_DUMP_METHOD void Loop::dumpVerbose() const {
+ print(dbgs(), /*Depth=*/ 0, /*Verbose=*/ true);
+}
#endif
//===----------------------------------------------------------------------===//
@@ -532,8 +557,7 @@ Loop *UnloopUpdater::getNearestLoop(BasicBlock *BB, Loop *BBLoop) {
assert(Subloop && "subloop is not an ancestor of the original loop");
}
// Get the current nearest parent of the Subloop exits, initially Unloop.
- NearLoop =
- SubloopParents.insert(std::make_pair(Subloop, &Unloop)).first->second;
+ NearLoop = SubloopParents.insert({Subloop, &Unloop}).first->second;
}
succ_iterator I = succ_begin(BB), E = succ_end(BB);
@@ -645,9 +669,9 @@ void LoopInfo::markAsRemoved(Loop *Unloop) {
}
}
-char LoopAnalysis::PassID;
+AnalysisKey LoopAnalysis::Key;
-LoopInfo LoopAnalysis::run(Function &F, AnalysisManager<Function> &AM) {
+LoopInfo LoopAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
// FIXME: Currently we create a LoopInfo from scratch for every function.
// This may prove to be too wasteful due to deallocating and re-allocating
// memory each time for the underlying map and vector datastructures. At some
@@ -660,23 +684,18 @@ LoopInfo LoopAnalysis::run(Function &F, AnalysisManager<Function> &AM) {
}
PreservedAnalyses LoopPrinterPass::run(Function &F,
- AnalysisManager<Function> &AM) {
+ FunctionAnalysisManager &AM) {
AM.getResult<LoopAnalysis>(F).print(OS);
return PreservedAnalyses::all();
}
-PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}
-PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner)
- : OS(OS), Banner(Banner) {}
-
-PreservedAnalyses PrintLoopPass::run(Loop &L, AnalysisManager<Loop> &) {
+void llvm::printLoop(Loop &L, raw_ostream &OS, const std::string &Banner) {
OS << Banner;
for (auto *Block : L.blocks())
if (Block)
Block->print(OS);
else
OS << "Printing <null> block";
- return PreservedAnalyses::all();
}
//===----------------------------------------------------------------------===//
@@ -702,8 +721,10 @@ void LoopInfoWrapperPass::verifyAnalysis() const {
// -verify-loop-info option can enable this. In order to perform some
// checking by default, LoopPass has been taught to call verifyLoop manually
// during loop pass sequences.
- if (VerifyLoopInfo)
- LI.verify();
+ if (VerifyLoopInfo) {
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ LI.verify(DT);
+ }
}
void LoopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
@@ -715,6 +736,14 @@ void LoopInfoWrapperPass::print(raw_ostream &OS, const Module *) const {
LI.print(OS);
}
+PreservedAnalyses LoopVerifierPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+ LI.verify(DT);
+ return PreservedAnalyses::all();
+}
+
//===----------------------------------------------------------------------===//
// LoopBlocksDFS implementation
//
OpenPOWER on IntegriCloud