1 //===- PruneUnprofitable.cpp ----------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Mark a SCoP as unfeasible if not deemed profitable to optimize. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "polly/PruneUnprofitable.h" 15 #include "polly/ScopDetection.h" 16 #include "polly/ScopInfo.h" 17 #include "polly/ScopPass.h" 18 #include "llvm/ADT/Statistic.h" 19 #include "llvm/IR/DebugLoc.h" 20 #include "llvm/Pass.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/raw_ostream.h" 23 24 using namespace llvm; 25 using namespace polly; 26 27 #define DEBUG_TYPE "polly-prune-unprofitable" 28 29 namespace { 30 31 STATISTIC(ScopsProcessed, 32 "Number of SCoPs considered for unprofitability pruning"); 33 STATISTIC(ScopsPruned, "Number of pruned SCoPs because it they cannot be " 34 "optimized in a significant way"); 35 STATISTIC(ScopsSurvived, "Number of SCoPs after pruning"); 36 37 STATISTIC(NumPrunedLoops, "Number of pruned loops"); 38 STATISTIC(NumPrunedBoxedLoops, "Number of pruned boxed loops"); 39 STATISTIC(NumPrunedAffineLoops, "Number of pruned affine loops"); 40 41 STATISTIC(NumLoopsInScop, "Number of loops in scops after pruning"); 42 STATISTIC(NumBoxedLoops, "Number of boxed loops in SCoPs after pruning"); 43 STATISTIC(NumAffineLoops, "Number of affine loops in SCoPs after pruning"); 44 45 class PruneUnprofitable : public ScopPass { 46 private: 47 void updateStatistics(Scop &S, bool Pruned) { 48 auto ScopStats = S.getStatistics(); 49 if (Pruned) { 50 ScopsPruned++; 51 NumPrunedLoops += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops; 52 NumPrunedBoxedLoops += ScopStats.NumBoxedLoops; 53 NumPrunedAffineLoops += ScopStats.NumAffineLoops; 54 } else { 55 ScopsSurvived++; 56 NumLoopsInScop += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops; 57 NumBoxedLoops += ScopStats.NumBoxedLoops; 58 NumAffineLoops += ScopStats.NumAffineLoops; 59 } 60 } 61 62 public: 63 static char ID; 64 65 explicit PruneUnprofitable() : ScopPass(ID) {} 66 PruneUnprofitable(const PruneUnprofitable &) = delete; 67 PruneUnprofitable &operator=(const PruneUnprofitable &) = delete; 68 69 void getAnalysisUsage(AnalysisUsage &AU) const override { 70 AU.addRequired<ScopInfoRegionPass>(); 71 AU.setPreservesAll(); 72 } 73 74 bool runOnScop(Scop &S) override { 75 if (PollyProcessUnprofitable) { 76 LLVM_DEBUG( 77 dbgs() << "NOTE: -polly-process-unprofitable active, won't prune " 78 "anything\n"); 79 return false; 80 } 81 82 ScopsProcessed++; 83 84 if (!S.isProfitable(true)) { 85 LLVM_DEBUG( 86 dbgs() << "SCoP pruned because it probably cannot be optimized in " 87 "a significant way\n"); 88 S.invalidate(PROFITABLE, DebugLoc()); 89 updateStatistics(S, true); 90 } else { 91 updateStatistics(S, false); 92 } 93 94 return false; 95 } 96 }; 97 } // namespace 98 99 char PruneUnprofitable::ID; 100 101 Pass *polly::createPruneUnprofitablePass() { return new PruneUnprofitable(); } 102 103 INITIALIZE_PASS_BEGIN(PruneUnprofitable, "polly-prune-unprofitable", 104 "Polly - Prune unprofitable SCoPs", false, false) 105 INITIALIZE_PASS_END(PruneUnprofitable, "polly-prune-unprofitable", 106 "Polly - Prune unprofitable SCoPs", false, false) 107