Changes in directory llvm/lib/Analysis:
LoopInfo.cpp updated: 1.77 -> 1.78 --- Log message: Do not rely on std::sort and std::erase to get list of unique exit blocks. The output is dependent on addresses of basic block. Add and use Loop::getUniqueExitBlocks. --- Diffs of the changes: (+53 -0) LoopInfo.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 53 insertions(+) Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.77 llvm/lib/Analysis/LoopInfo.cpp:1.78 --- llvm/lib/Analysis/LoopInfo.cpp:1.77 Sun Aug 27 17:30:17 2006 +++ llvm/lib/Analysis/LoopInfo.cpp Tue Aug 29 17:29:16 2006 @@ -349,6 +349,59 @@ ExitBlocks.push_back(*I); } +/// getUniqueExitBlocks - Return all unique successor blocks of this loop. These +/// are the blocks _outside of the current loop_ which are branched to. This +/// assumes that loop is in canonical form. +// +void Loop::getUniqueExitBlocks(std::vector<BasicBlock*> &ExitBlocks) const { + // Sort the blocks vector so that we can use binary search to do quick + // lookups. + std::vector<BasicBlock*> LoopBBs(block_begin(), block_end()); + std::sort(LoopBBs.begin(), LoopBBs.end()); + + std::vector<BasicBlock*> switchExitBlocks; + + for (std::vector<BasicBlock*>::const_iterator BI = Blocks.begin(), + BE = Blocks.end(); BI != BE; ++BI) { + + BasicBlock *current = *BI; + switchExitBlocks.clear(); + + for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I) { + if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) + // If block is inside the loop then it is not a exit block. + continue; + + pred_iterator PI = pred_begin(*I); + BasicBlock *firstPred = *PI; + + // If current basic block is this exit block's first predecessor + // then only insert exit block in to the output ExitBlocks vector. + // This ensures that same exit block is not inserted twice into + // ExitBlocks vector. + if (current != firstPred) + continue; + + // If a terminator has more then two successors, for example SwitchInst, + // then it is possible that there are multiple edges from current block + // to one exit block. + if (current->getTerminator()->getNumSuccessors() <= 2) { + ExitBlocks.push_back(*I); + continue; + } + + // 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(), *I) + == switchExitBlocks.end()) { + switchExitBlocks.push_back(*I); + ExitBlocks.push_back(*I); + } + } + } +} + /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits