diff options
author | Chad Rosier <mcrosier@codeaurora.org> | 2015-11-11 23:00:59 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@codeaurora.org> | 2015-11-11 23:00:59 +0000 |
commit | cc9030b60a4b84e3057836eaef2e2fc39b2712c8 (patch) | |
tree | db5bcb6bfa74c973ff328cb3423c1ecaad7ac378 | |
parent | 673283cc7c11de672e1b72d9c38a729da81035ae (diff) | |
download | bcm5719-llvm-cc9030b60a4b84e3057836eaef2e2fc39b2712c8.tar.gz bcm5719-llvm-cc9030b60a4b84e3057836eaef2e2fc39b2712c8.zip |
[LIR] General refactor to improve compile-time and simplify code.
First create a list of candidates, then transform. This simplifies the code in
that you have don't have to worry that you may be using an invalidated
iterator.
Previously, each time we created a memset/memcpy we would reevaluate the entire
loop potentially resulting in lots of redundant work for large basic blocks.
llvm-svn: 252817
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index 668d1df8548..a711319ce5a 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -107,6 +107,9 @@ public: } private: + typedef SmallVector<StoreInst *, 8> StoreList; + StoreList StoreRefs; + /// \name Countable Loop Idiom Handling /// @{ @@ -114,6 +117,7 @@ private: bool runOnLoopBlock(BasicBlock *BB, const SCEV *BECount, SmallVectorImpl<BasicBlock *> &ExitBlocks); + void collectStores(BasicBlock *BB); bool processLoopStore(StoreInst *SI, const SCEV *BECount); bool processLoopMemSet(MemSetInst *MSI, const SCEV *BECount); @@ -240,6 +244,22 @@ bool LoopIdiomRecognize::runOnCountableLoop() { return MadeChange; } +void LoopIdiomRecognize::collectStores(BasicBlock *BB) { + StoreRefs.clear(); + for (Instruction &I : *BB) { + StoreInst *SI = dyn_cast<StoreInst>(&I); + if (!SI) + continue; + + // Don't touch volatile stores. + if (!SI->isSimple()) + continue; + + // Save the store locations. + StoreRefs.push_back(SI); + } +} + /// runOnLoopBlock - Process the specified block, which lives in a counted loop /// with the specified backedge count. This block is known to be in the current /// loop and not in any subloops. @@ -254,22 +274,13 @@ bool LoopIdiomRecognize::runOnLoopBlock( return false; bool MadeChange = false; + // Look for store instructions, which may be optimized to memset/memcpy. + collectStores(BB); + for (auto &SI : StoreRefs) + MadeChange |= processLoopStore(SI, BECount); + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) { Instruction *Inst = &*I++; - // Look for store instructions, which may be optimized to memset/memcpy. - if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { - WeakVH InstPtr(&*I); - if (!processLoopStore(SI, BECount)) - continue; - MadeChange = true; - - // If processing the store invalidated our iterator, start over from the - // top of the block. - if (!InstPtr) - I = BB->begin(); - continue; - } - // Look for memset instructions, which may be optimized to a larger memset. if (MemSetInst *MSI = dyn_cast<MemSetInst>(Inst)) { WeakVH InstPtr(&*I); @@ -290,8 +301,7 @@ bool LoopIdiomRecognize::runOnLoopBlock( /// processLoopStore - See if this store can be promoted to a memset or memcpy. bool LoopIdiomRecognize::processLoopStore(StoreInst *SI, const SCEV *BECount) { - if (!SI->isSimple()) - return false; + assert(SI->isSimple() && "Expected only non-volatile stores."); Value *StoredVal = SI->getValueOperand(); Value *StorePtr = SI->getPointerOperand(); |