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 DEBUG(dbgs() << "NOTE: -polly-process-unprofitable active, won't prune " 77 "anything\n"); 78 return false; 79 } 80 81 ScopsProcessed++; 82 83 if (!S.isProfitable(true)) { 84 DEBUG(dbgs() << "SCoP pruned because it probably cannot be optimized in " 85 "a significant way\n"); 86 S.invalidate(PROFITABLE, DebugLoc()); 87 updateStatistics(S, true); 88 } else { 89 updateStatistics(S, false); 90 } 91 92 return false; 93 } 94 }; 95 96 } // namespace 97 98 char PruneUnprofitable::ID; 99 100 Pass *polly::createPruneUnprofitablePass() { return new PruneUnprofitable(); } 101 102 INITIALIZE_PASS_BEGIN(PruneUnprofitable, "polly-prune-unprofitable", 103 "Polly - Prune unprofitable SCoPs", false, false) 104 INITIALIZE_PASS_END(PruneUnprofitable, "polly-prune-unprofitable", 105 "Polly - Prune unprofitable SCoPs", false, false) 106