Index: llvm/include/llvm/Analysis/LoopInfo.h =================================================================== --- llvm/include/llvm/Analysis/LoopInfo.h +++ llvm/include/llvm/Analysis/LoopInfo.h @@ -168,6 +168,25 @@ return false; } + /// isLoopLatch - Returns true if \p BB is a loop-latch. + /// A latch block is a block that contains a branch back to the header. + /// This function is useful when there are multiple latches in a loop + /// because \fn getLoopLatch will return nullptr in that case. + bool isLoopLatch(const BlockT *BB) const { + BlockT *Header = getHeader(); + typedef GraphTraits > InvBlockTraits; + typename InvBlockTraits::ChildIteratorType PI = + InvBlockTraits::child_begin(Header); + typename InvBlockTraits::ChildIteratorType PE = + InvBlockTraits::child_end(Header); + for (; PI != PE; ++PI) { + typename InvBlockTraits::NodeType *N = *PI; + if ((BB == N) && contains(N)) + return true; + } + return false; + } + /// Calculate the number of back edges to the loop header. unsigned getNumBackEdges() const { unsigned NumBackEdges = 0; @@ -329,7 +348,10 @@ /// Verify loop structure of this loop and all nested loops. void verifyLoopNest(DenseSet *Loops) const; - void print(raw_ostream &OS, unsigned Depth = 0) const; + void print(raw_ostream &OS, unsigned Depth = 0, bool Verbose = false) const; + + /// Print loop with all the BBs inside it. + void printVerbose(raw_ostream &OS, unsigned Depth = 0) const; protected: friend class LoopInfoBase; @@ -451,6 +473,7 @@ BasicBlock *getUniqueExitBlock() const; void dump() const; + void dumpVerbose() const; /// Return the debug location of the start of this loop. /// This looks for a BB terminating instruction with a known debug Index: llvm/include/llvm/Analysis/LoopInfoImpl.h =================================================================== --- llvm/include/llvm/Analysis/LoopInfoImpl.h +++ llvm/include/llvm/Analysis/LoopInfoImpl.h @@ -317,17 +317,24 @@ } template -void LoopBase::print(raw_ostream &OS, unsigned Depth) const { +void LoopBase::print(raw_ostream &OS, unsigned Depth, + bool Verbose) const { OS.indent(Depth*2) << "Loop at depth " << getLoopDepth() << " containing: "; + BlockT *H = getHeader(); for (unsigned i = 0; i < getBlocks().size(); ++i) { - if (i) OS << ","; BlockT *BB = getBlocks()[i]; - BB->printAsOperand(OS, false); - if (BB == getHeader()) OS << "
"; - if (BB == getLoopLatch()) OS << ""; - if (isLoopExiting(BB)) OS << ""; + if (!Verbose) { + if (i) OS << ","; + BB->printAsOperand(OS, false); + } else OS << "\n"; + + if (BB == H) OS << "
"; + if (isLoopLatch(BB)) OS << ""; + if (isLoopExiting(BB)) OS << ""; + if (Verbose) + BB->print(OS); } OS << "\n"; Index: llvm/lib/Analysis/LoopInfo.cpp =================================================================== --- llvm/lib/Analysis/LoopInfo.cpp +++ llvm/lib/Analysis/LoopInfo.cpp @@ -387,6 +387,10 @@ LLVM_DUMP_METHOD void Loop::dump() const { print(dbgs()); } + +LLVM_DUMP_METHOD void Loop::dumpVerbose() const { + print(dbgs(), 0, true); +} #endif //===----------------------------------------------------------------------===//