[Polly] Port PruneUnprofitable to the NewPM.

This commit is contained in:
Michael Kruse 2021-02-09 21:53:14 -06:00
parent 7903d594ea
commit b687fc9122
6 changed files with 86 additions and 53 deletions

View File

@ -16,7 +16,6 @@
#include "polly/CodeGen/PPCGCodeGeneration.h"
#include "polly/Config/config.h"
#include "polly/PruneUnprofitable.h"
#include "polly/Simplify.h"
#include "polly/Support/DumpModulePass.h"
#include "llvm/ADT/StringRef.h"
@ -60,6 +59,7 @@ llvm::Pass *createFlattenSchedulePass();
llvm::Pass *createForwardOpTreeWrapperPass();
llvm::Pass *createDeLICMWrapperPass();
llvm::Pass *createMaximalStaticExpansionPass();
llvm::Pass *createPruneUnprofitableWrapperPass();
extern char &CodePreparationID;
} // namespace polly
@ -100,7 +100,7 @@ struct PollyForcePassLinking {
polly::createDeLICMWrapperPass();
polly::createDumpModulePass("", true);
polly::createSimplifyPass();
polly::createPruneUnprofitablePass();
polly::createPruneUnprofitableWrapperPass();
}
} PollyForcePassLinking; // Force link by creating a global definition.
} // namespace
@ -125,6 +125,7 @@ void initializePollyCanonicalizePass(llvm::PassRegistry &);
void initializeFlattenSchedulePass(llvm::PassRegistry &);
void initializeForwardOpTreeWrapperPassPass(llvm::PassRegistry &);
void initializeDeLICMWrapperPassPass(llvm::PassRegistry &);
void initializePruneUnprofitableWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm
#endif

View File

@ -13,17 +13,26 @@
#ifndef POLLY_PRUNEUNPROFITABLE_H
#define POLLY_PRUNEUNPROFITABLE_H
namespace llvm {
#include "polly/ScopPass.h"
namespace llvm {
class Pass;
class PassRegistry;
void initializePruneUnprofitablePass(PassRegistry &);
} // namespace llvm
namespace polly {
llvm::Pass *createPruneUnprofitableWrapperPass();
llvm::Pass *createPruneUnprofitablePass();
struct PruneUnprofitablePass : llvm::PassInfoMixin<PruneUnprofitablePass> {
PruneUnprofitablePass() {}
llvm::PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM,
ScopStandardAnalysisResults &SAR, SPMUpdater &U);
};
} // namespace polly
namespace llvm {
void initializePruneUnprofitableWrapperPassPass(PassRegistry &);
}
#endif // POLLY_PRUNEUNPROFITABLE_H

View File

