diff options
| author | Andrew Kaylor <andrew.kaylor@intel.com> | 2016-08-11 18:28:33 +0000 |
|---|---|---|
| committer | Andrew Kaylor <andrew.kaylor@intel.com> | 2016-08-11 18:28:33 +0000 |
| commit | 7cdf01ef58ac9d181fd02cdee69102d26ec24a2d (patch) | |
| tree | d59643085bbfefba50c2a578a696451702deff66 /llvm/lib/Transforms | |
| parent | 61edc107bbc0c92213184121db1c4bdf029bfdaf (diff) | |
| download | bcm5719-llvm-7cdf01ef58ac9d181fd02cdee69102d26ec24a2d.tar.gz bcm5719-llvm-7cdf01ef58ac9d181fd02cdee69102d26ec24a2d.zip | |
Target independent codesize heuristics for Loop Idiom Recognition
Patch by Sunita Marathe
Differential Revision: https://reviews.llvm.org/D21449
llvm-svn: 278378
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index 90e8bfa93c7..5d156b84b12 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -11,6 +11,12 @@ // non-loop form. In cases that this kicks in, it can be a significant // performance win. // +// If compiling for code size we avoid idiom recognition if the resulting +// code could be larger than the code for the original loop. One way this could +// happen is if the loop is not removable after idiom recognition due to the +// presence of non-idiom instructions. The initial implementation of the +// heuristics applies to idioms in multi-block loops. +// //===----------------------------------------------------------------------===// // // TODO List: @@ -65,6 +71,12 @@ using namespace llvm; STATISTIC(NumMemSet, "Number of memset's formed from loop stores"); STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores"); +static cl::opt<bool> UseLIRCodeSizeHeurs( + "use-lir-code-size-heurs", + cl::desc("Use loop idiom recognition code size heuristics when compiling" + "with -Os/-Oz"), + cl::init(true), cl::Hidden); + namespace { class LoopIdiomRecognize { @@ -76,6 +88,7 @@ class LoopIdiomRecognize { TargetLibraryInfo *TLI; const TargetTransformInfo *TTI; const DataLayout *DL; + bool ApplyCodeSizeHeuristics; public: explicit LoopIdiomRecognize(AliasAnalysis *AA, DominatorTree *DT, @@ -117,8 +130,10 @@ private: Instruction *TheStore, SmallPtrSetImpl<Instruction *> &Stores, const SCEVAddRecExpr *Ev, const SCEV *BECount, - bool NegStride); + bool NegStride, bool IsLoopMemset = false); bool processLoopStoreOfLoopLoad(StoreInst *SI, const SCEV *BECount); + bool avoidLIRForMultiBlockLoop(bool IsMemset = false, + bool IsLoopMemset = false); /// @} /// \name Noncountable Loop Idiom Handling @@ -229,6 +244,10 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L) { if (Name == "memset" || Name == "memcpy") return false; + // Determine if code size heuristics need to be applied. + ApplyCodeSizeHeuristics = + L->getHeader()->getParent()->optForSize() && UseLIRCodeSizeHeurs; + HasMemset = TLI->has(LibFunc::memset); HasMemsetPattern = TLI->has(LibFunc::memset_pattern16); HasMemcpy = TLI->has(LibFunc::memcpy); @@ -689,7 +708,7 @@ bool LoopIdiomRecognize::processLoopMemSet(MemSetInst *MSI, bool NegStride = SizeInBytes == -Stride; return processLoopStridedStore(Pointer, (unsigned)SizeInBytes, MSI->getAlignment(), SplatValue, MSI, MSIs, Ev, - BECount, NegStride); + BECount, NegStride, /*IsLoopMemset=*/true); } /// mayLoopAccessLocation - Return true if the specified loop might access the @@ -745,7 +764,7 @@ bool LoopIdiomRecognize::processLoopStridedStore( Value *DestPtr, unsigned StoreSize, unsigned StoreAlignment, Value *StoredVal, Instruction *TheStore, SmallPtrSetImpl<Instruction *> &Stores, const SCEVAddRecExpr *Ev, - const SCEV *BECount, bool NegStride) { + const SCEV *BECount, bool NegStride, bool IsLoopMemset) { Value *SplatValue = isBytewiseValue(StoredVal); Constant *PatternValue = nullptr; @@ -786,6 +805,9 @@ bool LoopIdiomRecognize::processLoopStridedStore( return false; } + if (avoidLIRForMultiBlockLoop(/*IsMemset=*/true, IsLoopMemset)) + return false; + // Okay, everything looks good, insert the memset. // The # stored bytes is (BECount+1)*Size. Expand the trip count out to @@ -917,6 +939,9 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI, return false; } + if (avoidLIRForMultiBlockLoop()) + return false; + // Okay, everything is safe, we can transform this! // The # stored bytes is (BECount+1)*Size. Expand the trip count out to @@ -948,6 +973,23 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI, return true; } +// When compiling for codesize we avoid idiom recognition for a multi-block loop +// unless it is a loop_memset idiom or a memset/memcpy idiom in a nested loop. +// +bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset, + bool IsLoopMemset) { + if (ApplyCodeSizeHeuristics && CurLoop->getNumBlocks() > 1) { + if (!CurLoop->getParentLoop() && (!IsMemset || !IsLoopMemset)) { + DEBUG(dbgs() << " " << CurLoop->getHeader()->getParent()->getName() + << " : LIR " << (IsMemset ? "Memset" : "Memcpy") + << " avoided: multi-block top-level loop\n"); + return true; + } + } + + return false; +} + bool LoopIdiomRecognize::runOnNoncountableLoop() { return recognizePopcount(); } |

