1a32707d5SEugene Zelenko //===- PruneUnprofitable.cpp ----------------------------------------------===//
2f3091bf4SMichael Kruse //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f3091bf4SMichael Kruse //
7f3091bf4SMichael Kruse //===----------------------------------------------------------------------===//
8f3091bf4SMichael Kruse //
9f3091bf4SMichael Kruse // Mark a SCoP as unfeasible if not deemed profitable to optimize.
10f3091bf4SMichael Kruse //
11f3091bf4SMichael Kruse //===----------------------------------------------------------------------===//
12f3091bf4SMichael Kruse
13f3091bf4SMichael Kruse #include "polly/PruneUnprofitable.h"
14a32707d5SEugene Zelenko #include "polly/ScopDetection.h"
15f3091bf4SMichael Kruse #include "polly/ScopInfo.h"
16f3091bf4SMichael Kruse #include "polly/ScopPass.h"
17a32707d5SEugene Zelenko #include "llvm/ADT/Statistic.h"
18a32707d5SEugene Zelenko #include "llvm/IR/DebugLoc.h"
19a32707d5SEugene Zelenko #include "llvm/Support/Debug.h"
20a32707d5SEugene Zelenko #include "llvm/Support/raw_ostream.h"
21f3091bf4SMichael Kruse
22f3091bf4SMichael Kruse using namespace llvm;
23a32707d5SEugene Zelenko using namespace polly;
24a32707d5SEugene Zelenko
25a32707d5SEugene Zelenko #define DEBUG_TYPE "polly-prune-unprofitable"
26f3091bf4SMichael Kruse
27f3091bf4SMichael Kruse namespace {
28f3091bf4SMichael Kruse
29f3091bf4SMichael Kruse STATISTIC(ScopsProcessed,
30f3091bf4SMichael Kruse "Number of SCoPs considered for unprofitability pruning");
31f3091bf4SMichael Kruse STATISTIC(ScopsPruned, "Number of pruned SCoPs because it they cannot be "
32f3091bf4SMichael Kruse "optimized in a significant way");
3306ed5292SMichael Kruse STATISTIC(ScopsSurvived, "Number of SCoPs after pruning");
3406ed5292SMichael Kruse
3506ed5292SMichael Kruse STATISTIC(NumPrunedLoops, "Number of pruned loops");
3606ed5292SMichael Kruse STATISTIC(NumPrunedBoxedLoops, "Number of pruned boxed loops");
3706ed5292SMichael Kruse STATISTIC(NumPrunedAffineLoops, "Number of pruned affine loops");
3806ed5292SMichael Kruse
3906ed5292SMichael Kruse STATISTIC(NumLoopsInScop, "Number of loops in scops after pruning");
4006ed5292SMichael Kruse STATISTIC(NumBoxedLoops, "Number of boxed loops in SCoPs after pruning");
4106ed5292SMichael Kruse STATISTIC(NumAffineLoops, "Number of affine loops in SCoPs after pruning");
42f3091bf4SMichael Kruse
updateStatistics(Scop & S,bool Pruned)43b687fc91SMichael Kruse static void updateStatistics(Scop &S, bool Pruned) {
44b687fc91SMichael Kruse Scop::ScopStatistics ScopStats = S.getStatistics();
4506ed5292SMichael Kruse if (Pruned) {
4606ed5292SMichael Kruse ScopsPruned++;
4706ed5292SMichael Kruse NumPrunedLoops += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops;
4806ed5292SMichael Kruse NumPrunedBoxedLoops += ScopStats.NumBoxedLoops;
4906ed5292SMichael Kruse NumPrunedAffineLoops += ScopStats.NumAffineLoops;
5006ed5292SMichael Kruse } else {
5106ed5292SMichael Kruse ScopsSurvived++;
5206ed5292SMichael Kruse NumLoopsInScop += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops;
5306ed5292SMichael Kruse NumBoxedLoops += ScopStats.NumBoxedLoops;
5406ed5292SMichael Kruse NumAffineLoops += ScopStats.NumAffineLoops;
5506ed5292SMichael Kruse }
5606ed5292SMichael Kruse }
5706ed5292SMichael Kruse
runPruneUnprofitable(Scop & S)58b687fc91SMichael Kruse static bool runPruneUnprofitable(Scop &S) {
59f3091bf4SMichael Kruse if (PollyProcessUnprofitable) {
60349506a9SNicola Zaghen LLVM_DEBUG(
61349506a9SNicola Zaghen dbgs() << "NOTE: -polly-process-unprofitable active, won't prune "
62f3091bf4SMichael Kruse "anything\n");
63f3091bf4SMichael Kruse return false;
64f3091bf4SMichael Kruse }
65f3091bf4SMichael Kruse
66f3091bf4SMichael Kruse ScopsProcessed++;
67f3091bf4SMichael Kruse
68f3091bf4SMichael Kruse if (!S.isProfitable(true)) {
69349506a9SNicola Zaghen LLVM_DEBUG(
70349506a9SNicola Zaghen dbgs() << "SCoP pruned because it probably cannot be optimized in "
71f3091bf4SMichael Kruse "a significant way\n");
72f3091bf4SMichael Kruse S.invalidate(PROFITABLE, DebugLoc());
7306ed5292SMichael Kruse updateStatistics(S, true);
7406ed5292SMichael Kruse } else {
7506ed5292SMichael Kruse updateStatistics(S, false);
76f3091bf4SMichael Kruse }
77f3091bf4SMichael Kruse
78f3091bf4SMichael Kruse return false;
79f3091bf4SMichael Kruse }
80b687fc91SMichael Kruse
81*bd93df93SMichael Kruse class PruneUnprofitableWrapperPass final : public ScopPass {
82b687fc91SMichael Kruse public:
83b687fc91SMichael Kruse static char ID;
84b687fc91SMichael Kruse
PruneUnprofitableWrapperPass()85b687fc91SMichael Kruse explicit PruneUnprofitableWrapperPass() : ScopPass(ID) {}
86b687fc91SMichael Kruse PruneUnprofitableWrapperPass(const PruneUnprofitableWrapperPass &) = delete;
87b687fc91SMichael Kruse PruneUnprofitableWrapperPass &
88b687fc91SMichael Kruse operator=(const PruneUnprofitableWrapperPass &) = delete;
89b687fc91SMichael Kruse
getAnalysisUsage(AnalysisUsage & AU) const90b687fc91SMichael Kruse void getAnalysisUsage(AnalysisUsage &AU) const override {
91b687fc91SMichael Kruse AU.addRequired<ScopInfoRegionPass>();
92b687fc91SMichael Kruse AU.setPreservesAll();
93b687fc91SMichael Kruse }
94b687fc91SMichael Kruse
runOnScop(Scop & S)95b687fc91SMichael Kruse bool runOnScop(Scop &S) override { return runPruneUnprofitable(S); }
96f3091bf4SMichael Kruse };
97a32707d5SEugene Zelenko } // namespace
98a32707d5SEugene Zelenko
99b687fc91SMichael Kruse char PruneUnprofitableWrapperPass::ID;
100f3091bf4SMichael Kruse
createPruneUnprofitableWrapperPass()101b687fc91SMichael Kruse Pass *polly::createPruneUnprofitableWrapperPass() {
102b687fc91SMichael Kruse return new PruneUnprofitableWrapperPass();
103b687fc91SMichael Kruse }
104f3091bf4SMichael Kruse
105b687fc91SMichael Kruse INITIALIZE_PASS_BEGIN(PruneUnprofitableWrapperPass, "polly-prune-unprofitable",
106f3091bf4SMichael Kruse "Polly - Prune unprofitable SCoPs", false, false)
107b687fc91SMichael Kruse INITIALIZE_PASS_END(PruneUnprofitableWrapperPass, "polly-prune-unprofitable",
108f3091bf4SMichael Kruse "Polly - Prune unprofitable SCoPs", false, false)
109b687fc91SMichael Kruse
110b687fc91SMichael Kruse llvm::PreservedAnalyses
run(Scop & S,ScopAnalysisManager & SAM,ScopStandardAnalysisResults & SAR,SPMUpdater & U)111b687fc91SMichael Kruse PruneUnprofitablePass::run(Scop &S, ScopAnalysisManager &SAM,
112b687fc91SMichael Kruse ScopStandardAnalysisResults &SAR, SPMUpdater &U) {
113b687fc91SMichael Kruse bool Changed = runPruneUnprofitable(S);
114b687fc91SMichael Kruse
115b687fc91SMichael Kruse if (!Changed)
116b687fc91SMichael Kruse return PreservedAnalyses::all();
117b687fc91SMichael Kruse
118b687fc91SMichael Kruse PreservedAnalyses PA;
119b687fc91SMichael Kruse PA.preserveSet<AllAnalysesOn<Module>>();
120b687fc91SMichael Kruse PA.preserveSet<AllAnalysesOn<Function>>();
121b687fc91SMichael Kruse PA.preserveSet<AllAnalysesOn<Loop>>();
122b687fc91SMichael Kruse return PA;
123b687fc91SMichael Kruse }
124