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