diff options
-rw-r--r-- | include/llvm/Analysis/LoopInfo.h | 18 | ||||
-rw-r--r-- | include/llvm/Analysis/LoopInfoImpl.h | 41 | ||||
-rw-r--r-- | lib/Analysis/LoopInfo.cpp | 18 | ||||
-rw-r--r-- | lib/Transforms/Utils/LCSSA.cpp | 15 | ||||
-rw-r--r-- | lib/Transforms/Vectorize/LoopVectorize.cpp | 11 |
5 files changed, 37 insertions, 66 deletions
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 7b3eed7350..62f5acad56 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 5485f3c0c0..c98cb58910 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 diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 142ebed4ed..d2cd6a08c2 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -177,10 +177,6 @@ PHINode *Loop::getCanonicalInductionVariable() const { /// isLCSSAForm - Return true if the Loop is in LCSSA form bool Loop::isLCSSAForm(DominatorTree &DT) const { - // Sort the blocks vector so that we can use binary search to do quick - // lookups. - SmallPtrSet<BasicBlock*, 16> LoopBBs(block_begin(), block_end()); - for (block_iterator BI = block_begin(), E = block_end(); BI != E; ++BI) { BasicBlock *BB = *BI; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;++I) @@ -196,7 +192,7 @@ bool Loop::isLCSSAForm(DominatorTree &DT) const { // block they are defined in. Also, blocks not reachable from the // entry are special; uses in them don't need to go through PHIs. if (UserBB != BB && - !LoopBBs.count(UserBB) && + !contains(UserBB) && DT.isReachableFromEntry(UserBB)) return false; } @@ -337,9 +333,6 @@ bool Loop::isAnnotatedParallel() const { /// hasDedicatedExits - Return true if no exit block for the loop /// has a predecessor that is outside the loop. bool Loop::hasDedicatedExits() const { - // Sort the blocks vector so that we can use binary search to do quick - // lookups. - SmallPtrSet<BasicBlock *, 16> LoopBBs(block_begin(), block_end()); // Each predecessor of each exit block of a normal loop is contained // within the loop. SmallVector<BasicBlock *, 4> ExitBlocks; @@ -347,7 +340,7 @@ bool Loop::hasDedicatedExits() const { for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) for (pred_iterator PI = pred_begin(ExitBlocks[i]), PE = pred_end(ExitBlocks[i]); PI != PE; ++PI) - if (!LoopBBs.count(*PI)) + if (!contains(*PI)) return false; // All the requirements are met. return true; @@ -362,11 +355,6 @@ Loop::getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const { assert(hasDedicatedExits() && "getUniqueExitBlocks assumes the loop has canonical form exits!"); - // Sort the blocks vector so that we can use binary search to do quick - // lookups. - SmallVector<BasicBlock *, 128> LoopBBs(block_begin(), block_end()); - std::sort(LoopBBs.begin(), LoopBBs.end()); - SmallVector<BasicBlock *, 32> switchExitBlocks; for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) { @@ -376,7 +364,7 @@ Loop::getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const { for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I) { // If block is inside the loop then it is not a exit block. - if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) + if (contains(*I)) continue; pred_iterator PI = pred_begin(*I); diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp index 2d1b166c21..f15e8d5927 100644 --- a/lib/Transforms/Utils/LCSSA.cpp +++ b/lib/Transforms/Utils/LCSSA.cpp @@ -55,7 +55,6 @@ namespace { DominatorTree *DT; LoopInfo *LI; ScalarEvolution *SE; - std::vector<BasicBlock*> LoopBlocks; PredIteratorCache PredCache; Loop *L; @@ -82,11 +81,6 @@ namespace { // Check the special guarantees that LCSSA makes. assert(L->isLCSSAForm(*DT) && "LCSSA form not preserved!"); } - - /// inLoop - returns true if the given block is within the current loop - bool inLoop(BasicBlock *B) const { - return std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), B); - } }; } @@ -129,11 +123,6 @@ bool LCSSA::runOnLoop(Loop *TheLoop, LPPassManager &LPM) { if (ExitBlocks.empty()) return false; - // Speed up queries by creating a sorted vector of blocks. - LoopBlocks.clear(); - LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end()); - array_pod_sort(LoopBlocks.begin(), LoopBlocks.end()); - // Look at all the instructions in the loop, checking to see if they have uses // outside the loop. If so, rewrite those uses. bool MadeChange = false; @@ -198,7 +187,7 @@ bool LCSSA::ProcessInstruction(Instruction *Inst, if (PHINode *PN = dyn_cast<PHINode>(U)) UserBB = PN->getIncomingBlock(UI); - if (InstBB != UserBB && !inLoop(UserBB)) + if (InstBB != UserBB && !L->contains(UserBB)) UsesToRewrite.push_back(&UI.getUse()); } @@ -244,7 +233,7 @@ bool LCSSA::ProcessInstruction(Instruction *Inst, // If the exit block has a predecessor not within the loop, arrange for // the incoming value use corresponding to that predecessor to be // rewritten in terms of a different LCSSA PHI. - if (!inLoop(*PI)) + if (!L->contains(*PI)) UsesToRewrite.push_back( &PN->getOperandUse( PN->getOperandNumForIncomingValue(PN->getNumIncomingValues()-1))); diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 8b5424f599..507f67f9c2 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -2694,14 +2694,14 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() { return false; assert(TheLoop->getNumBlocks() > 1 && "Single block loops are vectorizable"); - std::vector<BasicBlock*> &LoopBlocks = TheLoop->getBlocksVector(); // A list of pointers that we can safely read and write to. SmallPtrSet<Value *, 8> SafePointes; // Collect safe addresses. - for (unsigned i = 0, e = LoopBlocks.size(); i < e; ++i) { - BasicBlock *BB = LoopBlocks[i]; + for (Loop::block_iterator BI = TheLoop->block_begin(), + BE = TheLoop->block_end(); BI != BE; ++BI) { + BasicBlock *BB = *BI; if (blockNeedsPredication(BB)) continue; @@ -2715,8 +2715,9 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() { } // Collect the blocks that need predication. - for (unsigned i = 0, e = LoopBlocks.size(); i < e; ++i) { - BasicBlock *BB = LoopBlocks[i]; + for (Loop::block_iterator BI = TheLoop->block_begin(), + BE = TheLoop->block_end(); BI != BE; ++BI) { + BasicBlock *BB = *BI; // We don't support switch statements inside loops. if (!isa<BranchInst>(BB->getTerminator())) |