LLVM API Documentation
00001 //===- llvm/Analysis/LoopInfoImpl.h - Natural Loop Calculator ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This is the generic implementation of LoopInfo used for both Loops and 00011 // MachineLoops. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H 00016 #define LLVM_ANALYSIS_LOOPINFOIMPL_H 00017 00018 #include "llvm/ADT/DepthFirstIterator.h" 00019 #include "llvm/ADT/PostOrderIterator.h" 00020 #include "llvm/ADT/STLExtras.h" 00021 #include "llvm/Analysis/LoopInfo.h" 00022 #include "llvm/IR/Dominators.h" 00023 00024 namespace llvm { 00025 00026 //===----------------------------------------------------------------------===// 00027 // APIs for simple analysis of the loop. See header notes. 00028 00029 /// getExitingBlocks - Return all blocks inside the loop that have successors 00030 /// outside of the loop. These are the blocks _inside of the current loop_ 00031 /// which branch out. The returned list is always unique. 00032 /// 00033 template<class BlockT, class LoopT> 00034 void LoopBase<BlockT, LoopT>:: 00035 getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const { 00036 typedef GraphTraits<BlockT*> BlockTraits; 00037 for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) 00038 for (typename BlockTraits::ChildIteratorType I = 00039 BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); 00040 I != E; ++I) 00041 if (!contains(*I)) { 00042 // Not in current loop? It must be an exit block. 00043 ExitingBlocks.push_back(*BI); 00044 break; 00045 } 00046 } 00047 00048 /// getExitingBlock - If getExitingBlocks would return exactly one block, 00049 /// return that block. Otherwise return null. 00050 template<class BlockT, class LoopT> 00051 BlockT *LoopBase<BlockT, LoopT>::getExitingBlock() const { 00052 SmallVector<BlockT*, 8> ExitingBlocks; 00053 getExitingBlocks(ExitingBlocks); 00054 if (ExitingBlocks.size() == 1) 00055 return ExitingBlocks[0]; 00056 return nullptr; 00057 } 00058 00059 /// getExitBlocks - Return all of the successor blocks of this loop. These 00060 /// are the blocks _outside of the current loop_ which are branched to. 00061 /// 00062 template<class BlockT, class LoopT> 00063 void LoopBase<BlockT, LoopT>:: 00064 getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const { 00065 typedef GraphTraits<BlockT*> BlockTraits; 00066 for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) 00067 for (typename BlockTraits::ChildIteratorType I = 00068 BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); 00069 I != E; ++I) 00070 if (!contains(*I)) 00071 // Not in current loop? It must be an exit block. 00072 ExitBlocks.push_back(*I); 00073 } 00074 00075 /// getExitBlock - If getExitBlocks would return exactly one block, 00076 /// return that block. Otherwise return null. 00077 template<class BlockT, class LoopT> 00078 BlockT *LoopBase<BlockT, LoopT>::getExitBlock() const { 00079 SmallVector<BlockT*, 8> ExitBlocks; 00080 getExitBlocks(ExitBlocks); 00081 if (ExitBlocks.size() == 1) 00082 return ExitBlocks[0]; 00083 return nullptr; 00084 } 00085 00086 /// getExitEdges - Return all pairs of (_inside_block_,_outside_block_). 00087 template<class BlockT, class LoopT> 00088 void LoopBase<BlockT, LoopT>:: 00089 getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const { 00090 typedef GraphTraits<BlockT*> BlockTraits; 00091 for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) 00092 for (typename BlockTraits::ChildIteratorType I = 00093 BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); 00094 I != E; ++I) 00095 if (!contains(*I)) 00096 // Not in current loop? It must be an exit block. 00097 ExitEdges.push_back(Edge(*BI, *I)); 00098 } 00099 00100 /// getLoopPreheader - If there is a preheader for this loop, return it. A 00101 /// loop has a preheader if there is only one edge to the header of the loop 00102 /// from outside of the loop. If this is the case, the block branching to the 00103 /// header of the loop is the preheader node. 00104 /// 00105 /// This method returns null if there is no preheader for the loop. 00106 /// 00107 template<class BlockT, class LoopT> 00108 BlockT *LoopBase<BlockT, LoopT>::getLoopPreheader() const { 00109 // Keep track of nodes outside the loop branching to the header... 00110 BlockT *Out = getLoopPredecessor(); 00111 if (!Out) return nullptr; 00112 00113 // Make sure there is only one exit out of the preheader. 00114 typedef GraphTraits<BlockT*> BlockTraits; 00115 typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out); 00116 ++SI; 00117 if (SI != BlockTraits::child_end(Out)) 00118 return nullptr; // Multiple exits from the block, must not be a preheader. 00119 00120 // The predecessor has exactly one successor, so it is a preheader. 00121 return Out; 00122 } 00123 00124 /// getLoopPredecessor - If the given loop's header has exactly one unique 00125 /// predecessor outside the loop, return it. Otherwise return null. 00126 /// This is less strict that the loop "preheader" concept, which requires 00127 /// the predecessor to have exactly one successor. 00128 /// 00129 template<class BlockT, class LoopT> 00130 BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const { 00131 // Keep track of nodes outside the loop branching to the header... 00132 BlockT *Out = nullptr; 00133 00134 // Loop over the predecessors of the header node... 00135 BlockT *Header = getHeader(); 00136 typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; 00137 for (typename InvBlockTraits::ChildIteratorType PI = 00138 InvBlockTraits::child_begin(Header), 00139 PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) { 00140 typename InvBlockTraits::NodeType *N = *PI; 00141 if (!contains(N)) { // If the block is not in the loop... 00142 if (Out && Out != N) 00143 return nullptr; // Multiple predecessors outside the loop 00144 Out = N; 00145 } 00146 } 00147 00148 // Make sure there is only one exit out of the preheader. 00149 assert(Out && "Header of loop has no predecessors from outside loop?"); 00150 return Out; 00151 } 00152 00153 /// getLoopLatch - If there is a single latch block for this loop, return it. 00154 /// A latch block is a block that contains a branch back to the header. 00155 template<class BlockT, class LoopT> 00156 BlockT *LoopBase<BlockT, LoopT>::getLoopLatch() const { 00157 BlockT *Header = getHeader(); 00158 typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; 00159 typename InvBlockTraits::ChildIteratorType PI = 00160 InvBlockTraits::child_begin(Header); 00161 typename InvBlockTraits::ChildIteratorType PE = 00162 InvBlockTraits::child_end(Header); 00163 BlockT *Latch = nullptr; 00164 for (; PI != PE; ++PI) { 00165 typename InvBlockTraits::NodeType *N = *PI; 00166 if (contains(N)) { 00167 if (Latch) return nullptr; 00168 Latch = N; 00169 } 00170 } 00171 00172 return Latch; 00173 } 00174 00175 //===----------------------------------------------------------------------===// 00176 // APIs for updating loop information after changing the CFG 00177 // 00178 00179 /// addBasicBlockToLoop - This method is used by other analyses to update loop 00180 /// information. NewBB is set to be a new member of the current loop. 00181 /// Because of this, it is added as a member of all parent loops, and is added 00182 /// to the specified LoopInfo object as being in the current basic block. It 00183 /// is not valid to replace the loop header with this method. 00184 /// 00185 template<class BlockT, class LoopT> 00186 void LoopBase<BlockT, LoopT>:: 00187 addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LIB) { 00188 assert((Blocks.empty() || LIB[getHeader()] == this) && 00189 "Incorrect LI specified for this loop!"); 00190 assert(NewBB && "Cannot add a null basic block to the loop!"); 00191 assert(!LIB[NewBB] && "BasicBlock already in the loop!"); 00192 00193 LoopT *L = static_cast<LoopT *>(this); 00194 00195 // Add the loop mapping to the LoopInfo object... 00196 LIB.BBMap[NewBB] = L; 00197 00198 // Add the basic block to this loop and all parent loops... 00199 while (L) { 00200 L->addBlockEntry(NewBB); 00201 L = L->getParentLoop(); 00202 } 00203 } 00204 00205 /// replaceChildLoopWith - This is used when splitting loops up. It replaces 00206 /// the OldChild entry in our children list with NewChild, and updates the 00207 /// parent pointer of OldChild to be null and the NewChild to be this loop. 00208 /// This updates the loop depth of the new child. 00209 template<class BlockT, class LoopT> 00210 void LoopBase<BlockT, LoopT>:: 00211 replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild) { 00212 assert(OldChild->ParentLoop == this && "This loop is already broken!"); 00213 assert(!NewChild->ParentLoop && "NewChild already has a parent!"); 00214 typename std::vector<LoopT *>::iterator I = 00215 std::find(SubLoops.begin(), SubLoops.end(), OldChild); 00216 assert(I != SubLoops.end() && "OldChild not in loop!"); 00217 *I = NewChild; 00218 OldChild->ParentLoop = nullptr; 00219 NewChild->ParentLoop = static_cast<LoopT *>(this); 00220 } 00221 00222 /// verifyLoop - Verify loop structure 00223 template<class BlockT, class LoopT> 00224 void LoopBase<BlockT, LoopT>::verifyLoop() const { 00225 #ifndef NDEBUG 00226 assert(!Blocks.empty() && "Loop header is missing"); 00227 00228 // Setup for using a depth-first iterator to visit every block in the loop. 00229 SmallVector<BlockT*, 8> ExitBBs; 00230 getExitBlocks(ExitBBs); 00231 llvm::SmallPtrSet<BlockT*, 8> VisitSet; 00232 VisitSet.insert(ExitBBs.begin(), ExitBBs.end()); 00233 df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> > 00234 BI = df_ext_begin(getHeader(), VisitSet), 00235 BE = df_ext_end(getHeader(), VisitSet); 00236 00237 // Keep track of the number of BBs visited. 00238 unsigned NumVisited = 0; 00239 00240 // Check the individual blocks. 00241 for ( ; BI != BE; ++BI) { 00242 BlockT *BB = *BI; 00243 bool HasInsideLoopSuccs = false; 00244 bool HasInsideLoopPreds = false; 00245 SmallVector<BlockT *, 2> OutsideLoopPreds; 00246 00247 typedef GraphTraits<BlockT*> BlockTraits; 00248 for (typename BlockTraits::ChildIteratorType SI = 00249 BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB); 00250 SI != SE; ++SI) 00251 if (contains(*SI)) { 00252 HasInsideLoopSuccs = true; 00253 break; 00254 } 00255 typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; 00256 for (typename InvBlockTraits::ChildIteratorType PI = 00257 InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB); 00258 PI != PE; ++PI) { 00259 BlockT *N = *PI; 00260 if (contains(N)) 00261 HasInsideLoopPreds = true; 00262 else 00263 OutsideLoopPreds.push_back(N); 00264 } 00265 00266 if (BB == getHeader()) { 00267 assert(!OutsideLoopPreds.empty() && "Loop is unreachable!"); 00268 } else if (!OutsideLoopPreds.empty()) { 00269 // A non-header loop shouldn't be reachable from outside the loop, 00270 // though it is permitted if the predecessor is not itself actually 00271 // reachable. 00272 BlockT *EntryBB = BB->getParent()->begin(); 00273 for (BlockT *CB : depth_first(EntryBB)) 00274 for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i) 00275 assert(CB != OutsideLoopPreds[i] && 00276 "Loop has multiple entry points!"); 00277 } 00278 assert(HasInsideLoopPreds && "Loop block has no in-loop predecessors!"); 00279 assert(HasInsideLoopSuccs && "Loop block has no in-loop successors!"); 00280 assert(BB != getHeader()->getParent()->begin() && 00281 "Loop contains function entry block!"); 00282 00283 NumVisited++; 00284 } 00285 00286 assert(NumVisited == getNumBlocks() && "Unreachable block in loop"); 00287 00288 // Check the subloops. 00289 for (iterator I = begin(), E = end(); I != E; ++I) 00290 // Each block in each subloop should be contained within this loop. 00291 for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end(); 00292 BI != BE; ++BI) { 00293 assert(contains(*BI) && 00294 "Loop does not contain all the blocks of a subloop!"); 00295 } 00296 00297 // Check the parent loop pointer. 00298 if (ParentLoop) { 00299 assert(std::find(ParentLoop->begin(), ParentLoop->end(), this) != 00300 ParentLoop->end() && 00301 "Loop is not a subloop of its parent!"); 00302 } 00303 #endif 00304 } 00305 00306 /// verifyLoop - Verify loop structure of this loop and all nested loops. 00307 template<class BlockT, class LoopT> 00308 void LoopBase<BlockT, LoopT>::verifyLoopNest( 00309 DenseSet<const LoopT*> *Loops) const { 00310 Loops->insert(static_cast<const LoopT *>(this)); 00311 // Verify this loop. 00312 verifyLoop(); 00313 // Verify the subloops. 00314 for (iterator I = begin(), E = end(); I != E; ++I) 00315 (*I)->verifyLoopNest(Loops); 00316 } 00317 00318 template<class BlockT, class LoopT> 00319 void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth) const { 00320 OS.indent(Depth*2) << "Loop at depth " << getLoopDepth() 00321 << " containing: "; 00322 00323 for (unsigned i = 0; i < getBlocks().size(); ++i) { 00324 if (i) OS << ","; 00325 BlockT *BB = getBlocks()[i]; 00326 BB->printAsOperand(OS, false); 00327 if (BB == getHeader()) OS << "<header>"; 00328 if (BB == getLoopLatch()) OS << "<latch>"; 00329 if (isLoopExiting(BB)) OS << "<exiting>"; 00330 } 00331 OS << "\n"; 00332 00333 for (iterator I = begin(), E = end(); I != E; ++I) 00334 (*I)->print(OS, Depth+2); 00335 } 00336 00337 //===----------------------------------------------------------------------===// 00338 /// Stable LoopInfo Analysis - Build a loop tree using stable iterators so the 00339 /// result does / not depend on use list (block predecessor) order. 00340 /// 00341 00342 /// Discover a subloop with the specified backedges such that: All blocks within 00343 /// this loop are mapped to this loop or a subloop. And all subloops within this 00344 /// loop have their parent loop set to this loop or a subloop. 00345 template<class BlockT, class LoopT> 00346 static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges, 00347 LoopInfoBase<BlockT, LoopT> *LI, 00348 DominatorTreeBase<BlockT> &DomTree) { 00349 typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; 00350 00351 unsigned NumBlocks = 0; 00352 unsigned NumSubloops = 0; 00353 00354 // Perform a backward CFG traversal using a worklist. 00355 std::vector<BlockT *> ReverseCFGWorklist(Backedges.begin(), Backedges.end()); 00356 while (!ReverseCFGWorklist.empty()) { 00357 BlockT *PredBB = ReverseCFGWorklist.back(); 00358 ReverseCFGWorklist.pop_back(); 00359 00360 LoopT *Subloop = LI->getLoopFor(PredBB); 00361 if (!Subloop) { 00362 if (!DomTree.isReachableFromEntry(PredBB)) 00363 continue; 00364 00365 // This is an undiscovered block. Map it to the current loop. 00366 LI->changeLoopFor(PredBB, L); 00367 ++NumBlocks; 00368 if (PredBB == L->getHeader()) 00369 continue; 00370 // Push all block predecessors on the worklist. 00371 ReverseCFGWorklist.insert(ReverseCFGWorklist.end(), 00372 InvBlockTraits::child_begin(PredBB), 00373 InvBlockTraits::child_end(PredBB)); 00374 } 00375 else { 00376 // This is a discovered block. Find its outermost discovered loop. 00377 while (LoopT *Parent = Subloop->getParentLoop()) 00378 Subloop = Parent; 00379 00380 // If it is already discovered to be a subloop of this loop, continue. 00381 if (Subloop == L) 00382 continue; 00383 00384 // Discover a subloop of this loop. 00385 Subloop->setParentLoop(L); 00386 ++NumSubloops; 00387 NumBlocks += Subloop->getBlocks().capacity(); 00388 PredBB = Subloop->getHeader(); 00389 // Continue traversal along predecessors that are not loop-back edges from 00390 // within this subloop tree itself. Note that a predecessor may directly 00391 // reach another subloop that is not yet discovered to be a subloop of 00392 // this loop, which we must traverse. 00393 for (typename InvBlockTraits::ChildIteratorType PI = 00394 InvBlockTraits::child_begin(PredBB), 00395 PE = InvBlockTraits::child_end(PredBB); PI != PE; ++PI) { 00396 if (LI->getLoopFor(*PI) != Subloop) 00397 ReverseCFGWorklist.push_back(*PI); 00398 } 00399 } 00400 } 00401 L->getSubLoopsVector().reserve(NumSubloops); 00402 L->reserveBlocks(NumBlocks); 00403 } 00404 00405 namespace { 00406 /// Populate all loop data in a stable order during a single forward DFS. 00407 template<class BlockT, class LoopT> 00408 class PopulateLoopsDFS { 00409 typedef GraphTraits<BlockT*> BlockTraits; 00410 typedef typename BlockTraits::ChildIteratorType SuccIterTy; 00411 00412 LoopInfoBase<BlockT, LoopT> *LI; 00413 DenseSet<const BlockT *> VisitedBlocks; 00414 std::vector<std::pair<BlockT*, SuccIterTy> > DFSStack; 00415 00416 public: 00417 PopulateLoopsDFS(LoopInfoBase<BlockT, LoopT> *li): 00418 LI(li) {} 00419 00420 void traverse(BlockT *EntryBlock); 00421 00422 protected: 00423 void insertIntoLoop(BlockT *Block); 00424 00425 BlockT *dfsSource() { return DFSStack.back().first; } 00426 SuccIterTy &dfsSucc() { return DFSStack.back().second; } 00427 SuccIterTy dfsSuccEnd() { return BlockTraits::child_end(dfsSource()); } 00428 00429 void pushBlock(BlockT *Block) { 00430 DFSStack.push_back(std::make_pair(Block, BlockTraits::child_begin(Block))); 00431 } 00432 }; 00433 } // anonymous 00434 00435 /// Top-level driver for the forward DFS within the loop. 00436 template<class BlockT, class LoopT> 00437 void PopulateLoopsDFS<BlockT, LoopT>::traverse(BlockT *EntryBlock) { 00438 pushBlock(EntryBlock); 00439 VisitedBlocks.insert(EntryBlock); 00440 while (!DFSStack.empty()) { 00441 // Traverse the leftmost path as far as possible. 00442 while (dfsSucc() != dfsSuccEnd()) { 00443 BlockT *BB = *dfsSucc(); 00444 ++dfsSucc(); 00445 if (!VisitedBlocks.insert(BB).second) 00446 continue; 00447 00448 // Push the next DFS successor onto the stack. 00449 pushBlock(BB); 00450 } 00451 // Visit the top of the stack in postorder and backtrack. 00452 insertIntoLoop(dfsSource()); 00453 DFSStack.pop_back(); 00454 } 00455 } 00456 00457 /// Add a single Block to its ancestor loops in PostOrder. If the block is a 00458 /// subloop header, add the subloop to its parent in PostOrder, then reverse the 00459 /// Block and Subloop vectors of the now complete subloop to achieve RPO. 00460 template<class BlockT, class LoopT> 00461 void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) { 00462 LoopT *Subloop = LI->getLoopFor(Block); 00463 if (Subloop && Block == Subloop->getHeader()) { 00464 // We reach this point once per subloop after processing all the blocks in 00465 // the subloop. 00466 if (Subloop->getParentLoop()) 00467 Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop); 00468 else 00469 LI->addTopLevelLoop(Subloop); 00470 00471 // For convenience, Blocks and Subloops are inserted in postorder. Reverse 00472 // the lists, except for the loop header, which is always at the beginning. 00473 Subloop->reverseBlock(1); 00474 std::reverse(Subloop->getSubLoopsVector().begin(), 00475 Subloop->getSubLoopsVector().end()); 00476 00477 Subloop = Subloop->getParentLoop(); 00478 } 00479 for (; Subloop; Subloop = Subloop->getParentLoop()) 00480 Subloop->addBlockEntry(Block); 00481 } 00482 00483 /// Analyze LoopInfo discovers loops during a postorder DominatorTree traversal 00484 /// interleaved with backward CFG traversals within each subloop 00485 /// (discoverAndMapSubloop). The backward traversal skips inner subloops, so 00486 /// this part of the algorithm is linear in the number of CFG edges. Subloop and 00487 /// Block vectors are then populated during a single forward CFG traversal 00488 /// (PopulateLoopDFS). 00489 /// 00490 /// During the two CFG traversals each block is seen three times: 00491 /// 1) Discovered and mapped by a reverse CFG traversal. 00492 /// 2) Visited during a forward DFS CFG traversal. 00493 /// 3) Reverse-inserted in the loop in postorder following forward DFS. 00494 /// 00495 /// The Block vectors are inclusive, so step 3 requires loop-depth number of 00496 /// insertions per block. 00497 template<class BlockT, class LoopT> 00498 void LoopInfoBase<BlockT, LoopT>:: 00499 Analyze(DominatorTreeBase<BlockT> &DomTree) { 00500 00501 // Postorder traversal of the dominator tree. 00502 DomTreeNodeBase<BlockT>* DomRoot = DomTree.getRootNode(); 00503 for (po_iterator<DomTreeNodeBase<BlockT>*> DomIter = po_begin(DomRoot), 00504 DomEnd = po_end(DomRoot); DomIter != DomEnd; ++DomIter) { 00505 00506 BlockT *Header = DomIter->getBlock(); 00507 SmallVector<BlockT *, 4> Backedges; 00508 00509 // Check each predecessor of the potential loop header. 00510 typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; 00511 for (typename InvBlockTraits::ChildIteratorType PI = 00512 InvBlockTraits::child_begin(Header), 00513 PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) { 00514 00515 BlockT *Backedge = *PI; 00516 00517 // If Header dominates predBB, this is a new loop. Collect the backedges. 00518 if (DomTree.dominates(Header, Backedge) 00519 && DomTree.isReachableFromEntry(Backedge)) { 00520 Backedges.push_back(Backedge); 00521 } 00522 } 00523 // Perform a backward CFG traversal to discover and map blocks in this loop. 00524 if (!Backedges.empty()) { 00525 LoopT *L = new LoopT(Header); 00526 discoverAndMapSubloop(L, ArrayRef<BlockT*>(Backedges), this, DomTree); 00527 } 00528 } 00529 // Perform a single forward CFG traversal to populate block and subloop 00530 // vectors for all loops. 00531 PopulateLoopsDFS<BlockT, LoopT> DFS(this); 00532 DFS.traverse(DomRoot->getBlock()); 00533 } 00534 00535 // Debugging 00536 template<class BlockT, class LoopT> 00537 void LoopInfoBase<BlockT, LoopT>::print(raw_ostream &OS) const { 00538 for (unsigned i = 0; i < TopLevelLoops.size(); ++i) 00539 TopLevelLoops[i]->print(OS); 00540 #if 0 00541 for (DenseMap<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(), 00542 E = BBMap.end(); I != E; ++I) 00543 OS << "BB '" << I->first->getName() << "' level = " 00544 << I->second->getLoopDepth() << "\n"; 00545 #endif 00546 } 00547 00548 } // End llvm namespace 00549 00550 #endif