From 7c5f9c35d1afd65c80369803dc5f65309dc361ce Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 26 Dec 2010 20:45:45 +0000 Subject: [PATCH] sketch more of this out. llvm-svn: 122567 --- .../Transforms/Scalar/LoopIdiomRecognize.cpp | 84 ++++++++++++++----- 1 file changed, 64 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index 270c4afcc1d5..eb7d4930edfa 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -17,6 +17,8 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/Target/TargetData.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -26,6 +28,9 @@ using namespace llvm; namespace { class LoopIdiomRecognize : public LoopPass { + Loop *CurLoop; + const TargetData *TD; + ScalarEvolution *SE; public: static char ID; explicit LoopIdiomRecognize() : LoopPass(ID) { @@ -34,7 +39,7 @@ namespace { bool runOnLoop(Loop *L, LPPassManager &LPM); - bool scanBlock(BasicBlock *BB, Loop *L); + bool processLoopStore(StoreInst *SI, const SCEV *BECount); /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG. @@ -66,38 +71,77 @@ INITIALIZE_PASS_END(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms", Pass *llvm::createLoopIdiomPass() { return new LoopIdiomRecognize(); } bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) { + CurLoop = L; + // We only look at trivial single basic block loops. // TODO: eventually support more complex loops, scanning the header. if (L->getBlocks().size() != 1) return false; + // The trip count of the loop must be analyzable. + SE = &getAnalysis(); + if (!SE->hasLoopInvariantBackedgeTakenCount(L)) + return false; + const SCEV *BECount = SE->getBackedgeTakenCount(L); + if (isa(BECount)) return false; + + // We require target data for now. + TD = getAnalysisIfAvailable(); + if (TD == 0) return false; + BasicBlock *BB = L->getHeader(); - DEBUG(dbgs() << "Loop Idiom Recognize: F[" << BB->getParent()->getName() + DEBUG(dbgs() << "loop-idiom Scanning: F[" << BB->getParent()->getName() << "] Loop %" << BB->getName() << "\n"); - return scanBlock(BB, L); + bool MadeChange = false; + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { + // Look for store instructions, which may be memsets. + if (StoreInst *SI = dyn_cast(I++)) + MadeChange |= processLoopStore(SI, BECount); + } + + return MadeChange; } /// scanBlock - Look over a block to see if we can promote anything out of it. -bool LoopIdiomRecognize::scanBlock(BasicBlock *BB, Loop *L) { - ScalarEvolution &SE = getAnalysis(); +bool LoopIdiomRecognize::processLoopStore(StoreInst *SI, const SCEV *BECount) { + Value *StoredVal = SI->getValueOperand(); - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { - // Look for store instructions, which may be memsets. - StoreInst *SI = dyn_cast(I++); - if (SI == 0) continue; - - // See if the pointer expression is an AddRec like {base,+,1} on the current - // loop, which indicates a strided store. If we have something else, it's a - // random store we can't handle. - const SCEVAddRecExpr *Ev = - dyn_cast(SE.getSCEV(SI->getPointerOperand())); - if (Ev == 0 || Ev->getLoop() != L) - continue; - - errs() << "Found strided store: " << *Ev << "\n"; - } + // Check to see if the store updates all bits in memory. We don't want to + // process things like a store of i3. We also require that the store be a + // multiple of a byte. + uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); + if ((SizeInBits & 7) || (SizeInBits >> 32) != 0 || + SizeInBits != TD->getTypeStoreSizeInBits(StoredVal->getType())) + return false; + // See if the pointer expression is an AddRec like {base,+,1} on the current + // loop, which indicates a strided store. If we have something else, it's a + // random store we can't handle. + const SCEVAddRecExpr *Ev = + dyn_cast(SE->getSCEV(SI->getPointerOperand())); + if (Ev == 0 || Ev->getLoop() != CurLoop || !Ev->isAffine()) + return false; + + // Check to see if the stride matches the size of the store. If so, then we + // know that every byte is touched in the loop. + unsigned StoreSize = (unsigned)SizeInBits >> 3; + const SCEVConstant *Stride = dyn_cast(Ev->getOperand(1)); + if (Stride == 0 || StoreSize != Stride->getValue()->getValue()) + return false; + + errs() << "Found strided store: " << *Ev << "\n"; + + // Check for memcpy here. + + + // If the stored value is a byte-wise value (like i32 -1), then it may be + // turned into a memset of i8 -1, assuming that all the consequtive bytes + // are stored. A store of i32 0x01020304 can never be turned into a memset. + Value *SplatValue = isBytewiseValue(StoredVal); + if (SplatValue == 0) return false; + + return false; }