[llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp
Devang Patel
dpatel at apple.com
Tue Aug 29 15:29:33 PDT 2006
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
More information about the llvm-commits
mailing list