@ -40,65 +40,84 @@ STATISTIC(NumLoopsInScop, "Number of loops in scops after pruning");
STATISTIC(NumBoxedLoops, "Number of boxed loops in SCoPs after pruning");
STATISTIC(NumAffineLoops, "Number of affine loops in SCoPs after pruning");
class PruneUnprofitable : public ScopPass {
private:
void updateStatistics(Scop &S, bool Pruned) {
auto ScopStats = S.getStatistics();
if (Pruned) {
ScopsPruned++;
NumPrunedLoops += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops;
NumPrunedBoxedLoops += ScopStats.NumBoxedLoops;
NumPrunedAffineLoops += ScopStats.NumAffineLoops;
} else {
ScopsSurvived++;
NumLoopsInScop += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops;
NumBoxedLoops += ScopStats.NumBoxedLoops;
NumAffineLoops += ScopStats.NumAffineLoops;
}
static void updateStatistics(Scop &S, bool Pruned) {
Scop::ScopStatistics ScopStats = S.getStatistics();
if (Pruned) {
ScopsPruned++;
NumPrunedLoops += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops;
NumPrunedBoxedLoops += ScopStats.NumBoxedLoops;
NumPrunedAffineLoops += ScopStats.NumAffineLoops;
} else {
ScopsSurvived++;
NumLoopsInScop += ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops;
NumBoxedLoops += ScopStats.NumBoxedLoops;
NumAffineLoops += ScopStats.NumAffineLoops;
}
}
static bool runPruneUnprofitable(Scop &S) {
if (PollyProcessUnprofitable) {
LLVM_DEBUG(
dbgs() << "NOTE: -polly-process-unprofitable active, won't prune "
"anything\n");
return false;
}
ScopsProcessed++;
if (!S.isProfitable(true)) {
LLVM_DEBUG(
dbgs() << "SCoP pruned because it probably cannot be optimized in "
"a significant way\n");
S.invalidate(PROFITABLE, DebugLoc());
updateStatistics(S, true);
} else {
updateStatistics(S, false);
}
return false;
}
class PruneUnprofitableWrapperPass : public ScopPass {
public:
static char ID;
explicit PruneUnprofitable() : ScopPass(ID) {}
PruneUnprofitable(const PruneUnprofitable &) = delete;
PruneUnprofitable &operator=(const PruneUnprofitable &) = delete;
explicit PruneUnprofitableWrapperPass() : ScopPass(ID) {}
PruneUnprofitableWrapperPass(const PruneUnprofitableWrapperPass &) = delete;
PruneUnprofitableWrapperPass &
operator=(const PruneUnprofitableWrapperPass &) = delete;
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<ScopInfoRegionPass>();
AU.setPreservesAll();
}
bool runOnScop(Scop &S) override {
if (PollyProcessUnprofitable) {
LLVM_DEBUG(
dbgs() << "NOTE: -polly-process-unprofitable active, won't prune "
"anything\n");
return false;
}
ScopsProcessed++;
if (!S.isProfitable(true)) {
LLVM_DEBUG(
dbgs() << "SCoP pruned because it probably cannot be optimized in "
"a significant way\n");
S.invalidate(PROFITABLE, DebugLoc());
updateStatistics(S, true);
} else {
updateStatistics(S, false);
}
return false;
}
bool runOnScop(Scop &S) override { return runPruneUnprofitable(S); }
};
} // namespace
char PruneUnprofitable::ID;
char PruneUnprofitableWrapperPass::ID;
Pass *polly::createPruneUnprofitablePass() { return new PruneUnprofitable(); }
Pass *polly::createPruneUnprofitableWrapperPass() {
return new PruneUnprofitableWrapperPass();
}
INITIALIZE_PASS_BEGIN(PruneUnprofitable, "polly-prune-unprofitable",
INITIALIZE_PASS_BEGIN(PruneUnprofitableWrapperPass, "polly-prune-unprofitable",
"Polly - Prune unprofitable SCoPs", false, false)
INITIALIZE_PASS_END(PruneUnprofitable, "polly-prune-unprofitable",
INITIALIZE_PASS_END(PruneUnprofitableWrapperPass, "polly-prune-unprofitable",
"Polly - Prune unprofitable SCoPs", false, false)
llvm::PreservedAnalyses
PruneUnprofitablePass::run(Scop &S, ScopAnalysisManager &SAM,
ScopStandardAnalysisResults &SAR, SPMUpdater &U) {
bool Changed = runPruneUnprofitable(S);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
PA.preserveSet<AllAnalysesOn<Module>>();
PA.preserveSet<AllAnalysesOn<Function>>();
PA.preserveSet<AllAnalysesOn<Loop>>();
return PA;
}

View File

@ -34,4 +34,5 @@ SCOP_PASS("polly-optree", ForwardOpTreePass())
SCOP_PASS("print<polly-optree>", ForwardOpTreePrinterPass(outs()))
SCOP_PASS("polly-delicm", DeLICMPass())
SCOP_PASS("print<polly-delicm>", DeLICMPrinterPass(outs()))
SCOP_PASS("polly-prune-unprofitable", PruneUnprofitablePass())
#undef SCOP_PASS

View File

@ -30,6 +30,7 @@
#include "polly/JSONExporter.h"
#include "polly/LinkAllPasses.h"
#include "polly/PolyhedralInfo.h"
#include "polly/PruneUnprofitable.h"
#include "polly/ScopDetection.h"
#include "polly/ScopInfo.h"
#include "polly/Simplify.h"
@ -266,7 +267,7 @@ void initializePollyPasses(PassRegistry &Registry) {
initializeDeLICMWrapperPassPass(Registry);
initializeSimplifyLegacyPassPass(Registry);
initializeDumpModulePass(Registry);
initializePruneUnprofitablePass(Registry);
initializePruneUnprofitableWrapperPassPass(Registry);
}
/// Register Polly passes such that they form a polyhedral optimizer.
@ -338,7 +339,7 @@ void registerPollyPasses(llvm::legacy::PassManagerBase &PM) {
PM.add(polly::createMaximalStaticExpansionPass());
if (EnablePruneUnprofitable)
PM.add(polly::createPruneUnprofitablePass());
PM.add(polly::createPruneUnprofitableWrapperPass());
#ifdef GPU_CODEGEN
if (Target == TARGET_HYBRID)
@ -477,7 +478,8 @@ static void buildDefaultPollyPipeline(FunctionPassManager &PM,
if (ImportJScop)
SPM.addPass(JSONImportPass());
assert(!DeadCodeElim && "This option is not implemented");
assert(!EnablePruneUnprofitable && "This option is not implemented");
if (EnablePruneUnprofitable)
SPM.addPass(PruneUnprofitablePass());
if (Target == TARGET_CPU || Target == TARGET_HYBRID)
switch (Optimizer) {
case OPTIMIZER_NONE:

View File

@ -1,4 +1,5 @@
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-process-unprofitable=false -polly-unprofitable-scalar-accs=false -polly-prune-unprofitable -disable-output -stats < %s 2>&1 | FileCheck -match-full-lines %s
; RUN: opt %loadPolly -polly-stmt-granularity=bb -polly-process-unprofitable=false -polly-unprofitable-scalar-accs=false "-passes=scop(polly-prune-unprofitable)" -disable-output -stats < %s 2>&1 | FileCheck -match-full-lines %s
; REQUIRES: asserts
;
; Skip this SCoP for having scalar dependencies between all statements,