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