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 static void updateStatistics(Scop &S, bool Pruned) { 44 Scop::ScopStatistics ScopStats = S.getStatistics(); 45 if (Pruned) { 46 ScopsPruned++; 47 NumPrunedLoops += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops; 48 NumPrunedBoxedLoops += ScopStats.NumBoxedLoops; 49 NumPrunedAffineLoops += ScopStats.NumAffineLoops; 50 } else { 51 ScopsSurvived++; 52 NumLoopsInScop += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops; 53 NumBoxedLoops += ScopStats.NumBoxedLoops; 54 NumAffineLoops += ScopStats.NumAffineLoops; 55 } 56 } 57 58 static bool runPruneUnprofitable(Scop &S) { 59 if (PollyProcessUnprofitable) { 60 LLVM_DEBUG( 61 dbgs() << "NOTE: -polly-process-unprofitable active, won't prune " 62 "anything\n"); 63 return false; 64 } 65 66 ScopsProcessed++; 67 68 if (!S.isProfitable(true)) { 69 LLVM_DEBUG( 70 dbgs() << "SCoP pruned because it probably cannot be optimized in " 71 "a significant way\n"); 72 S.invalidate(PROFITABLE, DebugLoc()); 73 updateStatistics(S, true); 74 } else { 75 updateStatistics(S, false); 76 } 77 78 return false; 79 } 80 81 class PruneUnprofitableWrapperPass final : public ScopPass { 82 public: 83 static char ID; 84 85 explicit PruneUnprofitableWrapperPass() : ScopPass(ID) {} 86 PruneUnprofitableWrapperPass(const PruneUnprofitableWrapperPass &) = delete; 87 PruneUnprofitableWrapperPass & 88 operator=(const PruneUnprofitableWrapperPass &) = delete; 89 90 void getAnalysisUsage(AnalysisUsage &AU) const override { 91 AU.addRequired<ScopInfoRegionPass>(); 92 AU.setPreservesAll(); 93 } 94 95 bool runOnScop(Scop &S) override { return runPruneUnprofitable(S); } 96 }; 97 } // namespace 98 99 char PruneUnprofitableWrapperPass::ID; 100 101 Pass *polly::createPruneUnprofitableWrapperPass() { 102 return new PruneUnprofitableWrapperPass(); 103 } 104 105 INITIALIZE_PASS_BEGIN(PruneUnprofitableWrapperPass, "polly-prune-unprofitable", 106 "Polly - Prune unprofitable SCoPs", false, false) 107 INITIALIZE_PASS_END(PruneUnprofitableWrapperPass, "polly-prune-unprofitable", 108 "Polly - Prune unprofitable SCoPs", false, false) 109 110 llvm::PreservedAnalyses 111 PruneUnprofitablePass::run(Scop &S, ScopAnalysisManager &SAM, 112 ScopStandardAnalysisResults &SAR, SPMUpdater &U) { 113 bool Changed = runPruneUnprofitable(S); 114 115 if (!Changed) 116 return PreservedAnalyses::all(); 117 118 PreservedAnalyses PA; 119 PA.preserveSet<AllAnalysesOn<Module>>(); 120 PA.preserveSet<AllAnalysesOn<Function>>(); 121 PA.preserveSet<AllAnalysesOn<Loop>>(); 122 return PA; 123 } 124