From: Chad Rosier Date: Thu, 12 Nov 2015 19:09:16 +0000 (+0000) Subject: [LIR] Minor refactoring. NFCI. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1a1fb0065380f9d26311ed28f6c9cca13a2fd9e4;p=oota-llvm.git [LIR] Minor refactoring. NFCI. This change prevents uninteresting stores from being inserted into the list of candidate stores for memset/memcpy conversion. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252926 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index a711319ce5a..e177d4ab697 100644 --- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -118,6 +118,7 @@ private: SmallVectorImpl &ExitBlocks); void collectStores(BasicBlock *BB); + bool isLegalStore(StoreInst *SI); bool processLoopStore(StoreInst *SI, const SCEV *BECount); bool processLoopMemSet(MemSetInst *MSI, const SCEV *BECount); @@ -244,6 +245,42 @@ bool LoopIdiomRecognize::runOnCountableLoop() { return MadeChange; } +static unsigned getStoreSizeInBytes(StoreInst *SI, const DataLayout *DL) { + uint64_t SizeInBits = DL->getTypeSizeInBits(SI->getValueOperand()->getType()); + assert(((SizeInBits & 7) || (SizeInBits >> 32) == 0) && + "Don't overflow unsigned."); + return (unsigned)SizeInBits >> 3; +} + +static unsigned getStoreStride(const SCEVAddRecExpr *StoreEv) { + const SCEVConstant *ConstStride = cast(StoreEv->getOperand(1)); + return ConstStride->getValue()->getValue().getZExtValue(); +} + +bool LoopIdiomRecognize::isLegalStore(StoreInst *SI) { + Value *StoredVal = SI->getValueOperand(); + Value *StorePtr = SI->getPointerOperand(); + + // Reject stores that are so large that they overflow an unsigned. + uint64_t SizeInBits = DL->getTypeSizeInBits(StoredVal->getType()); + if ((SizeInBits & 7) || (SizeInBits >> 32) != 0) + 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 *StoreEv = + dyn_cast(SE->getSCEV(StorePtr)); + if (!StoreEv || StoreEv->getLoop() != CurLoop || !StoreEv->isAffine()) + return false; + + // Check to see if we have a constant stride. + if (!isa(StoreEv->getOperand(1))) + return false; + + return true; +} + void LoopIdiomRecognize::collectStores(BasicBlock *BB) { StoreRefs.clear(); for (Instruction &I : *BB) { @@ -255,6 +292,10 @@ void LoopIdiomRecognize::collectStores(BasicBlock *BB) { if (!SI->isSimple()) continue; + // Make sure this is a strided store with a constant stride. + if (!isLegalStore(SI)) + continue; + // Save the store locations. StoreRefs.push_back(SI); } @@ -306,29 +347,11 @@ bool LoopIdiomRecognize::processLoopStore(StoreInst *SI, const SCEV *BECount) { Value *StoredVal = SI->getValueOperand(); Value *StorePtr = SI->getPointerOperand(); - // Reject stores that are so large that they overflow an unsigned. - uint64_t SizeInBits = DL->getTypeSizeInBits(StoredVal->getType()); - if ((SizeInBits & 7) || (SizeInBits >> 32) != 0) - 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 *StoreEv = - dyn_cast(SE->getSCEV(StorePtr)); - if (!StoreEv || StoreEv->getLoop() != CurLoop || !StoreEv->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 *ConstStride = - dyn_cast(StoreEv->getOperand(1)); - if (!ConstStride) - return false; - - APInt Stride = ConstStride->getValue()->getValue(); + const SCEVAddRecExpr *StoreEv = cast(SE->getSCEV(StorePtr)); + unsigned Stride = getStoreStride(StoreEv); + unsigned StoreSize = getStoreSizeInBytes(SI, DL); if (StoreSize != Stride && StoreSize != -Stride) return false;