diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h index 7c89744123fd..12cb6c5cc480 100644 --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -33,6 +33,7 @@ #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallVector.h" @@ -484,12 +485,13 @@ public: } /// verifyLoop - Verify loop structure of this loop and all nested loops. - void verifyLoopNest() const { + void verifyLoopNest(DenseSet *Loops) const { + Loops->insert(static_cast(this)); // Verify this loop. verifyLoop(); // Verify the subloops. for (iterator I = begin(), E = end(); I != E; ++I) - (*I)->verifyLoopNest(); + (*I)->verifyLoopNest(Loops); } void print(raw_ostream &OS, unsigned Depth = 0) const { @@ -640,6 +642,7 @@ class LoopInfoBase { DenseMap BBMap; std::vector TopLevelLoops; friend class LoopBase; + friend class LoopInfo; void operator=(const LoopInfoBase &); // do not implement LoopInfoBase(const LoopInfo &); // do not implement diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 6abb14f55ae5..85aaccaefc37 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -509,6 +509,8 @@ void UnloopUpdater::updateSubloopParents() { assert(SubloopParents.count(Subloop) && "DFS failed to visit subloop"); if (SubloopParents[Subloop]) SubloopParents[Subloop]->addChildLoop(Subloop); + else + LI->addTopLevelLoop(Subloop); } } @@ -663,12 +665,21 @@ void LoopInfo::verifyAnalysis() const { if (!VerifyLoopInfo) return; + DenseSet Loops; for (iterator I = begin(), E = end(); I != E; ++I) { assert(!(*I)->getParentLoop() && "Top-level loop has a parent!"); - (*I)->verifyLoopNest(); + (*I)->verifyLoopNest(&Loops); } - // TODO: check BBMap consistency. + // Verify that blocks are mapped to valid loops. + // + // FIXME: With an up-to-date DFS (see LoopIterator.h) and DominatorTree, we + // could also verify that the blocks are still in the correct loops. + for (DenseMap::const_iterator I = LI.BBMap.begin(), + E = LI.BBMap.end(); I != E; ++I) { + assert(Loops.count(I->second) && "orphaned loop"); + assert(I->second->contains(I->first) && "orphaned block"); + } } void LoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {