summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-08-12 05:02:03 +0000
committerChris Lattner <sabre@nondot.org>2006-08-12 05:02:03 +0000
commit859a138dc4cf4783d37472d89f0723c9c5ddf958 (patch)
tree6b733dfa2e2c08cb4b818bdba2a0bc1d03b2a793 /llvm/lib/Analysis
parent85d9944f9a08edcef715674a819af8d636085898 (diff)
downloadbcm5719-llvm-859a138dc4cf4783d37472d89f0723c9c5ddf958.tar.gz
bcm5719-llvm-859a138dc4cf4783d37472d89f0723c9c5ddf958.zip
Make Loop::getExitBlocks significantly faster for large loops. Instead of
pounding on Loop::contains (which is O(n) in the size of the loop), use a sorted vector, which is O(log(N)) for each query. This speeds up Duraid's horrible testcase from ~72s to ~31s in a debug build. llvm-svn: 29645
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 0ea513368dc..a91c201e0cf 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -336,11 +336,17 @@ void LoopInfo::removeBlock(BasicBlock *BB) {
/// are the blocks _outside of the current loop_ which are branched to.
///
void Loop::getExitBlocks(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());
+
for (std::vector<BasicBlock*>::const_iterator BI = Blocks.begin(),
- BE = Blocks.end(); BI != BE; ++BI)
+ BE = Blocks.end(); BI != BE; ++BI)
for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I)
- if (!contains(*I)) // Not in current loop?
- ExitBlocks.push_back(*I); // It must be an exit block...
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // Not in current loop? It must be an exit block.
+ ExitBlocks.push_back(*I);
}
OpenPOWER on IntegriCloud