diff options
author | Wan Xiaofei <xiaofei.wan@intel.com> | 2013-10-26 03:08:02 +0000 |
---|---|---|
committer | Wan Xiaofei <xiaofei.wan@intel.com> | 2013-10-26 03:08:02 +0000 |
commit | 887f9c5ec15582aec34aa6c28955d01e4e9961e2 (patch) | |
tree | bd8ce8148a4f3a444b2ea0ffa51579a94fa9bb07 /include/llvm/Analysis | |
parent | f7ca7c2a09d4fa03d29fbb1fd1358a285b3c6e2e (diff) | |
download | external_llvm-887f9c5ec15582aec34aa6c28955d01e4e9961e2.zip external_llvm-887f9c5ec15582aec34aa6c28955d01e4e9961e2.tar.gz external_llvm-887f9c5ec15582aec34aa6c28955d01e4e9961e2.tar.bz2 |
Quick look-up for block in loop.
This patch implements quick look-up for block in loop by maintaining a hash set for blocks.
It improves the efficiency of loop analysis a lot, the biggest improvement could be 5-6%(458.sjeng).
Below are the compilation time for our benchmark in llc before & after the patch.
Benchmark llc - trunk llc - patched
401.bzip2 0.339081 100.00% 0.329657 102.86%
403.gcc 19.853966 100.00% 19.605466 101.27%
429.mcf 0.049823 100.00% 0.048451 102.83%
433.milc 0.514898 100.00% 0.510217 100.92%
444.namd 1.109328 100.00% 1.103481 100.53%
445.gobmk 4.988028 100.00% 4.929114 101.20%
456.hmmer 0.843871 100.00% 0.825865 102.18%
458.sjeng 0.754238 100.00% 0.714095 105.62%
464.h264ref 2.9668 100.00% 2.90612 102.09%
471.omnetpp 4.556533 100.00% 4.511886 100.99%
bitmnp01 0.038168 100.00% 0.0357 106.91%
idctrn01 0.037745 100.00% 0.037332 101.11%
libquake2 3.78689 100.00% 3.76209 100.66%
libquake_ 2.251525 100.00% 2.234104 100.78%
linpack 0.033159 100.00% 0.032788 101.13%
matrix01 0.045319 100.00% 0.043497 104.19%
nbench 0.333161 100.00% 0.329799 101.02%
tblook01 0.017863 100.00% 0.017666 101.12%
ttsprk01 0.054337 100.00% 0.053057 102.41%
Reviewer : Andrew Trick <atrick@apple.com>, Hal Finkel <hfinkel@anl.gov>
Approver : Andrew Trick <atrick@apple.com>
Test : Pass make check-all & llvm test-suite
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193460 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Analysis')
-rw-r--r-- | include/llvm/Analysis/LoopInfo.h | 18 | ||||
-rw-r--r-- | include/llvm/Analysis/LoopInfoImpl.h | 41 |
2 files changed, 26 insertions, 33 deletions
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 7b3eed7..62f5aca 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -69,6 +69,8 @@ class LoopBase { // Blocks - The list of blocks in this loop. First entry is the header node. std::vector<BlockT*> Blocks; + SmallPtrSet<const BlockT*, 8> DenseBlockSet; + LoopBase(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION; const LoopBase<BlockT, LoopT>& operator=(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION; @@ -108,7 +110,7 @@ public: /// contains - Return true if the specified basic block is in this loop. /// bool contains(const BlockT *BB) const { - return std::find(block_begin(), block_end(), BB) != block_end(); + return DenseBlockSet.count(BB); } /// contains - Return true if the specified instruction is in this loop. @@ -134,7 +136,6 @@ public: /// getBlocks - Get a list of the basic blocks which make up this loop. /// const std::vector<BlockT*> &getBlocks() const { return Blocks; } - std::vector<BlockT*> &getBlocksVector() { return Blocks; } typedef typename std::vector<BlockT*>::const_iterator block_iterator; block_iterator block_begin() const { return Blocks.begin(); } block_iterator block_end() const { return Blocks.end(); } @@ -271,6 +272,17 @@ public: /// transformations should use addBasicBlockToLoop. void addBlockEntry(BlockT *BB) { Blocks.push_back(BB); + DenseBlockSet.insert(BB); + } + + /// reverseBlocks - interface to reverse Blocks[from, end of loop] in this loop + void reverseBlock(unsigned from) { + std::reverse(Blocks.begin() + from, Blocks.end()); + } + + /// reserveBlocks- interface to do reserve() for Blocks + void reserveBlocks(unsigned size) { + Blocks.reserve(size); } /// moveToHeader - This method is used to move BB (which must be part of this @@ -293,6 +305,7 @@ public: /// the mapping in the LoopInfo class. void removeBlockFromLoop(BlockT *BB) { RemoveFromVector(Blocks, BB); + DenseBlockSet.erase(BB); } /// verifyLoop - Verify loop structure @@ -307,6 +320,7 @@ protected: friend class LoopInfoBase<BlockT, LoopT>; explicit LoopBase(BlockT *BB) : ParentLoop(0) { Blocks.push_back(BB); + DenseBlockSet.insert(BB); } }; diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 5485f3c..c98cb58 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -31,17 +31,12 @@ namespace llvm { template<class BlockT, class LoopT> void LoopBase<BlockT, LoopT>:: getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const { - // Sort the blocks vector so that we can use binary search to do quick - // lookups. - SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end()); - std::sort(LoopBBs.begin(), LoopBBs.end()); - typedef GraphTraits<BlockT*> BlockTraits; for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) for (typename BlockTraits::ChildIteratorType I = BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); I != E; ++I) - if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) { + if (!contains(*I)) { // Not in current loop? It must be an exit block. ExitingBlocks.push_back(*BI); break; @@ -65,17 +60,12 @@ BlockT *LoopBase<BlockT, LoopT>::getExitingBlock() const { template<class BlockT, class LoopT> void LoopBase<BlockT, LoopT>:: getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const { - // Sort the blocks vector so that we can use binary search to do quick - // lookups. - SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end()); - std::sort(LoopBBs.begin(), LoopBBs.end()); - typedef GraphTraits<BlockT*> BlockTraits; for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) for (typename BlockTraits::ChildIteratorType I = BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); I != E; ++I) - if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) + if (!contains(*I)) // Not in current loop? It must be an exit block. ExitBlocks.push_back(*I); } @@ -95,17 +85,12 @@ BlockT *LoopBase<BlockT, LoopT>::getExitBlock() const { template<class BlockT, class LoopT> void LoopBase<BlockT, LoopT>:: getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const { - // Sort the blocks vector so that we can use binary search to do quick - // lookups. - SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end()); - array_pod_sort(LoopBBs.begin(), LoopBBs.end()); - typedef GraphTraits<BlockT*> BlockTraits; for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) for (typename BlockTraits::ChildIteratorType I = BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); I != E; ++I) - if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) + if (!contains(*I)) // Not in current loop? It must be an exit block. ExitEdges.push_back(Edge(*BI, *I)); } @@ -210,7 +195,7 @@ addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LIB) { // Add the basic block to this loop and all parent loops... while (L) { - L->Blocks.push_back(NewBB); + L->addBlockEntry(NewBB); L = L->getParentLoop(); } } @@ -250,11 +235,6 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const { // Keep track of the number of BBs visited. unsigned NumVisited = 0; - // Sort the blocks vector so that we can use binary search to do quick - // lookups. - SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end()); - std::sort(LoopBBs.begin(), LoopBBs.end()); - // Check the individual blocks. for ( ; BI != BE; ++BI) { BlockT *BB = *BI; @@ -266,7 +246,7 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const { for (typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB); SI != SE; ++SI) - if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *SI)) { + if (contains(*SI)) { HasInsideLoopSuccs = true; break; } @@ -275,7 +255,7 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const { InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB); PI != PE; ++PI) { BlockT *N = *PI; - if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), N)) + if (contains(N)) HasInsideLoopPreds = true; else OutsideLoopPreds.push_back(N); @@ -309,7 +289,7 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const { // Each block in each subloop should be contained within this loop. for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end(); BI != BE; ++BI) { - assert(std::binary_search(LoopBBs.begin(), LoopBBs.end(), *BI) && + assert(contains(*BI) && "Loop does not contain all the blocks of a subloop!"); } @@ -418,7 +398,7 @@ static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges, } } L->getSubLoopsVector().reserve(NumSubloops); - L->getBlocksVector().reserve(NumBlocks); + L->reserveBlocks(NumBlocks); } namespace { @@ -489,15 +469,14 @@ void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) { // For convenience, Blocks and Subloops are inserted in postorder. Reverse // the lists, except for the loop header, which is always at the beginning. - std::reverse(Subloop->getBlocksVector().begin()+1, - Subloop->getBlocksVector().end()); + Subloop->reverseBlock(1); std::reverse(Subloop->getSubLoopsVector().begin(), Subloop->getSubLoopsVector().end()); Subloop = Subloop->getParentLoop(); } for (; Subloop; Subloop = Subloop->getParentLoop()) - Subloop->getBlocksVector().push_back(Block); + Subloop->addBlockEntry(Block); } /// Analyze LoopInfo discovers loops during a postorder DominatorTree traversal |