aboutsummaryrefslogtreecommitdiff
path: root/polly/lib
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib')
-rw-r--r--polly/lib/Analysis/DependenceInfo.cpp247
-rw-r--r--polly/lib/Analysis/PruneUnprofitable.cpp48
-rw-r--r--polly/lib/Analysis/ScopBuilder.cpp11
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp108
-rw-r--r--polly/lib/Analysis/ScopGraphPrinter.cpp120
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp229
-rw-r--r--polly/lib/Analysis/ScopPass.cpp170
-rw-r--r--polly/lib/CMakeLists.txt4
-rw-r--r--polly/lib/CodeGen/CodeGeneration.cpp107
-rw-r--r--polly/lib/CodeGen/IslAst.cpp120
-rw-r--r--polly/lib/Exchange/JSONExporter.cpp181
-rw-r--r--polly/lib/Pass/PhaseManager.cpp437
-rw-r--r--polly/lib/Pass/PollyFunctionPass.cpp22
-rw-r--r--polly/lib/Pass/PollyModulePass.cpp29
-rw-r--r--polly/lib/Support/DumpFunctionPass.cpp41
-rw-r--r--polly/lib/Support/DumpModulePass.cpp47
-rw-r--r--polly/lib/Support/PollyPasses.def55
-rw-r--r--polly/lib/Support/RegisterPasses.cpp499
-rw-r--r--polly/lib/Support/ScopHelper.cpp12
-rw-r--r--polly/lib/Transform/Canonicalization.cpp65
-rw-r--r--polly/lib/Transform/CodePreparation.cpp84
-rw-r--r--polly/lib/Transform/DeLICM.cpp166
-rw-r--r--polly/lib/Transform/DeadCodeElimination.cpp59
-rw-r--r--polly/lib/Transform/FlattenSchedule.cpp140
-rw-r--r--polly/lib/Transform/ForwardOpTree.cpp159
-rw-r--r--polly/lib/Transform/MatmulOptimizer.cpp1
-rw-r--r--polly/lib/Transform/MaximalStaticExpansion.cpp109
-rw-r--r--polly/lib/Transform/ScheduleOptimizer.cpp169
-rw-r--r--polly/lib/Transform/ScopInliner.cpp47
-rw-r--r--polly/lib/Transform/Simplify.cpp136
30 files changed, 972 insertions, 2650 deletions
diff --git a/polly/lib/Analysis/DependenceInfo.cpp b/polly/lib/Analysis/DependenceInfo.cpp
index c620f40..0f208ec 100644
--- a/polly/lib/Analysis/DependenceInfo.cpp
+++ b/polly/lib/Analysis/DependenceInfo.cpp
@@ -20,7 +20,6 @@
//===----------------------------------------------------------------------===//
//
#include "polly/DependenceInfo.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
#include "polly/Support/GICHelper.h"
@@ -42,6 +41,10 @@ using namespace llvm;
#include "polly/Support/PollyDebug.h"
#define DEBUG_TYPE "polly-dependence"
+namespace polly {
+Dependences::AnalysisLevel OptAnalysisLevel;
+}
+
static cl::opt<int> OptComputeOut(
"polly-dependences-computeout",
cl::desc("Bound the dependence analysis by a maximal amount of "
@@ -69,9 +72,10 @@ static cl::opt<enum AnalysisType> OptAnalysisType(
"Overapproximation of dependences")),
cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::cat(PollyCategory));
-static cl::opt<Dependences::AnalysisLevel> OptAnalysisLevel(
+static cl::opt<Dependences::AnalysisLevel, true> XOptAnalysisLevel(
"polly-dependences-analysis-level",
cl::desc("The level of dependence analysis"),
+ cl::location(OptAnalysisLevel),
cl::values(clEnumValN(Dependences::AL_Statement, "statement-wise",
"Statement-level analysis"),
clEnumValN(Dependences::AL_Reference, "reference-wise",
@@ -854,240 +858,7 @@ void DependenceAnalysis::Result::abandonDependences() {
Deps.release();
}
-DependenceAnalysis::Result
-DependenceAnalysis::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR) {
- return {S, {}};
-}
-
-AnalysisKey DependenceAnalysis::Key;
-
-PreservedAnalyses
-DependenceInfoPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- auto &DI = SAM.getResult<DependenceAnalysis>(S, SAR);
-
- if (auto d = DI.D[OptAnalysisLevel].get()) {
- d->print(OS);
- return PreservedAnalyses::all();
- }
-
- // Otherwise create the dependences on-the-fly and print them
- Dependences D(S.getSharedIslCtx(), OptAnalysisLevel);
- D.calculateDependences(S);
- D.print(OS);
-
- return PreservedAnalyses::all();
-}
-
-const Dependences &
-DependenceInfo::getDependences(Dependences::AnalysisLevel Level) {
- if (Dependences *d = D[Level].get())
- return *d;
-
- return recomputeDependences(Level);
-}
-
-const Dependences &
-DependenceInfo::recomputeDependences(Dependences::AnalysisLevel Level) {
- D[Level].reset(new Dependences(S->getSharedIslCtx(), Level));
- D[Level]->calculateDependences(*S);
- return *D[Level];
-}
-
-void DependenceInfo::abandonDependences() {
- for (std::unique_ptr<Dependences> &Deps : D)
- Deps.release();
-}
-
-bool DependenceInfo::runOnScop(Scop &ScopVar) {
- S = &ScopVar;
- return false;
-}
-
-/// Print the dependences for the given SCoP to @p OS.
-
-void polly::DependenceInfo::printScop(raw_ostream &OS, Scop &S) const {
- if (auto d = D[OptAnalysisLevel].get()) {
- d->print(OS);
- return;
- }
-
- // Otherwise create the dependences on-the-fly and print it
- Dependences D(S.getSharedIslCtx(), OptAnalysisLevel);
- D.calculateDependences(S);
- D.print(OS);
-}
-
-void DependenceInfo::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredTransitive<ScopInfoRegionPass>();
- AU.setPreservesAll();
+DependenceAnalysis::Result polly::runDependenceAnalysis(Scop &S) {
+ DependenceAnalysis::Result Result{S, {}};
+ return Result;
}
-
-char DependenceInfo::ID = 0;
-
-Pass *polly::createDependenceInfoPass() { return new DependenceInfo(); }
-
-INITIALIZE_PASS_BEGIN(DependenceInfo, "polly-dependences",
- "Polly - Calculate dependences", false, false);
-INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
-INITIALIZE_PASS_END(DependenceInfo, "polly-dependences",
- "Polly - Calculate dependences", false, false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from DependenceAnalysis.
-class DependenceInfoPrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- DependenceInfoPrinterLegacyPass() : DependenceInfoPrinterLegacyPass(outs()) {}
-
- explicit DependenceInfoPrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- DependenceInfo &P = getAnalysis<DependenceInfo>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for "
- << "region: '" << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<DependenceInfo>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char DependenceInfoPrinterLegacyPass::ID = 0;
-} // namespace
-
-Pass *polly::createDependenceInfoPrinterLegacyPass(raw_ostream &OS) {
- return new DependenceInfoPrinterLegacyPass(OS);
-}
-
-INITIALIZE_PASS_BEGIN(DependenceInfoPrinterLegacyPass,
- "polly-print-dependences", "Polly - Print dependences",
- false, false);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
-INITIALIZE_PASS_END(DependenceInfoPrinterLegacyPass, "polly-print-dependences",
- "Polly - Print dependences", false, false)
-
-//===----------------------------------------------------------------------===//
-
-const Dependences &
-DependenceInfoWrapperPass::getDependences(Scop *S,
- Dependences::AnalysisLevel Level) {
- auto It = ScopToDepsMap.find(S);
- if (It != ScopToDepsMap.end())
- if (It->second) {
- if (It->second->getDependenceLevel() == Level)
- return *It->second;
- }
- return recomputeDependences(S, Level);
-}
-
-const Dependences &DependenceInfoWrapperPass::recomputeDependences(
- Scop *S, Dependences::AnalysisLevel Level) {
- std::unique_ptr<Dependences> D(new Dependences(S->getSharedIslCtx(), Level));
- D->calculateDependences(*S);
- auto Inserted = ScopToDepsMap.insert(std::make_pair(S, std::move(D)));
- return *Inserted.first->second;
-}
-
-bool DependenceInfoWrapperPass::runOnFunction(Function &F) {
- auto &SI = *getAnalysis<ScopInfoWrapperPass>().getSI();
- for (auto &It : SI) {
- assert(It.second && "Invalid SCoP object!");
- recomputeDependences(It.second.get(), Dependences::AL_Access);
- }
- return false;
-}
-
-void DependenceInfoWrapperPass::print(raw_ostream &OS, const Module *M) const {
- for (auto &It : ScopToDepsMap) {
- assert((It.first && It.second) && "Invalid Scop or Dependence object!\n");
- It.second->print(OS);
- }
-}
-
-void DependenceInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredTransitive<ScopInfoWrapperPass>();
- AU.setPreservesAll();
-}
-
-char DependenceInfoWrapperPass::ID = 0;
-
-Pass *polly::createDependenceInfoWrapperPassPass() {
- return new DependenceInfoWrapperPass();
-}
-
-INITIALIZE_PASS_BEGIN(
- DependenceInfoWrapperPass, "polly-function-dependences",
- "Polly - Calculate dependences for all the SCoPs of a function", false,
- false)
-INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass);
-INITIALIZE_PASS_END(
- DependenceInfoWrapperPass, "polly-function-dependences",
- "Polly - Calculate dependences for all the SCoPs of a function", false,
- false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from DependenceInfoWrapperPass.
-class DependenceInfoPrinterLegacyFunctionPass final : public FunctionPass {
-public:
- static char ID;
-
- DependenceInfoPrinterLegacyFunctionPass()
- : DependenceInfoPrinterLegacyFunctionPass(outs()) {}
-
- explicit DependenceInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS)
- : FunctionPass(ID), OS(OS) {}
-
- bool runOnFunction(Function &F) override {
- DependenceInfoWrapperPass &P = getAnalysis<DependenceInfoWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for function '"
- << F.getName() << "':\n";
- P.print(OS);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- FunctionPass::getAnalysisUsage(AU);
- AU.addRequired<DependenceInfoWrapperPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char DependenceInfoPrinterLegacyFunctionPass::ID = 0;
-} // namespace
-
-Pass *polly::createDependenceInfoPrinterLegacyFunctionPass(raw_ostream &OS) {
- return new DependenceInfoPrinterLegacyFunctionPass(OS);
-}
-
-INITIALIZE_PASS_BEGIN(
- DependenceInfoPrinterLegacyFunctionPass, "polly-print-function-dependences",
- "Polly - Print dependences for all the SCoPs of a function", false, false);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfoWrapperPass);
-INITIALIZE_PASS_END(DependenceInfoPrinterLegacyFunctionPass,
- "polly-print-function-dependences",
- "Polly - Print dependences for all the SCoPs of a function",
- false, false)
diff --git a/polly/lib/Analysis/PruneUnprofitable.cpp b/polly/lib/Analysis/PruneUnprofitable.cpp
index f8469c0..7201d3d1 100644
--- a/polly/lib/Analysis/PruneUnprofitable.cpp
+++ b/polly/lib/Analysis/PruneUnprofitable.cpp
@@ -13,7 +13,6 @@
#include "polly/PruneUnprofitable.h"
#include "polly/ScopDetection.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/Debug.h"
@@ -55,8 +54,9 @@ static void updateStatistics(Scop &S, bool Pruned) {
NumAffineLoops += ScopStats.NumAffineLoops;
}
}
+} // namespace
-static bool runPruneUnprofitable(Scop &S) {
+bool polly::runPruneUnprofitable(Scop &S) {
if (PollyProcessUnprofitable) {
POLLY_DEBUG(
dbgs() << "NOTE: -polly-process-unprofitable active, won't prune "
@@ -78,47 +78,3 @@ static bool runPruneUnprofitable(Scop &S) {
return false;
}
-
-class PruneUnprofitableWrapperPass final : public ScopPass {
-public:
- static char ID;
-
- 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 { return runPruneUnprofitable(S); }
-};
-} // namespace
-
-char PruneUnprofitableWrapperPass::ID;
-
-Pass *polly::createPruneUnprofitableWrapperPass() {
- return new PruneUnprofitableWrapperPass();
-}
-
-INITIALIZE_PASS_BEGIN(PruneUnprofitableWrapperPass, "polly-prune-unprofitable",
- "Polly - Prune unprofitable SCoPs", false, false)
-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;
-}
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 67a4c43..0f96c89 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -56,6 +56,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
+#include <deque>
using namespace llvm;
using namespace polly;
@@ -1463,7 +1464,7 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
return false;
SmallVector<const SCEV *, 4> Subscripts;
- SmallVector<int, 4> Sizes;
+ SmallVector<const SCEV *, 4> Sizes;
getIndexExpressionsFromGEP(SE, GEP, Subscripts, Sizes);
auto *BasePtr = GEP->getOperand(0);
@@ -1475,8 +1476,6 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
if (BasePtr != BasePointer->getValue())
return false;
- std::vector<const SCEV *> SizesSCEV;
-
const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads();
Loop *SurroundingLoop = Stmt->getSurroundingLoop();
@@ -1494,11 +1493,9 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
if (Sizes.empty())
return false;
+ std::vector<const SCEV *> SizesSCEV;
SizesSCEV.push_back(nullptr);
-
- for (auto V : Sizes)
- SizesSCEV.push_back(SE.getSCEV(
- ConstantInt::get(IntegerType::getInt64Ty(BasePtr->getContext()), V)));
+ SizesSCEV.insert(SizesSCEV.end(), Sizes.begin(), Sizes.end());
addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType,
true, Subscripts, SizesSCEV, Val);
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 43ed863..9e0b495 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -44,7 +44,6 @@
//===----------------------------------------------------------------------===//
#include "polly/ScopDetection.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopDetectionDiagnostic.h"
#include "polly/Support/SCEVValidator.h"
@@ -73,10 +72,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
@@ -1983,53 +1979,12 @@ void ScopDetection::verifyAnalysis() {
verifyRegion(*R);
}
-bool ScopDetectionWrapperPass::runOnFunction(Function &F) {
- auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto &RI = getAnalysis<RegionInfoPass>().getRegionInfo();
- auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
-
- Result = std::make_unique<ScopDetection>(DT, SE, LI, RI, AA, ORE);
- Result->detect(F);
- return false;
-}
-
-void ScopDetectionWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<LoopInfoWrapperPass>();
- AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
- // We also need AA and RegionInfo when we are verifying analysis.
- AU.addRequiredTransitive<AAResultsWrapperPass>();
- AU.addRequiredTransitive<RegionInfoPass>();
- AU.setPreservesAll();
-}
-
-void ScopDetectionWrapperPass::print(raw_ostream &OS, const Module *) const {
- for (const Region *R : Result->ValidRegions)
- OS << "Valid Region for Scop: " << R->getNameStr() << '\n';
-
- OS << "\n";
-}
-
-ScopDetectionWrapperPass::ScopDetectionWrapperPass() : FunctionPass(ID) {
- // Disable runtime alias checks if we ignore aliasing all together.
- if (IgnoreAliasing)
- PollyUseRuntimeAliasChecks = false;
-}
-
ScopAnalysis::ScopAnalysis() {
// Disable runtime alias checks if we ignore aliasing all together.
if (IgnoreAliasing)
PollyUseRuntimeAliasChecks = false;
}
-void ScopDetectionWrapperPass::releaseMemory() { Result.reset(); }
-
-char ScopDetectionWrapperPass::ID;
-
AnalysisKey ScopAnalysis::Key;
ScopDetection ScopAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
@@ -2055,66 +2010,3 @@ PreservedAnalyses ScopAnalysisPrinterPass::run(Function &F,
OS << "\n";
return PreservedAnalyses::all();
}
-
-Pass *polly::createScopDetectionWrapperPassPass() {
- return new ScopDetectionWrapperPass();
-}
-
-INITIALIZE_PASS_BEGIN(ScopDetectionWrapperPass, "polly-detect",
- "Polly - Detect static control parts (SCoPs)", false,
- false);
-INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass);
-INITIALIZE_PASS_END(ScopDetectionWrapperPass, "polly-detect",
- "Polly - Detect static control parts (SCoPs)", false, false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from ScopDetectionWrapperPass.
-class ScopDetectionPrinterLegacyPass final : public FunctionPass {
-public:
- static char ID;
-
- ScopDetectionPrinterLegacyPass() : ScopDetectionPrinterLegacyPass(outs()) {}
-
- explicit ScopDetectionPrinterLegacyPass(llvm::raw_ostream &OS)
- : FunctionPass(ID), OS(OS) {}
-
- bool runOnFunction(Function &F) override {
- ScopDetectionWrapperPass &P = getAnalysis<ScopDetectionWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for function '"
- << F.getName() << "':\n";
- P.print(OS);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- FunctionPass::getAnalysisUsage(AU);
- AU.addRequired<ScopDetectionWrapperPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char ScopDetectionPrinterLegacyPass::ID = 0;
-} // namespace
-
-Pass *polly::createScopDetectionPrinterLegacyPass(raw_ostream &OS) {
- return new ScopDetectionPrinterLegacyPass(OS);
-}
-
-INITIALIZE_PASS_BEGIN(ScopDetectionPrinterLegacyPass, "polly-print-detect",
- "Polly - Print static control parts (SCoPs)", false,
- false);
-INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
-INITIALIZE_PASS_END(ScopDetectionPrinterLegacyPass, "polly-print-detect",
- "Polly - Print static control parts (SCoPs)", false, false)
diff --git a/polly/lib/Analysis/ScopGraphPrinter.cpp b/polly/lib/Analysis/ScopGraphPrinter.cpp
index eb6c995..29e2128 100644
--- a/polly/lib/Analysis/ScopGraphPrinter.cpp
+++ b/polly/lib/Analysis/ScopGraphPrinter.cpp
@@ -14,20 +14,26 @@
//===----------------------------------------------------------------------===//
#include "polly/ScopGraphPrinter.h"
-#include "polly/LinkAllPasses.h"
#include "polly/ScopDetection.h"
#include "llvm/Support/CommandLine.h"
using namespace polly;
using namespace llvm;
-static cl::opt<std::string>
- ViewFilter("polly-view-only",
- cl::desc("Only view functions that match this pattern"),
- cl::Hidden, cl::init(""));
-static cl::opt<bool> ViewAll("polly-view-all",
- cl::desc("Also show functions without any scops"),
- cl::Hidden, cl::init(false));
+namespace polly {
+std::string ViewFilter;
+bool ViewAll;
+} // namespace polly
+
+static cl::opt<std::string, true>
+ XViewFilter("polly-view-only",
+ cl::desc("Only view functions that match this pattern"),
+ cl::location(ViewFilter), cl::Hidden, cl::init(""));
+
+static cl::opt<bool, true>
+ XViewAll("polly-view-all",
+ cl::desc("Also show functions without any scops"),
+ cl::location(ViewAll), cl::Hidden, cl::init(false));
namespace llvm {
@@ -134,104 +140,6 @@ void DOTGraphTraits<ScopDetection *>::addCustomGraphFeatures(
} // namespace llvm
-struct ScopDetectionAnalysisGraphTraits {
- static ScopDetection *getGraph(ScopDetectionWrapperPass *Analysis) {
- return &Analysis->getSD();
- }
-};
-
-struct ScopViewerWrapperPass
- : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits> {
- static char ID;
- ScopViewerWrapperPass()
- : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits>(
- "scops", ID) {}
- bool processFunction(Function &F, ScopDetectionWrapperPass &SD) override {
- if (ViewFilter != "" && !F.getName().count(ViewFilter))
- return false;
-
- if (ViewAll)
- return true;
-
- // Check that at least one scop was detected.
- return std::distance(SD.getSD().begin(), SD.getSD().end()) > 0;
- }
-};
-char ScopViewerWrapperPass::ID = 0;
-
-struct ScopOnlyViewerWrapperPass
- : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits> {
- static char ID;
- ScopOnlyViewerWrapperPass()
- : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits>(
- "scopsonly", ID) {}
-};
-char ScopOnlyViewerWrapperPass::ID = 0;
-
-struct ScopPrinterWrapperPass
- : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits> {
- static char ID;
- ScopPrinterWrapperPass()
- : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits>(
- "scops", ID) {}
-};
-char ScopPrinterWrapperPass::ID = 0;
-
-struct ScopOnlyPrinterWrapperPass
- : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits> {
- static char ID;
- ScopOnlyPrinterWrapperPass()
- : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
- ScopDetection *,
- ScopDetectionAnalysisGraphTraits>(
- "scopsonly", ID) {}
-};
-char ScopOnlyPrinterWrapperPass::ID = 0;
-
-static RegisterPass<ScopViewerWrapperPass> X("view-scops",
- "Polly - View Scops of function");
-
-static RegisterPass<ScopOnlyViewerWrapperPass>
- Y("view-scops-only",
- "Polly - View Scops of function (with no function bodies)");
-
-static RegisterPass<ScopPrinterWrapperPass>
- M("dot-scops", "Polly - Print Scops of function");
-
-static RegisterPass<ScopOnlyPrinterWrapperPass>
- N("dot-scops-only",
- "Polly - Print Scops of function (with no function bodies)");
-
-Pass *polly::createDOTViewerWrapperPass() {
- return new ScopViewerWrapperPass();
-}
-
-Pass *polly::createDOTOnlyViewerWrapperPass() {
- return new ScopOnlyViewerWrapperPass();
-}
-
-Pass *polly::createDOTPrinterWrapperPass() {
- return new ScopPrinterWrapperPass();
-}
-
-Pass *polly::createDOTOnlyPrinterWrapperPass() {
- return new ScopOnlyPrinterWrapperPass();
-}
-
bool ScopViewer::processFunction(Function &F, const ScopDetection &SD) {
if (ViewFilter != "" && !F.getName().count(ViewFilter))
return false;
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 8c6a236..bf993a2 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -17,7 +17,6 @@
//===----------------------------------------------------------------------===//
#include "polly/ScopInfo.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopBuilder.h"
#include "polly/ScopDetection.h"
@@ -54,10 +53,8 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -2544,19 +2541,6 @@ raw_ostream &polly::operator<<(raw_ostream &OS, const Scop &scop) {
return OS;
}
-//===----------------------------------------------------------------------===//
-void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<LoopInfoWrapperPass>();
- AU.addRequired<RegionInfoPass>();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
- AU.addRequiredTransitive<ScopDetectionWrapperPass>();
- AU.addRequired<AAResultsWrapperPass>();
- AU.addRequired<AssumptionCacheTracker>();
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
- AU.setPreservesAll();
-}
-
void updateLoopCountStatistic(ScopDetection::LoopStats Stats,
Scop::ScopStatistics ScopStats) {
assert(Stats.NumLoops == ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops);
@@ -2592,112 +2576,6 @@ void updateLoopCountStatistic(ScopDetection::LoopStats Stats,
NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
}
-bool ScopInfoRegionPass::runOnRegion(Region *R, RGPassManager &RGM) {
- auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
-
- if (!SD.isMaxRegionInScop(*R))
- return false;
-
- Function *F = R->getEntry()->getParent();
- auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto const &DL = F->getParent()->getDataLayout();
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*F);
- auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
-
- ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE);
- S = SB.getScop(); // take ownership of scop object
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
- if (S) {
- ScopDetection::LoopStats Stats =
- ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0);
- updateLoopCountStatistic(Stats, S->getStatistics());
- }
-#endif
-
- return false;
-}
-
-void ScopInfoRegionPass::print(raw_ostream &OS, const Module *) const {
- if (S)
- S->print(OS, PollyPrintInstructions);
- else
- OS << "Invalid Scop!\n";
-}
-
-char ScopInfoRegionPass::ID = 0;
-
-Pass *polly::createScopInfoRegionPassPass() { return new ScopInfoRegionPass(); }
-
-INITIALIZE_PASS_BEGIN(ScopInfoRegionPass, "polly-scops",
- "Polly - Create polyhedral description of Scops", false,
- false);
-INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
-INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
-INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops",
- "Polly - Create polyhedral description of Scops", false,
- false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-/// Print result from ScopInfoRegionPass.
-class ScopInfoPrinterLegacyRegionPass final : public RegionPass {
-public:
- static char ID;
-
- ScopInfoPrinterLegacyRegionPass() : ScopInfoPrinterLegacyRegionPass(outs()) {}
-
- explicit ScopInfoPrinterLegacyRegionPass(llvm::raw_ostream &OS)
- : RegionPass(ID), OS(OS) {}
-
- bool runOnRegion(Region *R, RGPassManager &RGM) override {
- ScopInfoRegionPass &P = getAnalysis<ScopInfoRegionPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << R->getNameStr() << "' in function '"
- << R->getEntry()->getParent()->getName() << "':\n";
- P.print(OS);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- RegionPass::getAnalysisUsage(AU);
- AU.addRequired<ScopInfoRegionPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char ScopInfoPrinterLegacyRegionPass::ID = 0;
-} // namespace
-
-Pass *polly::createScopInfoPrinterLegacyRegionPass(raw_ostream &OS) {
- return new ScopInfoPrinterLegacyRegionPass(OS);
-}
-
-INITIALIZE_PASS_BEGIN(ScopInfoPrinterLegacyRegionPass, "polly-print-scops",
- "Polly - Print polyhedral description of Scops", false,
- false);
-INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
-INITIALIZE_PASS_END(ScopInfoPrinterLegacyRegionPass, "polly-print-scops",
- "Polly - Print polyhedral description of Scops", false,
- false)
-
-//===----------------------------------------------------------------------===//
-
ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE,
LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT,
AssumptionCache &AC, OptimizationRemarkEmitter &ORE)
@@ -2771,110 +2649,3 @@ PreservedAnalyses ScopInfoPrinterPass::run(Function &F,
}
return PreservedAnalyses::all();
}
-
-void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<LoopInfoWrapperPass>();
- AU.addRequired<RegionInfoPass>();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
- AU.addRequiredTransitive<ScopDetectionWrapperPass>();
- AU.addRequired<AAResultsWrapperPass>();
- AU.addRequired<AssumptionCacheTracker>();
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
- AU.setPreservesAll();
-}
-
-bool ScopInfoWrapperPass::runOnFunction(Function &F) {
- auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
- auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto const &DL = F.getParent()->getDataLayout();
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
-
- Result.reset(new ScopInfo{DL, SD, SE, LI, AA, DT, AC, ORE});
- return false;
-}
-
-void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const {
- for (auto &It : *Result) {
- if (It.second)
- It.second->print(OS, PollyPrintInstructions);
- else
- OS << "Invalid Scop!\n";
- }
-}
-
-char ScopInfoWrapperPass::ID = 0;
-
-Pass *polly::createScopInfoWrapperPassPass() {
- return new ScopInfoWrapperPass();
-}
-
-INITIALIZE_PASS_BEGIN(
- ScopInfoWrapperPass, "polly-function-scops",
- "Polly - Create polyhedral description of all Scops of a function", false,
- false);
-INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
-INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
-INITIALIZE_PASS_END(
- ScopInfoWrapperPass, "polly-function-scops",
- "Polly - Create polyhedral description of all Scops of a function", false,
- false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from ScopInfoWrapperPass.
-class ScopInfoPrinterLegacyFunctionPass final : public FunctionPass {
-public:
- static char ID;
-
- ScopInfoPrinterLegacyFunctionPass()
- : ScopInfoPrinterLegacyFunctionPass(outs()) {}
- explicit ScopInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS)
- : FunctionPass(ID), OS(OS) {}
-
- bool runOnFunction(Function &F) override {
- ScopInfoWrapperPass &P = getAnalysis<ScopInfoWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for function '"
- << F.getName() << "':\n";
- P.print(OS);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- FunctionPass::getAnalysisUsage(AU);
- AU.addRequired<ScopInfoWrapperPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char ScopInfoPrinterLegacyFunctionPass::ID = 0;
-} // namespace
-
-Pass *polly::createScopInfoPrinterLegacyFunctionPass(raw_ostream &OS) {
- return new ScopInfoPrinterLegacyFunctionPass(OS);
-}
-
-INITIALIZE_PASS_BEGIN(
- ScopInfoPrinterLegacyFunctionPass, "polly-print-function-scops",
- "Polly - Print polyhedral description of all Scops of a function", false,
- false);
-INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass);
-INITIALIZE_PASS_END(
- ScopInfoPrinterLegacyFunctionPass, "polly-print-function-scops",
- "Polly - Print polyhedral description of all Scops of a function", false,
- false)
diff --git a/polly/lib/Analysis/ScopPass.cpp b/polly/lib/Analysis/ScopPass.cpp
deleted file mode 100644
index 719cd0f..0000000
--- a/polly/lib/Analysis/ScopPass.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-//===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the definitions of the ScopPass members.
-//
-//===----------------------------------------------------------------------===//
-
-#include "polly/ScopPass.h"
-#include "polly/ScopInfo.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
-#include "llvm/Analysis/LazyBranchProbabilityInfo.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include <optional>
-
-using namespace llvm;
-using namespace polly;
-
-bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) {
- S = nullptr;
-
- if (skipRegion(*R))
- return false;
-
- if ((S = getAnalysis<ScopInfoRegionPass>().getScop()))
- return runOnScop(*S);
-
- return false;
-}
-
-void ScopPass::print(raw_ostream &OS, const Module *M) const {
- if (S)
- printScop(OS, *S);
-}
-
-void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<ScopInfoRegionPass>();
-
- AU.addPreserved<AAResultsWrapperPass>();
- AU.addPreserved<BasicAAWrapperPass>();
- AU.addPreserved<LoopInfoWrapperPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- AU.addPreserved<GlobalsAAWrapperPass>();
- AU.addPreserved<ScopDetectionWrapperPass>();
- AU.addPreserved<ScalarEvolutionWrapperPass>();
- AU.addPreserved<SCEVAAWrapperPass>();
- AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
- AU.addPreserved<LazyBlockFrequencyInfoPass>();
- AU.addPreserved<LazyBranchProbabilityInfoPass>();
- AU.addPreserved<RegionInfoPass>();
- AU.addPreserved<ScopInfoRegionPass>();
- AU.addPreserved<TargetTransformInfoWrapperPass>();
-}
-
-namespace polly {
-template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
-}
-
-namespace llvm {
-
-template class PassManager<Scop, ScopAnalysisManager,
- ScopStandardAnalysisResults &, SPMUpdater &>;
-template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
-template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
- ScopStandardAnalysisResults &>;
-
-template <>
-PreservedAnalyses
-PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
- SPMUpdater &>::run(Scop &S, ScopAnalysisManager &AM,
- ScopStandardAnalysisResults &AR, SPMUpdater &U) {
- auto PA = PreservedAnalyses::all();
- for (auto &Pass : Passes) {
- auto PassPA = Pass->run(S, AM, AR, U);
-
- AM.invalidate(S, PassPA);
- PA.intersect(std::move(PassPA));
- }
-
- // All analyses for 'this' Scop have been invalidated above.
- // If ScopPasses affect break other scops they have to propagate this
- // information through the updater
- PA.preserveSet<AllAnalysesOn<Scop>>();
- return PA;
-}
-
-bool ScopAnalysisManagerFunctionProxy::Result::invalidate(
- Function &F, const PreservedAnalyses &PA,
- FunctionAnalysisManager::Invalidator &Inv) {
-
- // First, check whether our ScopInfo is about to be invalidated
- auto PAC = PA.getChecker<ScopAnalysisManagerFunctionProxy>();
- if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
- Inv.invalidate<ScopInfoAnalysis>(F, PA) ||
- Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
- Inv.invalidate<LoopAnalysis>(F, PA) ||
- Inv.invalidate<DominatorTreeAnalysis>(F, PA)) {
-
- // As everything depends on ScopInfo, we must drop all existing results
- for (auto &S : *SI)
- if (auto *scop = S.second.get())
- if (InnerAM)
- InnerAM->clear(*scop, scop->getName());
-
- InnerAM = nullptr;
- return true; // Invalidate the proxy result as well.
- }
-
- bool allPreserved = PA.allAnalysesInSetPreserved<AllAnalysesOn<Scop>>();
-
- // Invalidate all non-preserved analyses
- // Even if all analyses were preserved, we still need to run deferred
- // invalidation
- for (auto &S : *SI) {
- std::optional<PreservedAnalyses> InnerPA;
- auto *scop = S.second.get();
- if (!scop)
- continue;
-
- if (auto *OuterProxy =
- InnerAM->getCachedResult<FunctionAnalysisManagerScopProxy>(*scop)) {
- for (const auto &InvPair : OuterProxy->getOuterInvalidations()) {
- auto *OuterAnalysisID = InvPair.first;
- const auto &InnerAnalysisIDs = InvPair.second;
-
- if (Inv.invalidate(OuterAnalysisID, F, PA)) {
- if (!InnerPA)
- InnerPA = PA;
- for (auto *InnerAnalysisID : InnerAnalysisIDs)
- InnerPA->abandon(InnerAnalysisID);
- }
- }
-
- if (InnerPA) {
- InnerAM->invalidate(*scop, *InnerPA);
- continue;
- }
- }
-
- if (!allPreserved)
- InnerAM->invalidate(*scop, PA);
- }
-
- return false; // This proxy is still valid
-}
-
-template <>
-ScopAnalysisManagerFunctionProxy::Result
-ScopAnalysisManagerFunctionProxy::run(Function &F,
- FunctionAnalysisManager &FAM) {
- return Result(*InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
-}
-} // namespace llvm
-
-namespace polly {
-template <>
-OwningScopAnalysisManagerFunctionProxy::Result
-OwningScopAnalysisManagerFunctionProxy::run(Function &F,
- FunctionAnalysisManager &FAM) {
- return Result(InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
-}
-} // namespace polly
diff --git a/polly/lib/CMakeLists.txt b/polly/lib/CMakeLists.txt
index 0ed6738..7c609fd 100644
--- a/polly/lib/CMakeLists.txt
+++ b/polly/lib/CMakeLists.txt
@@ -48,7 +48,6 @@ add_llvm_pass_plugin(Polly
Analysis/ScopInfo.cpp
Analysis/ScopBuilder.cpp
Analysis/ScopGraphPrinter.cpp
- Analysis/ScopPass.cpp
Analysis/PruneUnprofitable.cpp
CodeGen/BlockGenerators.cpp
${ISL_CODEGEN_FILES}
@@ -60,6 +59,9 @@ add_llvm_pass_plugin(Polly
CodeGen/RuntimeDebugBuilder.cpp
CodeGen/PerfMonitor.cpp
Exchange/JSONExporter.cpp
+ Pass/PhaseManager.cpp
+ Pass/PollyFunctionPass.cpp
+ Pass/PollyModulePass.cpp
Support/GICHelper.cpp
Support/PollyDebug.cpp
Support/SCEVAffinator.cpp
diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp
index 2d8b393..5d2b6363 100644
--- a/polly/lib/CodeGen/CodeGeneration.cpp
+++ b/polly/lib/CodeGen/CodeGeneration.cpp
@@ -25,7 +25,6 @@
#include "polly/CodeGen/PerfMonitor.h"
#include "polly/CodeGen/Utils.h"
#include "polly/DependenceInfo.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
#include "polly/Support/ScopHelper.h"
@@ -35,9 +34,7 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/PassManager.h"
#include "llvm/IR/Verifier.h"
-#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -235,15 +232,6 @@ static bool generateCode(Scop &S, IslAstInfo &AI, LoopInfo &LI,
NodeBuilder.allocateNewArrays(StartExitBlocks);
Annotator.buildAliasScopes(S);
- // The code below annotates the "llvm.loop.vectorize.enable" to false
- // for the code flow taken when RTCs fail. Because we don't want the
- // Loop Vectorizer to come in later and vectorize the original fall back
- // loop when Polly is enabled.
- for (Loop *L : LI.getLoopsInPreorder()) {
- if (S.contains(L))
- addStringMetadataToLoop(L, "llvm.loop.vectorize.enable", 0);
- }
-
if (PerfMonitoring) {
PerfMonitor P(S, EnteringBB->getParent()->getParent());
P.initialize();
@@ -285,6 +273,21 @@ static bool generateCode(Scop &S, IslAstInfo &AI, LoopInfo &LI,
Builder.GetInsertBlock()->getTerminator()->setOperand(0, RTC);
+ auto *CI = dyn_cast<ConstantInt>(RTC);
+ // The code below annotates the "llvm.loop.vectorize.enable" to false
+ // for the code flow taken when RTCs fail. Because we don't want the
+ // Loop Vectorizer to come in later and vectorize the original fall back
+ // loop when Polly is enabled. This avoids loop versioning on fallback
+ // loop by Loop Vectorizer. Don't do this when Polly's RTC value is
+ // false (due to code generation failure), as we are left with only one
+ // version of Loop.
+ if (!(CI && CI->isZero())) {
+ for (Loop *L : LI.getLoopsInPreorder()) {
+ if (S.contains(L))
+ addStringMetadataToLoop(L, "llvm.loop.vectorize.enable", 0);
+ }
+ }
+
// Explicitly set the insert point to the end of the block to avoid that a
// split at the builder's current
// insert position would move the malloc calls to the wrong BasicBlock.
@@ -314,82 +317,6 @@ static bool generateCode(Scop &S, IslAstInfo &AI, LoopInfo &LI,
return true;
}
-namespace {
-
-class CodeGeneration final : public ScopPass {
-public:
- static char ID;
-
- /// The data layout used.
- const DataLayout *DL;
-
- /// @name The analysis passes we need to generate code.
- ///
- ///{
- LoopInfo *LI;
- IslAstInfo *AI;
- DominatorTree *DT;
- ScalarEvolution *SE;
- RegionInfo *RI;
- ///}
-
- CodeGeneration() : ScopPass(ID) {}
-
- /// Generate LLVM-IR for the SCoP @p S.
- bool runOnScop(Scop &S) override {
- AI = &getAnalysis<IslAstInfoWrapperPass>().getAI();
- LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- DL = &S.getFunction().getDataLayout();
- RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
- return generateCode(S, *AI, *LI, *DT, *SE, *RI);
- }
-
- /// Register all analyses and transformation required.
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
-
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<IslAstInfoWrapperPass>();
- AU.addRequired<RegionInfoPass>();
- AU.addRequired<ScalarEvolutionWrapperPass>();
- AU.addRequired<ScopDetectionWrapperPass>();
- AU.addRequired<ScopInfoRegionPass>();
- AU.addRequired<LoopInfoWrapperPass>();
-
- AU.addPreserved<DependenceInfo>();
- AU.addPreserved<IslAstInfoWrapperPass>();
-
- // FIXME: We do not yet add regions for the newly generated code to the
- // region tree.
- }
-};
-} // namespace
-
-PreservedAnalyses CodeGenerationPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &AR,
- SPMUpdater &U) {
- auto &AI = SAM.getResult<IslAstAnalysis>(S, AR);
- if (generateCode(S, AI, AR.LI, AR.DT, AR.SE, AR.RI)) {
- U.invalidateScop(S);
- return PreservedAnalyses::none();
- }
-
- return PreservedAnalyses::all();
+bool polly::runCodeGeneration(Scop &S, RegionInfo &RI, IslAstInfo &AI) {
+ return generateCode(S, AI, *S.getLI(), *S.getDT(), *S.getSE(), RI);
}
-
-char CodeGeneration::ID = 1;
-
-Pass *polly::createCodeGenerationPass() { return new CodeGeneration(); }
-
-INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
- "Polly - Create LLVM-IR from SCoPs", false, false);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
-INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
-INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
- "Polly - Create LLVM-IR from SCoPs", false, false)
diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp
index 09bacda..0ea14ae 100644
--- a/polly/lib/CodeGen/IslAst.cpp
+++ b/polly/lib/CodeGen/IslAst.cpp
@@ -29,11 +29,9 @@
#include "polly/CodeGen/IslAst.h"
#include "polly/CodeGen/CodeGeneration.h"
#include "polly/DependenceInfo.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopDetection.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Support/GICHelper.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
@@ -83,6 +81,11 @@ static cl::opt<bool> DetectParallel("polly-ast-detect-parallel",
cl::desc("Detect parallelism"), cl::Hidden,
cl::cat(PollyCategory));
+static cl::opt<bool>
+ PollyPrintAst("polly-print-ast",
+ cl::desc("Print the ISL abstract syntax tree"),
+ cl::cat(PollyCategory));
+
STATISTIC(ScopsProcessed, "Number of SCoPs processed");
STATISTIC(ScopsBeneficial, "Number of beneficial SCoPs");
STATISTIC(BeneficialAffineLoops, "Number of beneficial affine loops");
@@ -659,15 +662,6 @@ static std::unique_ptr<IslAstInfo> runIslAst(
return Ast;
}
-IslAstInfo IslAstAnalysis::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR) {
- auto GetDeps = [&](Dependences::AnalysisLevel Lvl) -> const Dependences & {
- return SAM.getResult<DependenceAnalysis>(S, SAR).getDependences(Lvl);
- };
-
- return std::move(*runIslAst(S, GetDeps));
-}
-
static __isl_give isl_printer *cbPrintUser(__isl_take isl_printer *P,
__isl_take isl_ast_print_options *O,
__isl_keep isl_ast_node *Node,
@@ -767,99 +761,19 @@ void IslAstInfo::print(raw_ostream &OS) {
isl_printer_free(P);
}
-AnalysisKey IslAstAnalysis::Key;
-PreservedAnalyses IslAstPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- auto &Ast = SAM.getResult<IslAstAnalysis>(S, SAR);
- Ast.print(OS);
- return PreservedAnalyses::all();
-}
-
-void IslAstInfoWrapperPass::releaseMemory() { Ast.reset(); }
-
-bool IslAstInfoWrapperPass::runOnScop(Scop &Scop) {
- auto GetDeps = [this](Dependences::AnalysisLevel Lvl) -> const Dependences & {
- return getAnalysis<DependenceInfo>().getDependences(Lvl);
+std::unique_ptr<IslAstInfo>
+polly::runIslAstGen(Scop &S, DependenceAnalysis::Result &DA) {
+ auto GetDeps = [&](Dependences::AnalysisLevel Lvl) -> const Dependences & {
+ return DA.getDependences(Lvl);
};
- Ast = runIslAst(Scop, GetDeps);
-
- return false;
-}
-
-void IslAstInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
- // Get the Common analysis usage of ScopPasses.
- ScopPass::getAnalysisUsage(AU);
- AU.addRequiredTransitive<ScopInfoRegionPass>();
- AU.addRequired<DependenceInfo>();
-
- AU.addPreserved<DependenceInfo>();
-}
-
-void IslAstInfoWrapperPass::printScop(raw_ostream &OS, Scop &S) const {
- OS << "Printing analysis 'Polly - Generate an AST of the SCoP (isl)'"
- << S.getName() << "' in function '" << S.getFunction().getName() << "':\n";
- if (Ast)
- Ast->print(OS);
-}
-
-char IslAstInfoWrapperPass::ID = 0;
-
-Pass *polly::createIslAstInfoWrapperPassPass() {
- return new IslAstInfoWrapperPass();
-}
-
-INITIALIZE_PASS_BEGIN(IslAstInfoWrapperPass, "polly-ast",
- "Polly - Generate an AST of the SCoP (isl)", false,
- false);
-INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
-INITIALIZE_PASS_END(IslAstInfoWrapperPass, "polly-ast",
- "Polly - Generate an AST from the SCoP (isl)", false, false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from IslAstInfoWrapperPass.
-class IslAstInfoPrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- IslAstInfoPrinterLegacyPass() : IslAstInfoPrinterLegacyPass(outs()) {}
- explicit IslAstInfoPrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- IslAstInfoWrapperPass &P = getAnalysis<IslAstInfoWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
+ std::unique_ptr<IslAstInfo> Result = runIslAst(S, GetDeps);
+ if (PollyPrintAst) {
+ outs() << "Printing analysis 'Polly - Generate an AST of the SCoP (isl)'"
+ << S.getName() << "' in function '" << S.getFunction().getName()
+ << "':\n";
+ if (Result)
+ Result->print(llvm::outs());
}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<IslAstInfoWrapperPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char IslAstInfoPrinterLegacyPass::ID = 0;
-} // namespace
-
-Pass *polly::createIslAstInfoPrinterLegacyPass(raw_ostream &OS) {
- return new IslAstInfoPrinterLegacyPass(OS);
+ return Result;
}
-
-INITIALIZE_PASS_BEGIN(IslAstInfoPrinterLegacyPass, "polly-print-ast",
- "Polly - Print the AST from a SCoP (isl)", false, false);
-INITIALIZE_PASS_DEPENDENCY(IslAstInfoWrapperPass);
-INITIALIZE_PASS_END(IslAstInfoPrinterLegacyPass, "polly-print-ast",
- "Polly - Print the AST from a SCoP (isl)", false, false)
diff --git a/polly/lib/Exchange/JSONExporter.cpp b/polly/lib/Exchange/JSONExporter.cpp
index dfd6314..e392066 100644
--- a/polly/lib/Exchange/JSONExporter.cpp
+++ b/polly/lib/Exchange/JSONExporter.cpp
@@ -12,10 +12,8 @@
#include "polly/JSONExporter.h"
#include "polly/DependenceInfo.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Support/ISLTools.h"
#include "polly/Support/ScopLocation.h"
#include "llvm/ADT/Statistic.h"
@@ -36,6 +34,11 @@ using namespace polly;
#define DEBUG_TYPE "polly-import-jscop"
+static cl::opt<bool>
+ PollyPrintImportJscop("polly-print-import-jscop",
+ cl::desc("Polly - Print Scop import result"),
+ cl::cat(PollyCategory));
+
STATISTIC(NewAccessMapFound, "Number of updated access functions");
namespace {
@@ -50,36 +53,6 @@ static cl::opt<std::string>
cl::desc("Postfix to append to the import .jsop files."),
cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired,
cl::init(""), cl::cat(PollyCategory));
-
-class JSONExporter : public ScopPass {
-public:
- static char ID;
- explicit JSONExporter() : ScopPass(ID) {}
-
- /// Export the SCoP @p S to a JSON file.
- bool runOnScop(Scop &S) override;
-
- /// Print the SCoP @p S as it is exported.
- void printScop(raw_ostream &OS, Scop &S) const override;
-
- /// Register all analyses and transformation required.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-};
-
-class JSONImporter : public ScopPass {
-public:
- static char ID;
- std::vector<std::string> NewAccessStrings;
- explicit JSONImporter() : ScopPass(ID) {}
- /// Import new access functions for SCoP @p S from a JSON file.
- bool runOnScop(Scop &S) override;
-
- /// Print the SCoP @p S and the imported access functions.
- void printScop(raw_ostream &OS, Scop &S) const override;
-
- /// Register all analyses and transformation required.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-};
} // namespace
static std::string getFileName(Scop &S, StringRef Suffix = "") {
@@ -742,140 +715,24 @@ static bool importScop(Scop &S, const Dependences &D, const DataLayout &DL,
return true;
}
-char JSONExporter::ID = 0;
-void JSONExporter::printScop(raw_ostream &OS, Scop &S) const { OS << S; }
-
-bool JSONExporter::runOnScop(Scop &S) {
- exportScop(S);
- return false;
-}
-
-void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<ScopInfoRegionPass>();
-}
-
-Pass *polly::createJSONExporterPass() { return new JSONExporter(); }
-
-PreservedAnalyses JSONExportPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &) {
- exportScop(S);
- return PreservedAnalyses::all();
-}
-
-char JSONImporter::ID = 0;
-
-void JSONImporter::printScop(raw_ostream &OS, Scop &S) const {
- OS << S;
- for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
- E = NewAccessStrings.end();
- I != E; I++)
- OS << "New access function '" << *I << "' detected in JSCOP file\n";
-}
-
-bool JSONImporter::runOnScop(Scop &S) {
- const Dependences &D =
- getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
+void polly::runImportJSON(Scop &S, DependenceAnalysis::Result &DA) {
+ const Dependences &D = DA.getDependences(Dependences::AL_Statement);
const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
-
+ std::vector<std::string> NewAccessStrings;
if (!importScop(S, D, DL, &NewAccessStrings))
report_fatal_error("Tried to import a malformed jscop file.");
- return false;
-}
-
-void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<DependenceInfo>();
-
- // TODO: JSONImporter should throw away DependenceInfo.
- AU.addPreserved<DependenceInfo>();
-}
-
-Pass *polly::createJSONImporterPass() { return new JSONImporter(); }
-
-PreservedAnalyses JSONImportPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &) {
- const Dependences &D =
- SAM.getResult<DependenceAnalysis>(S, SAR).getDependences(
- Dependences::AL_Statement);
- const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
-
- if (!importScop(S, D, DL))
- report_fatal_error("Tried to import a malformed jscop file.");
-
- // This invalidates all analyses on Scop.
- PreservedAnalyses PA;
- PA.preserveSet<AllAnalysesOn<Module>>();
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserveSet<AllAnalysesOn<Loop>>();
- return PA;
-}
-
-INITIALIZE_PASS_BEGIN(JSONExporter, "polly-export-jscop",
- "Polly - Export Scops as JSON"
- " (Writes a .jscop file for each Scop)",
- false, false);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
-INITIALIZE_PASS_END(JSONExporter, "polly-export-jscop",
- "Polly - Export Scops as JSON"
- " (Writes a .jscop file for each Scop)",
- false, false)
-
-INITIALIZE_PASS_BEGIN(JSONImporter, "polly-import-jscop",
- "Polly - Import Scops from JSON"
- " (Reads a .jscop file for each Scop)",
- false, false);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
-INITIALIZE_PASS_END(JSONImporter, "polly-import-jscop",
- "Polly - Import Scops from JSON"
- " (Reads a .jscop file for each Scop)",
- false, false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from JSONImporter.
-class JSONImporterPrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- JSONImporterPrinterLegacyPass() : JSONImporterPrinterLegacyPass(outs()) {}
- explicit JSONImporterPrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- JSONImporter &P = getAnalysis<JSONImporter>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
+ if (PollyPrintImportJscop) {
+ outs()
+ << "Printing analysis 'Polly - Print Scop import result' for region: '"
+ << S.getRegion().getNameStr() << "' in function '"
+ << S.getFunction().getName() << "':\n";
+ outs() << S;
+ for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
+ E = NewAccessStrings.end();
+ I != E; I++)
+ outs() << "New access function '" << *I << "' detected in JSCOP file\n";
}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<JSONImporter>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char JSONImporterPrinterLegacyPass::ID = 0;
-} // namespace
-
-Pass *polly::createJSONImporterPrinterLegacyPass(llvm::raw_ostream &OS) {
- return new JSONImporterPrinterLegacyPass(OS);
}
-INITIALIZE_PASS_BEGIN(JSONImporterPrinterLegacyPass, "polly-print-import-jscop",
- "Polly - Print Scop import result", false, false)
-INITIALIZE_PASS_DEPENDENCY(JSONImporter)
-INITIALIZE_PASS_END(JSONImporterPrinterLegacyPass, "polly-print-import-jscop",
- "Polly - Print Scop import result", false, false)
+void polly::runExportJSON(Scop &S) { exportScop(S); }
diff --git a/polly/lib/Pass/PhaseManager.cpp b/polly/lib/Pass/PhaseManager.cpp
new file mode 100644
index 0000000..330dfe8
--- /dev/null
+++ b/polly/lib/Pass/PhaseManager.cpp
@@ -0,0 +1,437 @@
+//===------ PhaseManager.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Pass/PhaseManager.h"
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/CodeGen/IslAst.h"
+#include "polly/CodePreparation.h"
+#include "polly/DeLICM.h"
+#include "polly/DeadCodeElimination.h"
+#include "polly/DependenceInfo.h"
+#include "polly/FlattenSchedule.h"
+#include "polly/ForwardOpTree.h"
+#include "polly/JSONExporter.h"
+#include "polly/MaximalStaticExpansion.h"
+#include "polly/PruneUnprofitable.h"
+#include "polly/ScheduleOptimizer.h"
+#include "polly/ScopDetection.h"
+#include "polly/ScopDetectionDiagnostic.h"
+#include "polly/ScopGraphPrinter.h"
+#include "polly/ScopInfo.h"
+#include "polly/Simplify.h"
+#include "polly/Support/PollyDebug.h"
+#include "llvm/ADT/PriorityWorklist.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/Module.h"
+
+#define DEBUG_TYPE "polly-pass"
+
+using namespace polly;
+using namespace llvm;
+
+namespace {
+
+/// Recurse through all subregions and all regions and add them to RQ.
+static void addRegionIntoQueue(Region &R, SmallVector<Region *> &RQ) {
+ RQ.push_back(&R);
+ for (const auto &E : R)
+ addRegionIntoQueue(*E, RQ);
+}
+
+/// The phase pipeline of Polly to be embedded into another pass manager than
+/// runs passes on functions.
+///
+/// Polly holds state besides LLVM-IR (RegionInfo and ScopInfo) between phases
+/// that LLVM pass managers do not consider when scheduling analyses and passes.
+/// That is, the ScopInfo must persist between phases that a pass manager must
+/// not invalidate to recompute later.
+class PhaseManager {
+private:
+ Function &F;
+ FunctionAnalysisManager &FAM;
+ PollyPassOptions Opts;
+
+public:
+ PhaseManager(Function &F, FunctionAnalysisManager &FAM, PollyPassOptions Opts)
+ : F(F), FAM(FAM), Opts(std::move(Opts)) {}
+
+ /// Execute Polly's phases as indicated by the options.
+ bool run() {
+ // Get analyses from the function pass manager.
+ // These must be preserved during all phases so that if processing one SCoP
+ // has finished, the next SCoP can still use them. Recomputing is not an
+ // option because ScopDetection stores references to the old results.
+ // TODO: CodePreparation doesn't actually need these analysis, it just keeps
+ // them up-to-date. If they are not computed yet, can also compute after the
+ // prepare phase.
+ LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
+ DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
+ bool ModifiedIR = false;
+
+ // Phase: prepare
+ // TODO: Setting ModifiedIR will invalidate any analysis, even if DT, LI are
+ // preserved.
+ if (Opts.isPhaseEnabled(PassPhase::Prepare)) {
+ if (runCodePreparation(F, &DT, &LI, nullptr)) {
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<LoopAnalysis>();
+ FAM.invalidate(F, PA);
+ ModifiedIR = true;
+ }
+ }
+
+ // Can't do anything without detection
+ if (!Opts.isPhaseEnabled(PassPhase::Detection))
+ return false;
+
+ AAResults &AA = FAM.getResult<AAManager>(F);
+ ScalarEvolution &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
+ OptimizationRemarkEmitter &ORE =
+ FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
+
+ // ScopDetection is modifying RegionInfo, do not cache it, nor use a cached
+ // version.
+ RegionInfo RI = RegionInfoAnalysis().run(F, FAM);
+
+ // Phase: detection
+ ScopDetection SD(DT, SE, LI, RI, AA, ORE);
+ SD.detect(F);
+ if (Opts.isPhaseEnabled(PassPhase::PrintDetect)) {
+ outs() << "Detected Scops in Function " << F.getName() << "\n";
+ for (const Region *R : SD.ValidRegions)
+ outs() << "Valid Region for Scop: " << R->getNameStr() << '\n';
+ outs() << "\n";
+ }
+
+ if (Opts.isPhaseEnabled(PassPhase::DotScops))
+ printGraphForFunction(F, &SD, "scops", false);
+ if (Opts.isPhaseEnabled(PassPhase::DotScopsOnly))
+ printGraphForFunction(F, &SD, "scopsonly", true);
+
+ auto ViewScops = [&](const char *Name, bool IsSimply) {
+ if (Opts.ViewFilter.empty() && !F.getName().count(Opts.ViewFilter))
+ return;
+
+ if (Opts.ViewAll || std::distance(SD.begin(), SD.end()) > 0)
+ viewGraphForFunction(F, &SD, Name, IsSimply);
+ };
+ if (Opts.isPhaseEnabled(PassPhase::ViewScops))
+ ViewScops("scops", false);
+ if (Opts.isPhaseEnabled(PassPhase::ViewScopsOnly))
+ ViewScops("scopsonly", true);
+
+ // Phase: scops
+ AssumptionCache &AC = FAM.getResult<AssumptionAnalysis>(F);
+ const DataLayout &DL = F.getParent()->getDataLayout();
+ ScopInfo Info(DL, SD, SE, LI, AA, DT, AC, ORE);
+ if (Opts.isPhaseEnabled(PassPhase::PrintScopInfo)) {
+ if (Region *TLR = RI.getTopLevelRegion()) {
+ SmallVector<Region *> Regions;
+ addRegionIntoQueue(*TLR, Regions);
+
+ // reverse iteration because the regression tests expect it.
+ for (Region *R : reverse(Regions)) {
+ Scop *S = Info.getScop(R);
+ outs() << "Printing analysis 'Polly - Create polyhedral "
+ "description of Scops' for region: '"
+ << R->getNameStr() << "' in function '" << F.getName()
+ << "':\n";
+ if (S)
+ outs() << *S;
+ else
+ outs() << "Invalid Scop!\n";
+ }
+ }
+ }
+
+ SmallPriorityWorklist<Region *, 4> Worklist;
+ for (auto &[R, S] : Info)
+ if (S)
+ Worklist.insert(R);
+
+ TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
+ while (!Worklist.empty()) {
+ Region *R = Worklist.pop_back_val();
+ Scop *S = Info.getScop(R);
+ if (!S) {
+ // This can happen if codegenning of a previous SCoP made this region
+ // not-a-SCoP anymore.
+ POLLY_DEBUG(dbgs() << "SCoP in Region '" << *R << "' disappeared");
+ continue;
+ }
+
+ if (!SD.isMaxRegionInScop(*R, /*Verify=*/false))
+ continue;
+
+ // Phase: flatten
+ if (Opts.isPhaseEnabled(PassPhase::Flatten))
+ runFlattenSchedulePass(*S);
+
+ // Phase: deps
+ // Actual analysis runs on-demand, so it does not matter whether the phase
+ // is actually enabled, but use this location to print dependencies.
+ DependenceAnalysis::Result DA = runDependenceAnalysis(*S);
+ if (Opts.isPhaseEnabled(PassPhase::PrintDependences)) {
+ assert(Opts.isPhaseEnabled(PassPhase::Dependences));
+ const Dependences &D = DA.getDependences(Opts.PrintDepsAnalysisLevel);
+ D.print(outs());
+ }
+
+ // Phase: import-jscop
+ if (Opts.isPhaseEnabled(PassPhase::ImportJScop))
+ runImportJSON(*S, DA);
+
+ // Phase: simplify-0
+ bool ModifiedSinceSimplify = true;
+ if (Opts.isPhaseEnabled(PassPhase::Simplify0)) {
+ runSimplify(*S, 0);
+ ModifiedSinceSimplify = false;
+ }
+
+ // Phase: optree
+ if (Opts.isPhaseEnabled(PassPhase::Optree)) {
+ bool ModifiedByOptree = runForwardOpTree(*S);
+ ModifiedSinceSimplify |= ModifiedByOptree;
+ }
+
+ // Phase: delicm
+ if (Opts.isPhaseEnabled(PassPhase::DeLICM)) {
+ bool ModifiedByDelicm = runDeLICM(*S);
+ ModifiedSinceSimplify |= ModifiedByDelicm;
+ }
+
+ // Phase: simplify-1
+ // If we have already run simplify-0, do not re-run it if the SCoP has not
+ // changed since then.
+ if (ModifiedSinceSimplify && Opts.isPhaseEnabled(PassPhase::Simplify1)) {
+ runSimplify(*S, 1);
+ ModifiedSinceSimplify = false;
+ }
+
+ // Phase: dce
+ if (Opts.isPhaseEnabled(PassPhase::DeadCodeElimination))
+ runDeadCodeElim(*S, DA);
+
+ // Phase: mse
+ if (Opts.isPhaseEnabled(PassPhase::MaximumStaticExtension))
+ runMaximalStaticExpansion(*S, DA);
+
+ // Phase: prune
+ if (Opts.isPhaseEnabled(PassPhase::PruneUnprofitable))
+ runPruneUnprofitable(*S);
+
+ // Phase: opt-isl
+ if (Opts.isPhaseEnabled(PassPhase::Optimization))
+ runIslScheduleOptimizer(*S, &TTI, DA);
+
+ // Phase: import-jscop
+ if (Opts.isPhaseEnabled(PassPhase::ExportJScop))
+ runExportJSON(*S);
+
+ // Phase: ast
+ // Cannot run codegen unless ast is enabled
+ if (!Opts.isPhaseEnabled(PassPhase::AstGen))
+ continue;
+ std::unique_ptr<IslAstInfo> IslAst = runIslAstGen(*S, DA);
+
+ // Phase: codegen
+ if (!Opts.isPhaseEnabled(PassPhase::CodeGen))
+ continue;
+ bool ModifiedByCodeGen = runCodeGeneration(*S, RI, *IslAst);
+ if (ModifiedByCodeGen) {
+ ModifiedIR = true;
+
+ // For all regions, create new polly::Scop objects because the old ones
+ // refere to invalidated LLVM-IR.
+ // FIXME: Adds all SCoPs again to statistics
+ Info.recompute();
+ }
+ }
+
+ return ModifiedIR;
+ }
+};
+} // namespace
+
+StringRef polly::getPhaseName(PassPhase Phase) {
+ switch (Phase) {
+ case PassPhase::Prepare:
+ return "prepare";
+ case PassPhase::Detection:
+ return "detect";
+ case PassPhase::PrintDetect:
+ return "print-detect";
+ case PassPhase::DotScops:
+ return "dot-scops";
+ case PassPhase::DotScopsOnly:
+ return "dot-scops-only";
+ case PassPhase::ViewScops:
+ return "view-scops";
+ case PassPhase::ViewScopsOnly:
+ return "view-scops-only";
+ case PassPhase::ScopInfo:
+ return "scops";
+ case PassPhase::PrintScopInfo:
+ return "print-scops";
+ case PassPhase::Flatten:
+ return "flatten";
+ case PassPhase::Dependences:
+ return "deps";
+ case PassPhase::PrintDependences:
+ return "print-deps";
+ case PassPhase::ImportJScop:
+ return "import-jscop";
+ case PassPhase::Simplify0:
+ return "simplify-0";
+ case PassPhase::Optree:
+ return "optree";
+ case PassPhase::DeLICM:
+ return "delicm";
+ case PassPhase::Simplify1:
+ return "simplify-1";
+ case PassPhase::DeadCodeElimination:
+ return "dce";
+ case PassPhase::MaximumStaticExtension:
+ return "mse";
+ case PassPhase::PruneUnprofitable:
+ return "prune";
+ case PassPhase::Optimization:
+ return "opt-isl"; // "opt" would conflict with the llvm executable
+ case PassPhase::ExportJScop:
+ return "export-jscop";
+ case PassPhase::AstGen:
+ return "ast";
+ case PassPhase::CodeGen:
+ return "codegen";
+ default:
+ llvm_unreachable("Unexpected phase");
+ }
+}
+
+PassPhase polly::parsePhase(StringRef Name) {
+ return StringSwitch<PassPhase>(Name)
+ .Case("prepare", PassPhase::Prepare)
+ .Case("detect", PassPhase::Detection)
+ .Case("print-detect", PassPhase::PrintDetect)
+ .Case("dot-scops", PassPhase::DotScops)
+ .Case("dot-scops-only", PassPhase::DotScopsOnly)
+ .Case("view-scops", PassPhase::ViewScops)
+ .Case("view-scops-only", PassPhase::ViewScopsOnly)
+ .Case("scops", PassPhase::ScopInfo)
+ .Case("print-scops", PassPhase::PrintScopInfo)
+ .Case("flatten", PassPhase::Flatten)
+ .Case("deps", PassPhase::Dependences)
+ .Case("print-deps", PassPhase::PrintDependences)
+ .Case("import-jscop", PassPhase::ImportJScop)
+ .Case("simplify-0", PassPhase::Simplify0)
+ .Case("optree", PassPhase::Optree)
+ .Case("delicm", PassPhase::DeLICM)
+ .Case("simplify-1", PassPhase::Simplify1)
+ .Case("dce", PassPhase::DeadCodeElimination)
+ .Case("mse", PassPhase::MaximumStaticExtension)
+ .Case("prune", PassPhase::PruneUnprofitable)
+ .Case("opt-isl", PassPhase::Optimization)
+ .Case("export-jscop", PassPhase::ExportJScop)
+ .Case("ast", PassPhase::AstGen)
+ .Case("codegen", PassPhase::CodeGen)
+ .Default(PassPhase::None);
+}
+
+bool polly::dependsOnDependenceInfo(PassPhase Phase) {
+ // Nothing before dep phase can depend on it
+ if (static_cast<size_t>(Phase) <= static_cast<size_t>(PassPhase::Dependences))
+ return false;
+
+ switch (Phase) {
+ case PassPhase::Simplify0:
+ case PassPhase::Optree:
+ case PassPhase::DeLICM:
+ case PassPhase::Simplify1:
+ case PassPhase::PruneUnprofitable:
+ case PassPhase::ImportJScop:
+ case PassPhase::ExportJScop:
+ case PassPhase::AstGen: // transitively through codegen
+ case PassPhase::CodeGen:
+ return false;
+ default:
+ return true;
+ }
+}
+
+void PollyPassOptions::enableEnd2End() {
+ setPhaseEnabled(PassPhase::Detection);
+ setPhaseEnabled(PassPhase::ScopInfo);
+ setPhaseEnabled(PassPhase::Dependences);
+ setPhaseEnabled(PassPhase::AstGen);
+ setPhaseEnabled(PassPhase::CodeGen);
+}
+
+void PollyPassOptions::enableDefaultOpts() {
+ setPhaseEnabled(PassPhase::Prepare);
+ setPhaseEnabled(PassPhase::Simplify0);
+ setPhaseEnabled(PassPhase::Optree);
+ setPhaseEnabled(PassPhase::DeLICM);
+ setPhaseEnabled(PassPhase::Simplify1);
+ setPhaseEnabled(PassPhase::PruneUnprofitable);
+ setPhaseEnabled(PassPhase::Optimization);
+}
+
+void PollyPassOptions::disableAfter(PassPhase Phase) {
+ assert(Phase != PassPhase::None);
+ for (PassPhase P : enum_seq_inclusive(Phase, PassPhase::PassPhaseLast)) {
+ if (P == Phase)
+ continue;
+ setPhaseEnabled(P, false);
+ }
+}
+
+Error PollyPassOptions::checkConsistency() const {
+ for (PassPhase P : enum_seq_inclusive(PassPhase::PassPhaseFirst,
+ PassPhase::PassPhaseLast)) {
+ if (!isPhaseEnabled(P))
+ continue;
+
+ // Prepare and Detection have no requirements
+ if (P == PassPhase::Prepare || P == PassPhase::Detection)
+ continue;
+
+ if (!isPhaseEnabled(PassPhase::Detection))
+ return make_error<StringError>(
+ formatv("'{0}' requires 'detect' to be enabled", getPhaseName(P))
+ .str(),
+ inconvertibleErrorCode());
+
+ if (static_cast<size_t>(P) < static_cast<size_t>(PassPhase::ScopInfo))
+ continue;
+
+ if (!isPhaseEnabled(PassPhase::ScopInfo))
+ return make_error<StringError>(
+ formatv("'{0}' requires 'scops' to be enabled", getPhaseName(P))
+ .str(),
+ inconvertibleErrorCode());
+
+ if (dependsOnDependenceInfo(P) && !isPhaseEnabled(PassPhase::Dependences))
+ return make_error<StringError>(
+ formatv("'{0}' requires 'deps' to be enabled", getPhaseName(P)).str(),
+ inconvertibleErrorCode());
+ }
+
+ if (isPhaseEnabled(PassPhase::CodeGen) && !isPhaseEnabled(PassPhase::AstGen))
+ return make_error<StringError>("'codegen' requires 'ast' to be enabled",
+ inconvertibleErrorCode());
+
+ return Error::success();
+}
+
+bool polly::runPollyPass(Function &F, FunctionAnalysisManager &FAM,
+ PollyPassOptions Opts) {
+ return PhaseManager(F, FAM, std::move(Opts)).run();
+}
diff --git a/polly/lib/Pass/PollyFunctionPass.cpp b/polly/lib/Pass/PollyFunctionPass.cpp
new file mode 100644
index 0000000..a478e4d
--- /dev/null
+++ b/polly/lib/Pass/PollyFunctionPass.cpp
@@ -0,0 +1,22 @@
+//===------ PollyFunctionPass.cpp - Polly function pass ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Pass/PollyFunctionPass.h"
+
+using namespace llvm;
+using namespace polly;
+
+PreservedAnalyses PollyFunctionPass::run(llvm::Function &F,
+ llvm::FunctionAnalysisManager &FAM) {
+ bool ModifiedIR = runPollyPass(F, FAM, Opts);
+
+ // Be conservative about preserved analyses.
+ // FIXME: May also need to invalidate/update Module/CGSCC passes, but cannot
+ // reach them within a FunctionPassManager.
+ return ModifiedIR ? PreservedAnalyses::none() : PreservedAnalyses::all();
+}
diff --git a/polly/lib/Pass/PollyModulePass.cpp b/polly/lib/Pass/PollyModulePass.cpp
new file mode 100644
index 0000000..f56ee67
--- /dev/null
+++ b/polly/lib/Pass/PollyModulePass.cpp
@@ -0,0 +1,29 @@
+//===------ PollyModulePass.cpp - Polly module pass ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Pass/PollyModulePass.h"
+#include "llvm/IR/Module.h"
+
+using namespace llvm;
+using namespace polly;
+
+PreservedAnalyses PollyModulePass::run(llvm::Module &M,
+ llvm::ModuleAnalysisManager &MAM) {
+ FunctionAnalysisManager &FAM =
+ MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+
+ bool ModifiedAnyIR = false;
+ for (Function &F : M) {
+ bool LocalModifiedIR = runPollyPass(F, FAM, Opts);
+ ModifiedAnyIR |= LocalModifiedIR;
+ }
+
+ // Be conservative about preserved analyses, especially if parallel functions
+ // have been outlined.
+ return ModifiedAnyIR ? PreservedAnalyses::none() : PreservedAnalyses::all();
+}
diff --git a/polly/lib/Support/DumpFunctionPass.cpp b/polly/lib/Support/DumpFunctionPass.cpp
index e47b7fe..9565e21 100644
--- a/polly/lib/Support/DumpFunctionPass.cpp
+++ b/polly/lib/Support/DumpFunctionPass.cpp
@@ -13,7 +13,6 @@
#include "polly/Support/DumpFunctionPass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassInstrumentation.h"
-#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@@ -82,50 +81,10 @@ static void runDumpFunction(llvm::Function &F, StringRef Suffix) {
Out->keep();
LLVM_DEBUG(dbgs() << "Dump file " << Dumpfile << " written successfully\n");
}
-
-class DumpFunctionWrapperPass final : public FunctionPass {
-private:
- DumpFunctionWrapperPass(const DumpFunctionWrapperPass &) = delete;
- const DumpFunctionWrapperPass &
- operator=(const DumpFunctionWrapperPass &) = delete;
-
- std::string Suffix;
-
-public:
- static char ID;
-
- explicit DumpFunctionWrapperPass() : FunctionPass(ID), Suffix("-dump") {}
-
- explicit DumpFunctionWrapperPass(std::string Suffix)
- : FunctionPass(ID), Suffix(std::move(Suffix)) {}
-
- /// @name FunctionPass interface
- //@{
- void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
-
- bool runOnFunction(llvm::Function &F) override {
- runDumpFunction(F, Suffix);
- return false;
- }
- //@}
-};
-
-char DumpFunctionWrapperPass::ID;
} // namespace
-FunctionPass *polly::createDumpFunctionWrapperPass(std::string Suffix) {
- return new DumpFunctionWrapperPass(std::move(Suffix));
-}
-
llvm::PreservedAnalyses DumpFunctionPass::run(Function &F,
FunctionAnalysisManager &AM) {
runDumpFunction(F, Suffix);
return PreservedAnalyses::all();
}
-
-INITIALIZE_PASS_BEGIN(DumpFunctionWrapperPass, "polly-dump-function",
- "Polly - Dump Function", false, false)
-INITIALIZE_PASS_END(DumpFunctionWrapperPass, "polly-dump-function",
- "Polly - Dump Function", false, false)
diff --git a/polly/lib/Support/DumpModulePass.cpp b/polly/lib/Support/DumpModulePass.cpp
index c1c27ef..2eaa070 100644
--- a/polly/lib/Support/DumpModulePass.cpp
+++ b/polly/lib/Support/DumpModulePass.cpp
@@ -12,7 +12,6 @@
#include "polly/Support/DumpModulePass.h"
#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@@ -47,56 +46,10 @@ static void runDumpModule(llvm::Module &M, StringRef Filename, bool IsSuffix) {
M.print(Out->os(), nullptr);
Out->keep();
}
-
-class DumpModuleWrapperPass final : public ModulePass {
-private:
- DumpModuleWrapperPass(const DumpModuleWrapperPass &) = delete;
- const DumpModuleWrapperPass &
- operator=(const DumpModuleWrapperPass &) = delete;
-
- std::string Filename;
- bool IsSuffix;
-
-public:
- static char ID;
-
- /// This constructor is used e.g. if using opt -polly-dump-module.
- ///
- /// Provide a default suffix to not overwrite the original file.
- explicit DumpModuleWrapperPass()
- : ModulePass(ID), Filename("-dump"), IsSuffix(true) {}
-
- explicit DumpModuleWrapperPass(std::string Filename, bool IsSuffix)
- : ModulePass(ID), Filename(std::move(Filename)), IsSuffix(IsSuffix) {}
-
- /// @name ModulePass interface
- //@{
- void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
-
- bool runOnModule(llvm::Module &M) override {
- runDumpModule(M, Filename, IsSuffix);
- return false;
- }
- //@}
-};
-
-char DumpModuleWrapperPass::ID;
} // namespace
-ModulePass *polly::createDumpModuleWrapperPass(std::string Filename,
- bool IsSuffix) {
- return new DumpModuleWrapperPass(std::move(Filename), IsSuffix);
-}
-
llvm::PreservedAnalyses DumpModulePass::run(llvm::Module &M,
llvm::ModuleAnalysisManager &AM) {
runDumpModule(M, Filename, IsSuffix);
return PreservedAnalyses::all();
}
-
-INITIALIZE_PASS_BEGIN(DumpModuleWrapperPass, "polly-dump-module",
- "Polly - Dump Module", false, false)
-INITIALIZE_PASS_END(DumpModuleWrapperPass, "polly-dump-module",
- "Polly - Dump Module", false, false)
diff --git a/polly/lib/Support/PollyPasses.def b/polly/lib/Support/PollyPasses.def
index 2c792a5..c95ffa3 100644
--- a/polly/lib/Support/PollyPasses.def
+++ b/polly/lib/Support/PollyPasses.def
@@ -1,54 +1,19 @@
+#ifndef MODULE_PASS
+#define MODULE_PASS(NAME, CREATE_PASS, PARSER)
+#endif
+MODULE_PASS("polly", createModuleToFunctionPassAdaptor(PollyFunctionPass(Opts)), parsePollyDefaultOptions)
+MODULE_PASS("polly-custom", createModuleToFunctionPassAdaptor(PollyFunctionPass(Opts)), parsePollyCustomOptions)
+#undef MODULE_PASS
+
#ifndef CGSCC_PASS
#define CGSCC_PASS(NAME, CREATE_PASS, PARSER)
#endif
CGSCC_PASS("polly-inline", ScopInlinerPass(), parseNoOptions)
#undef CGSCC_PASS
-#ifndef FUNCTION_ANALYSIS
-#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
-#endif
-FUNCTION_ANALYSIS("polly-detect", ScopAnalysis())
-FUNCTION_ANALYSIS("polly-function-scops", ScopInfoAnalysis())
-#undef FUNCTION_ANALYSIS
-
#ifndef FUNCTION_PASS
-#define FUNCTION_PASS(NAME, CREATE_PASS)
+#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER)
#endif
-FUNCTION_PASS("polly-prepare", CodePreparationPass())
-FUNCTION_PASS("print<polly-detect>", ScopAnalysisPrinterPass(llvm::errs()))
-FUNCTION_PASS("print<polly-function-scops>", ScopInfoPrinterPass(llvm::errs()))
-FUNCTION_PASS("polly-scop-viewer", ScopViewer())
-FUNCTION_PASS("polly-scop-only-viewer", ScopOnlyViewer())
-FUNCTION_PASS("polly-scop-printer", ScopPrinter())
-FUNCTION_PASS("polly-scop-only-printer", ScopOnlyPrinter())
+FUNCTION_PASS("polly", PollyFunctionPass(Opts), parsePollyDefaultOptions)
+FUNCTION_PASS("polly-custom", PollyFunctionPass(Opts), parsePollyCustomOptions)
#undef FUNCTION_PASS
-
-#ifndef SCOP_ANALYSIS
-#define SCOP_ANALYSIS(NAME, CREATE_PASS)
-#endif
-SCOP_ANALYSIS("pass-instrumentation", llvm::PassInstrumentationAnalysis(PIC))
-SCOP_ANALYSIS("polly-ast", IslAstAnalysis())
-SCOP_ANALYSIS("polly-dependences", DependenceAnalysis())
-#undef SCOP_ANALYSIS
-
-#ifndef SCOP_PASS
-#define SCOP_PASS(NAME, CREATE_PASS)
-#endif
-SCOP_PASS("polly-export-jscop", JSONExportPass())
-SCOP_PASS("polly-import-jscop", JSONImportPass())
-SCOP_PASS("print<polly-ast>", IslAstPrinterPass(llvm::outs()))
-SCOP_PASS("print<polly-dependences>", DependenceInfoPrinterPass(llvm::outs()))
-SCOP_PASS("polly-codegen", CodeGenerationPass())
-SCOP_PASS("polly-simplify", SimplifyPass())
-SCOP_PASS("print<polly-simplify>", SimplifyPrinterPass(llvm::outs()))
-SCOP_PASS("polly-optree", ForwardOpTreePass())
-SCOP_PASS("print<polly-optree>", ForwardOpTreePrinterPass(llvm::outs()))
-SCOP_PASS("polly-delicm", DeLICMPass())
-SCOP_PASS("print<polly-delicm>", DeLICMPrinterPass(llvm::outs()))
-SCOP_PASS("polly-prune-unprofitable", PruneUnprofitablePass())
-SCOP_PASS("polly-opt-isl", IslScheduleOptimizerPass())
-SCOP_PASS("print<polly-opt-isl>", IslScheduleOptimizerPrinterPass(llvm::outs()))
-SCOP_PASS("polly-dce", DeadCodeElimPass())
-SCOP_PASS("polly-mse", MaximalStaticExpansionPass())
-SCOP_PASS("print<polly-mse>", MaximalStaticExpansionPrinterPass(llvm::outs()))
-#undef SCOP_PASS
diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index 04f8715..a430bee 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -28,8 +28,9 @@
#include "polly/DependenceInfo.h"
#include "polly/ForwardOpTree.h"
#include "polly/JSONExporter.h"
-#include "polly/LinkAllPasses.h"
#include "polly/MaximalStaticExpansion.h"
+#include "polly/Options.h"
+#include "polly/Pass/PollyFunctionPass.h"
#include "polly/PruneUnprofitable.h"
#include "polly/ScheduleOptimizer.h"
#include "polly/ScopDetection.h"
@@ -52,6 +53,8 @@
#include "llvm/Transforms/IPO.h"
using namespace llvm;
+using namespace polly;
+
namespace cl = llvm::cl;
using namespace polly;
@@ -201,58 +204,19 @@ static cl::opt<bool> EnablePruneUnprofitable(
cl::desc("Bail out on unprofitable SCoPs before rescheduling"), cl::Hidden,
cl::init(true), cl::cat(PollyCategory));
-namespace {
+static cl::opt<bool>
+ PollyPrintDetect("polly-print-detect",
+ cl::desc("Polly - Print static control parts (SCoPs)"),
+ cl::cat(PollyCategory));
-/// Initialize Polly passes when library is loaded.
-///
-/// We use the constructor of a statically declared object to initialize the
-/// different Polly passes right after the Polly library is loaded. This ensures
-/// that the Polly passes are available e.g. in the 'opt' tool.
-struct StaticInitializer {
- StaticInitializer() {
- llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
- polly::initializePollyPasses(Registry);
- }
-};
-static StaticInitializer InitializeEverything;
-} // end of anonymous namespace.
-
-void initializePollyPasses(llvm::PassRegistry &Registry) {
- initializeCodeGenerationPass(Registry);
-
- initializeCodePreparationPass(Registry);
- initializeDeadCodeElimWrapperPassPass(Registry);
- initializeDependenceInfoPass(Registry);
- initializeDependenceInfoPrinterLegacyPassPass(Registry);
- initializeDependenceInfoWrapperPassPass(Registry);
- initializeDependenceInfoPrinterLegacyFunctionPassPass(Registry);
- initializeJSONExporterPass(Registry);
- initializeJSONImporterPass(Registry);
- initializeJSONImporterPrinterLegacyPassPass(Registry);
- initializeMaximalStaticExpanderWrapperPassPass(Registry);
- initializeIslAstInfoWrapperPassPass(Registry);
- initializeIslAstInfoPrinterLegacyPassPass(Registry);
- initializeIslScheduleOptimizerWrapperPassPass(Registry);
- initializeIslScheduleOptimizerPrinterLegacyPassPass(Registry);
- initializePollyCanonicalizePass(Registry);
- initializeScopDetectionWrapperPassPass(Registry);
- initializeScopDetectionPrinterLegacyPassPass(Registry);
- initializeScopInlinerWrapperPassPass(Registry);
- initializeScopInfoRegionPassPass(Registry);
- initializeScopInfoPrinterLegacyRegionPassPass(Registry);
- initializeScopInfoWrapperPassPass(Registry);
- initializeScopInfoPrinterLegacyFunctionPassPass(Registry);
- initializeFlattenSchedulePass(Registry);
- initializeFlattenSchedulePrinterLegacyPassPass(Registry);
- initializeForwardOpTreeWrapperPassPass(Registry);
- initializeForwardOpTreePrinterLegacyPassPass(Registry);
- initializeDeLICMWrapperPassPass(Registry);
- initializeDeLICMPrinterLegacyPassPass(Registry);
- initializeSimplifyWrapperPassPass(Registry);
- initializeSimplifyPrinterLegacyPassPass(Registry);
- initializeDumpModuleWrapperPassPass(Registry);
- initializePruneUnprofitableWrapperPassPass(Registry);
-}
+static cl::opt<bool>
+ PollyPrintScops("polly-print-scops",
+ cl::desc("Print polyhedral description of all regions"),
+ cl::cat(PollyCategory));
+
+static cl::opt<bool> PollyPrintDeps("polly-print-deps",
+ cl::desc("Polly - Print dependences"),
+ cl::cat(PollyCategory));
static bool shouldEnablePollyForOptimization() { return PollyEnabled; }
@@ -266,6 +230,198 @@ static bool shouldEnablePollyForDiagnostic() {
ExportJScop;
}
+/// Parser of parameters for LoopVectorize pass.
+static llvm::Expected<PollyPassOptions> parsePollyOptions(StringRef Params,
+ bool IsCustom) {
+ PassPhase PrevPhase = PassPhase::None;
+
+ bool EnableDefaultOpts = !IsCustom;
+ bool EnableEnd2End = !IsCustom;
+ std::optional<bool>
+ PassEnabled[static_cast<size_t>(PassPhase::PassPhaseLast) + 1];
+ PassPhase StopAfter = PassPhase::None;
+
+ // Passes enabled using command-line flags (can be overridden using
+ // 'polly<no-pass>')
+ if (PollyPrintDetect)
+ PassEnabled[static_cast<size_t>(PassPhase::PrintDetect)] = true;
+ if (PollyPrintScops)
+ PassEnabled[static_cast<size_t>(PassPhase::PrintScopInfo)] = true;
+ if (PollyPrintDeps)
+ PassEnabled[static_cast<size_t>(PassPhase::PrintDependences)] = true;
+
+ if (PollyViewer)
+ PassEnabled[static_cast<size_t>(PassPhase::ViewScops)] = true;
+ if (PollyOnlyViewer)
+ PassEnabled[static_cast<size_t>(PassPhase::ViewScopsOnly)] = true;
+ if (PollyPrinter)
+ PassEnabled[static_cast<size_t>(PassPhase::DotScops)] = true;
+ if (PollyOnlyPrinter)
+ PassEnabled[static_cast<size_t>(PassPhase::DotScopsOnly)] = true;
+ if (!EnableSimplify)
+ PassEnabled[static_cast<size_t>(PassPhase::Simplify0)] = false;
+ if (!EnableForwardOpTree)
+ PassEnabled[static_cast<size_t>(PassPhase::Optree)] = false;
+ if (!EnableDeLICM)
+ PassEnabled[static_cast<size_t>(PassPhase::DeLICM)] = false;
+ if (!EnableSimplify)
+ PassEnabled[static_cast<size_t>(PassPhase::Simplify1)] = false;
+ if (ImportJScop)
+ PassEnabled[static_cast<size_t>(PassPhase::ImportJScop)] = true;
+ if (DeadCodeElim)
+ PassEnabled[static_cast<size_t>(PassPhase::DeadCodeElimination)] = true;
+ if (FullyIndexedStaticExpansion)
+ PassEnabled[static_cast<size_t>(PassPhase::MaximumStaticExtension)] = true;
+ if (!EnablePruneUnprofitable)
+ PassEnabled[static_cast<size_t>(PassPhase::PruneUnprofitable)] = false;
+ switch (Optimizer) {
+ case OPTIMIZER_NONE:
+ // explicitly switched off
+ PassEnabled[static_cast<size_t>(PassPhase::Optimization)] = false;
+ break;
+ case OPTIMIZER_ISL:
+ // default: enabled
+ break;
+ }
+ if (ExportJScop)
+ PassEnabled[static_cast<size_t>(PassPhase::ExportJScop)] = true;
+ switch (CodeGeneration) {
+ case CODEGEN_AST:
+ PassEnabled[static_cast<size_t>(PassPhase::AstGen)] = true;
+ PassEnabled[static_cast<size_t>(PassPhase::CodeGen)] = false;
+ break;
+ case CODEGEN_FULL:
+ // default: ast and codegen enabled
+ break;
+ case CODEGEN_NONE:
+ PassEnabled[static_cast<size_t>(PassPhase::AstGen)] = false;
+ PassEnabled[static_cast<size_t>(PassPhase::CodeGen)] = false;
+ break;
+ }
+
+ while (!Params.empty()) {
+ StringRef Param;
+ std::tie(Param, Params) = Params.split(';');
+ auto [ParamName, ParamVal] = Param.split('=');
+
+ if (ParamName == "stopafter") {
+ StopAfter = parsePhase(ParamVal);
+ if (StopAfter == PassPhase::None)
+ return make_error<StringError>(
+ formatv("invalid stopafter parameter value '{0}'", ParamVal).str(),
+ inconvertibleErrorCode());
+ continue;
+ }
+
+ if (!ParamVal.empty())
+ return make_error<StringError>(
+ formatv("parameter '{0}' does not take value", ParamName).str(),
+ inconvertibleErrorCode());
+
+ bool Enabled = true;
+ if (ParamName.starts_with("no-")) {
+ Enabled = false;
+ ParamName = ParamName.drop_front(3);
+ }
+
+ if (ParamName == "default-opts") {
+ EnableDefaultOpts = Enabled;
+ continue;
+ }
+
+ if (ParamName == "end2end") {
+ EnableEnd2End = Enabled;
+ continue;
+ }
+
+ PassPhase Phase;
+
+ // Shortcut for both simplifys at the same time
+ if (ParamName == "simplify") {
+ PassEnabled[static_cast<size_t>(PassPhase::Simplify0)] = Enabled;
+ PassEnabled[static_cast<size_t>(PassPhase::Simplify1)] = Enabled;
+ Phase = PassPhase::Simplify0;
+ } else {
+ Phase = parsePhase(ParamName);
+ if (Phase == PassPhase::None)
+ return make_error<StringError>(
+ formatv("invalid Polly parameter/phase name '{0}'", ParamName)
+ .str(),
+ inconvertibleErrorCode());
+
+ if (PrevPhase >= Phase)
+ return make_error<StringError>(
+ formatv("phases must not be repeated and enumerated in-order: "
+ "'{0}' listed before '{1}'",
+ getPhaseName(PrevPhase), getPhaseName(Phase))
+ .str(),
+ inconvertibleErrorCode());
+
+ PassEnabled[static_cast<size_t>(Phase)] = Enabled;
+ }
+ PrevPhase = Phase;
+ }
+
+ PollyPassOptions Opts;
+ Opts.ViewAll = ViewAll;
+ Opts.ViewFilter = ViewFilter;
+ Opts.PrintDepsAnalysisLevel = OptAnalysisLevel;
+
+ // Implicitly enable dependent phases first. May be overriden explicitly
+ // on/off later.
+ for (PassPhase P : llvm::enum_seq_inclusive(PassPhase::PassPhaseFirst,
+ PassPhase::PassPhaseLast)) {
+ bool Enabled = PassEnabled[static_cast<size_t>(P)].value_or(false);
+ if (!Enabled)
+ continue;
+
+ if (static_cast<size_t>(PassPhase::Detection) < static_cast<size_t>(P))
+ Opts.setPhaseEnabled(PassPhase::Detection);
+
+ if (static_cast<size_t>(PassPhase::ScopInfo) < static_cast<size_t>(P))
+ Opts.setPhaseEnabled(PassPhase::ScopInfo);
+
+ if (dependsOnDependenceInfo(P))
+ Opts.setPhaseEnabled(PassPhase::Dependences);
+
+ if (static_cast<size_t>(PassPhase::AstGen) < static_cast<size_t>(P))
+ Opts.setPhaseEnabled(PassPhase::AstGen);
+ }
+
+ if (EnableEnd2End)
+ Opts.enableEnd2End();
+
+ if (EnableDefaultOpts)
+ Opts.enableDefaultOpts();
+
+ for (PassPhase P : llvm::enum_seq_inclusive(PassPhase::PassPhaseFirst,
+ PassPhase::PassPhaseLast)) {
+ std::optional<bool> Enabled = PassEnabled[static_cast<size_t>(P)];
+
+ // Apply only if set explicitly.
+ if (Enabled.has_value())
+ Opts.setPhaseEnabled(P, *Enabled);
+ }
+
+ if (StopAfter != PassPhase::None)
+ Opts.disableAfter(StopAfter);
+
+ if (Error CheckResult = Opts.checkConsistency())
+ return CheckResult;
+
+ return Opts;
+}
+
+static llvm::Expected<PollyPassOptions>
+parsePollyDefaultOptions(StringRef Params) {
+ return parsePollyOptions(Params, false);
+}
+
+static llvm::Expected<PollyPassOptions>
+parsePollyCustomOptions(StringRef Params) {
+ return parsePollyOptions(Params, true);
+}
+
/// Register Polly passes such that they form a polyhedral optimizer.
///
/// The individual Polly passes are registered in the pass manager such that
@@ -305,77 +461,12 @@ static void buildCommonPollyPipeline(FunctionPassManager &PM,
OptimizationLevel Level,
bool EnableForOpt) {
PassBuilder PB;
- ScopPassManager SPM;
- PM.addPass(CodePreparationPass());
+ ExitOnError Err("Inconsistent Polly configuration: ");
+ PollyPassOptions &&Opts =
+ Err(parsePollyOptions(StringRef(), /*IsCustom=*/false));
+ PM.addPass(PollyFunctionPass(Opts));
- // TODO add utility passes for the various command line options, once they're
- // ported
-
- if (PollyDetectOnly) {
- // Don't add more passes other than the ScopPassManager's detection passes.
- PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
- return;
- }
-
- if (PollyViewer)
- PM.addPass(ScopViewer());
- if (PollyOnlyViewer)
- PM.addPass(ScopOnlyViewer());
- if (PollyPrinter)
- PM.addPass(ScopPrinter());
- if (PollyOnlyPrinter)
- PM.addPass(ScopOnlyPrinter());
- if (EnableSimplify)
- SPM.addPass(SimplifyPass(0));
- if (EnableForwardOpTree)
- SPM.addPass(ForwardOpTreePass());
- if (EnableDeLICM)
- SPM.addPass(DeLICMPass());
- if (EnableSimplify)
- SPM.addPass(SimplifyPass(1));
-
- if (ImportJScop)
- SPM.addPass(JSONImportPass());
-
- if (DeadCodeElim)
- SPM.addPass(DeadCodeElimPass());
-
- if (FullyIndexedStaticExpansion)
- SPM.addPass(MaximalStaticExpansionPass());
-
- if (EnablePruneUnprofitable)
- SPM.addPass(PruneUnprofitablePass());
-
- switch (Optimizer) {
- case OPTIMIZER_NONE:
- break; /* Do nothing */
- case OPTIMIZER_ISL:
- SPM.addPass(IslScheduleOptimizerPass());
- break;
- }
-
- if (ExportJScop)
- SPM.addPass(JSONExportPass());
-
- if (!EnableForOpt)
- return;
-
- switch (CodeGeneration) {
- case CODEGEN_AST:
- SPM.addPass(
- llvm::RequireAnalysisPass<IslAstAnalysis, Scop, ScopAnalysisManager,
- ScopStandardAnalysisResults &,
- SPMUpdater &>());
- break;
- case CODEGEN_FULL:
- SPM.addPass(CodeGenerationPass());
- break;
- case CODEGEN_NONE:
- break;
- }
-
- PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
PM.addPass(PB.buildFunctionSimplificationPipeline(
Level, llvm::ThinOrFullLTOPhase::None)); // Cleanup
@@ -448,33 +539,6 @@ static llvm::Expected<std::monostate> parseNoOptions(StringRef Params) {
return std::monostate{};
}
-static OwningScopAnalysisManagerFunctionProxy
-createScopAnalyses(FunctionAnalysisManager &FAM,
- PassInstrumentationCallbacks *PIC) {
- OwningScopAnalysisManagerFunctionProxy Proxy;
-#define SCOP_ANALYSIS(NAME, CREATE_PASS) \
- Proxy.getManager().registerPass([PIC] { \
- (void)PIC; \
- return CREATE_PASS; \
- });
-#include "PollyPasses.def"
-
- Proxy.getManager().registerPass(
- [&FAM] { return FunctionAnalysisManagerScopProxy(FAM); });
- return Proxy;
-}
-
-static void registerFunctionAnalyses(FunctionAnalysisManager &FAM,
- PassInstrumentationCallbacks *PIC) {
-
-#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
- FAM.registerPass([] { return CREATE_PASS; });
-
-#include "PollyPasses.def"
-
- FAM.registerPass([&FAM, PIC] { return createScopAnalyses(FAM, PIC); });
-}
-
static llvm::Expected<bool>
parseCGPipeline(StringRef Name, llvm::CGSCCPassManager &CGPM,
PassInstrumentationCallbacks *PIC,
@@ -492,21 +556,18 @@ parseCGPipeline(StringRef Name, llvm::CGSCCPassManager &CGPM,
return false;
}
-static bool
+static llvm::Expected<bool>
parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
+ PassInstrumentationCallbacks *PIC,
ArrayRef<PassBuilder::PipelineElement> Pipeline) {
- if (llvm::parseAnalysisUtilityPasses<OwningScopAnalysisManagerFunctionProxy>(
- "polly-scop-analyses", Name, FPM))
- return true;
-
-#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
- if (llvm::parseAnalysisUtilityPasses< \
- std::remove_reference<decltype(CREATE_PASS)>::type>(NAME, Name, \
- FPM)) \
- return true;
-
-#define FUNCTION_PASS(NAME, CREATE_PASS) \
- if (Name == NAME) { \
+
+#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER) \
+ if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
+ auto ExpectedOpts = PassBuilder::parsePassParameters(PARSER, Name, NAME); \
+ if (!ExpectedOpts) \
+ return ExpectedOpts.takeError(); \
+ auto &&Opts = *ExpectedOpts; \
+ (void)Opts; \
FPM.addPass(CREATE_PASS); \
return true; \
}
@@ -515,17 +576,18 @@ parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
return false;
}
-static bool parseScopPass(StringRef Name, ScopPassManager &SPM,
- PassInstrumentationCallbacks *PIC) {
-#define SCOP_ANALYSIS(NAME, CREATE_PASS) \
- if (llvm::parseAnalysisUtilityPasses< \
- std::remove_reference<decltype(CREATE_PASS)>::type>(NAME, Name, \
- SPM)) \
- return true;
-
-#define SCOP_PASS(NAME, CREATE_PASS) \
- if (Name == NAME) { \
- SPM.addPass(CREATE_PASS); \
+static llvm::Expected<bool>
+parseModulePipeline(StringRef Name, llvm::ModulePassManager &MPM,
+ PassInstrumentationCallbacks *PIC,
+ ArrayRef<PassBuilder::PipelineElement> Pipeline) {
+#define MODULE_PASS(NAME, CREATE_PASS, PARSER) \
+ if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
+ auto ExpectedOpts = PassBuilder::parsePassParameters(PARSER, Name, NAME); \
+ if (!ExpectedOpts) \
+ return ExpectedOpts.takeError(); \
+ auto &&Opts = *ExpectedOpts; \
+ (void)Opts; \
+ MPM.addPass(CREATE_PASS); \
return true; \
}
@@ -534,64 +596,6 @@ static bool parseScopPass(StringRef Name, ScopPassManager &SPM,
return false;
}
-static bool parseScopPipeline(StringRef Name, FunctionPassManager &FPM,
- PassInstrumentationCallbacks *PIC,
- ArrayRef<PassBuilder::PipelineElement> Pipeline) {
- if (Name != "scop")
- return false;
- if (!Pipeline.empty()) {
- ScopPassManager SPM;
- for (const auto &E : Pipeline)
- if (!parseScopPass(E.Name, SPM, PIC))
- return false;
- FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
- }
- return true;
-}
-
-static bool isScopPassName(StringRef Name) {
-#define SCOP_ANALYSIS(NAME, CREATE_PASS) \
- if (Name == "require<" NAME ">") \
- return true; \
- if (Name == "invalidate<" NAME ">") \
- return true;
-
-#define SCOP_PASS(NAME, CREATE_PASS) \
- if (Name == NAME) \
- return true;
-
-#include "PollyPasses.def"
-
- return false;
-}
-
-static bool
-parseTopLevelPipeline(llvm::ModulePassManager &MPM,
- PassInstrumentationCallbacks *PIC,
- ArrayRef<PassBuilder::PipelineElement> Pipeline) {
- StringRef FirstName = Pipeline.front().Name;
-
- if (!isScopPassName(FirstName))
- return false;
-
- FunctionPassManager FPM;
- ScopPassManager SPM;
-
- for (auto &Element : Pipeline) {
- auto &Name = Element.Name;
- auto &InnerPipeline = Element.InnerPipeline;
- if (!InnerPipeline.empty()) // Scop passes don't have inner pipelines
- return false;
- if (!parseScopPass(Name, SPM, PIC))
- return false;
- }
-
- FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
- MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
-
- return true;
-}
-
/// Register Polly to be available as an optimizer
///
///
@@ -620,14 +624,32 @@ parseTopLevelPipeline(llvm::ModulePassManager &MPM,
/// handle LICMed code to make it useful.
void registerPollyPasses(PassBuilder &PB) {
PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();
- PB.registerAnalysisRegistrationCallback([PIC](FunctionAnalysisManager &FAM) {
- registerFunctionAnalyses(FAM, PIC);
- });
- PB.registerPipelineParsingCallback(parseFunctionPipeline);
+
+#define MODULE_PASS(NAME, CREATE_PASS, PARSER) \
+ { \
+ std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts; \
+ (void)Opts; \
+ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); \
+ }
+#define CGSCC_PASS(NAME, CREATE_PASS, PARSER) \
+ { \
+ std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts; \
+ (void)Opts; \
+ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); \
+ }
+#define FUNCTION_PASS(NAME, CREATE_PASS, PARSER) \
+ { \
+ std::remove_reference_t<decltype(*PARSER(StringRef()))> Opts; \
+ (void)Opts; \
+ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); \
+ }
+#include "PollyPasses.def"
+
PB.registerPipelineParsingCallback(
[PIC](StringRef Name, FunctionPassManager &FPM,
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
- return parseScopPipeline(Name, FPM, PIC, Pipeline);
+ ExitOnError Err("Unable to parse Polly module pass: ");
+ return Err(parseFunctionPipeline(Name, FPM, PIC, Pipeline));
});
PB.registerPipelineParsingCallback(
[PIC](StringRef Name, CGSCCPassManager &CGPM,
@@ -635,10 +657,11 @@ void registerPollyPasses(PassBuilder &PB) {
ExitOnError Err("Unable to parse Polly call graph pass: ");
return Err(parseCGPipeline(Name, CGPM, PIC, Pipeline));
});
- PB.registerParseTopLevelPipelineCallback(
- [PIC](llvm::ModulePassManager &MPM,
+ PB.registerPipelineParsingCallback(
+ [PIC](StringRef Name, ModulePassManager &MPM,
ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
- return parseTopLevelPipeline(MPM, PIC, Pipeline);
+ ExitOnError Err("Unable to parse Polly module pass: ");
+ return Err(parseModulePipeline(Name, MPM, PIC, Pipeline));
});
switch (PassPosition) {
diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp
index a2328d1..cf0ec44 100644
--- a/polly/lib/Support/ScopHelper.cpp
+++ b/polly/lib/Support/ScopHelper.cpp
@@ -206,18 +206,6 @@ void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, DominatorTree *DT,
splitBlock(EntryBlock, I, DT, LI, RI);
}
-void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
- auto *DTWP = P->getAnalysisIfAvailable<DominatorTreeWrapperPass>();
- auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
- auto *LIWP = P->getAnalysisIfAvailable<LoopInfoWrapperPass>();
- auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
- RegionInfoPass *RIP = P->getAnalysisIfAvailable<RegionInfoPass>();
- RegionInfo *RI = RIP ? &RIP->getRegionInfo() : nullptr;
-
- // splitBlock updates DT, LI and RI.
- polly::splitEntryBlockForAlloca(EntryBlock, DT, LI, RI);
-}
-
void polly::recordAssumption(polly::RecordedAssumptionsTy *RecordedAssumptions,
polly::AssumptionKind Kind, isl::set Set,
DebugLoc Loc, polly::AssumptionSign Sign,
diff --git a/polly/lib/Transform/Canonicalization.cpp b/polly/lib/Transform/Canonicalization.cpp
index 1be560e..cd7195f 100644
--- a/polly/lib/Transform/Canonicalization.cpp
+++ b/polly/lib/Transform/Canonicalization.cpp
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "polly/Canonicalization.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
@@ -39,24 +38,6 @@ static cl::opt<bool>
cl::desc("Run an early inliner pass before Polly"), cl::Hidden,
cl::cat(PollyCategory));
-void polly::registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM) {
- bool UseMemSSA = true;
- PM.add(llvm::createPromoteMemoryToRegisterPass());
- PM.add(llvm::createEarlyCSEPass(UseMemSSA));
- PM.add(llvm::createInstructionCombiningPass());
- PM.add(llvm::createCFGSimplificationPass());
- PM.add(llvm::createTailCallEliminationPass());
- PM.add(llvm::createCFGSimplificationPass());
- PM.add(llvm::createReassociatePass());
- if (PollyInliner) {
- PM.add(llvm::createPromoteMemoryToRegisterPass());
- PM.add(llvm::createCFGSimplificationPass());
- PM.add(llvm::createInstructionCombiningPass());
- PM.add(createBarrierNoopPass());
- }
- PM.add(llvm::createInstructionCombiningPass());
-}
-
/// Adapted from llvm::PassBuilder::buildInlinerPipeline
static ModuleInlinerWrapperPass
buildInlinePasses(llvm::OptimizationLevel Level) {
@@ -125,49 +106,3 @@ polly::buildCanonicalicationPassesForNPM(llvm::ModulePassManager &MPM,
return FPM;
}
-
-namespace {
-class PollyCanonicalize final : public ModulePass {
- PollyCanonicalize(const PollyCanonicalize &) = delete;
- const PollyCanonicalize &operator=(const PollyCanonicalize &) = delete;
-
-public:
- static char ID;
-
- explicit PollyCanonicalize() : ModulePass(ID) {}
- ~PollyCanonicalize();
-
- /// @name FunctionPass interface.
- //@{
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- void releaseMemory() override;
- bool runOnModule(Module &M) override;
- void print(raw_ostream &OS, const Module *) const override;
- //@}
-};
-} // namespace
-
-PollyCanonicalize::~PollyCanonicalize() {}
-
-void PollyCanonicalize::getAnalysisUsage(AnalysisUsage &AU) const {}
-
-void PollyCanonicalize::releaseMemory() {}
-
-bool PollyCanonicalize::runOnModule(Module &M) {
- legacy::PassManager PM;
- registerCanonicalicationPasses(PM);
- PM.run(M);
-
- return true;
-}
-
-void PollyCanonicalize::print(raw_ostream &OS, const Module *) const {}
-
-char PollyCanonicalize::ID = 0;
-
-Pass *polly::createPollyCanonicalizePass() { return new PollyCanonicalize(); }
-
-INITIALIZE_PASS_BEGIN(PollyCanonicalize, "polly-canonicalize",
- "Polly - Run canonicalization passes", false, false)
-INITIALIZE_PASS_END(PollyCanonicalize, "polly-canonicalize",
- "Polly - Run canonicalization passes", false, false)
diff --git a/polly/lib/Transform/CodePreparation.cpp b/polly/lib/Transform/CodePreparation.cpp
index d045fb6..3e76dbd 100644
--- a/polly/lib/Transform/CodePreparation.cpp
+++ b/polly/lib/Transform/CodePreparation.cpp
@@ -16,13 +16,11 @@
//===----------------------------------------------------------------------===//
#include "polly/CodePreparation.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Support/ScopHelper.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/InitializePasses.h"
using namespace llvm;
using namespace polly;
@@ -47,83 +45,7 @@ static bool runCodePreprationImpl(Function &F, DominatorTree *DT, LoopInfo *LI,
return true;
}
-namespace {
-
-/// Prepare the IR for the scop detection.
-///
-class CodePreparation final : public FunctionPass {
- CodePreparation(const CodePreparation &) = delete;
- const CodePreparation &operator=(const CodePreparation &) = delete;
-
- void clear();
-
-public:
- static char ID;
-
- explicit CodePreparation() : FunctionPass(ID) {}
- ~CodePreparation();
-
- /// @name FunctionPass interface.
- //@{
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- void releaseMemory() override;
- bool runOnFunction(Function &F) override;
- void print(raw_ostream &OS, const Module *) const override;
- //@}
-};
-} // namespace
-
-PreservedAnalyses CodePreparationPass::run(Function &F,
- FunctionAnalysisManager &FAM) {
- auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
- auto &LI = FAM.getResult<LoopAnalysis>(F);
- bool Changed = runCodePreprationImpl(F, &DT, &LI, nullptr);
- if (!Changed)
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserve<DominatorTreeAnalysis>();
- PA.preserve<LoopAnalysis>();
- return PA;
-}
-
-void CodePreparation::clear() {}
-
-CodePreparation::~CodePreparation() { clear(); }
-
-void CodePreparation::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<LoopInfoWrapperPass>();
-
- AU.addPreserved<LoopInfoWrapperPass>();
- AU.addPreserved<RegionInfoPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- AU.addPreserved<DominanceFrontierWrapperPass>();
+bool polly::runCodePreparation(Function &F, DominatorTree *DT, LoopInfo *LI,
+ RegionInfo *RI) {
+ return runCodePreprationImpl(F, DT, LI, RI);
}
-
-bool CodePreparation::runOnFunction(Function &F) {
- if (skipFunction(F))
- return false;
-
- DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- RegionInfo *RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
-
- runCodePreprationImpl(F, DT, LI, RI);
-
- return true;
-}
-
-void CodePreparation::releaseMemory() { clear(); }
-
-void CodePreparation::print(raw_ostream &OS, const Module *) const {}
-
-char CodePreparation::ID = 0;
-char &polly::CodePreparationID = CodePreparation::ID;
-
-Pass *polly::createCodePreparationPass() { return new CodePreparation(); }
-
-INITIALIZE_PASS_BEGIN(CodePreparation, "polly-prepare",
- "Polly - Prepare code for polly", false, false)
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_END(CodePreparation, "polly-prepare",
- "Polly - Prepare code for polly", false, false)
diff --git a/polly/lib/Transform/DeLICM.cpp b/polly/lib/Transform/DeLICM.cpp
index 9a9768a..4deace1 100644
--- a/polly/lib/Transform/DeLICM.cpp
+++ b/polly/lib/Transform/DeLICM.cpp
@@ -15,17 +15,14 @@
//===----------------------------------------------------------------------===//
#include "polly/DeLICM.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Support/GICHelper.h"
#include "polly/Support/ISLOStream.h"
#include "polly/Support/ISLTools.h"
#include "polly/ZoneAlgo.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Module.h"
-#include "llvm/InitializePasses.h"
#include "polly/Support/PollyDebug.h"
#define DEBUG_TYPE "polly-delicm"
@@ -35,6 +32,10 @@ using namespace llvm;
namespace {
+static cl::opt<bool> PollyPrintDeLICM("polly-print-delicm",
+ cl::desc("Polly - Print DeLICM/DePRE"),
+ cl::cat(PollyCategory));
+
cl::opt<int>
DelicmMaxOps("polly-delicm-max-ops",
cl::desc("Maximum number of isl operations to invest for "
@@ -1356,7 +1357,10 @@ public:
}
/// Return whether at least one transformation been applied.
- bool isModified() const { return NumberOfTargetsMapped > 0; }
+ bool isModified() const {
+ return NumberOfTargetsMapped > 0 || NumberOfMappedValueScalars > 0 ||
+ NumberOfMappedPHIScalars > 0;
+ }
};
static std::unique_ptr<DeLICMImpl> collapseToUnused(Scop &S, LoopInfo &LI) {
@@ -1376,7 +1380,7 @@ static std::unique_ptr<DeLICMImpl> collapseToUnused(Scop &S, LoopInfo &LI) {
return Impl;
}
-static std::unique_ptr<DeLICMImpl> runDeLICM(Scop &S, LoopInfo &LI) {
+static std::unique_ptr<DeLICMImpl> runDeLICMImpl(Scop &S, LoopInfo &LI) {
std::unique_ptr<DeLICMImpl> Impl = collapseToUnused(S, LI);
Scop::ScopStatistics ScopStats = S.getStatistics();
@@ -1389,130 +1393,8 @@ static std::unique_ptr<DeLICMImpl> runDeLICM(Scop &S, LoopInfo &LI) {
return Impl;
}
-
-static PreservedAnalyses runDeLICMUsingNPM(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U, raw_ostream *OS) {
- LoopInfo &LI = SAR.LI;
- std::unique_ptr<DeLICMImpl> Impl = runDeLICM(S, LI);
-
- if (OS) {
- *OS << "Printing analysis 'Polly - DeLICM/DePRE' for region: '"
- << S.getName() << "' in function '" << S.getFunction().getName()
- << "':\n";
- if (Impl) {
- assert(Impl->getScop() == &S);
-
- *OS << "DeLICM result:\n";
- Impl->print(*OS);
- }
- }
-
- if (!Impl->isModified())
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<AllAnalysesOn<Module>>();
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserveSet<AllAnalysesOn<Loop>>();
- return PA;
-}
-
-class DeLICMWrapperPass final : public ScopPass {
-private:
- DeLICMWrapperPass(const DeLICMWrapperPass &) = delete;
- const DeLICMWrapperPass &operator=(const DeLICMWrapperPass &) = delete;
-
- /// The pass implementation, also holding per-scop data.
- std::unique_ptr<DeLICMImpl> Impl;
-
-public:
- static char ID;
- explicit DeLICMWrapperPass() : ScopPass(ID) {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequiredTransitive<ScopInfoRegionPass>();
- AU.addRequired<LoopInfoWrapperPass>();
- AU.setPreservesAll();
- }
-
- bool runOnScop(Scop &S) override {
- // Free resources for previous scop's computation, if not yet done.
- releaseMemory();
-
- auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- Impl = runDeLICM(S, LI);
-
- return Impl->isModified();
- }
-
- void printScop(raw_ostream &OS, Scop &S) const override {
- if (!Impl)
- return;
- assert(Impl->getScop() == &S);
-
- OS << "DeLICM result:\n";
- Impl->print(OS);
- }
-
- void releaseMemory() override { Impl.reset(); }
-};
-
-char DeLICMWrapperPass::ID;
-
-/// Print result from DeLICMWrapperPass.
-class DeLICMPrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- DeLICMPrinterLegacyPass() : DeLICMPrinterLegacyPass(outs()) {}
- explicit DeLICMPrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- DeLICMWrapperPass &P = getAnalysis<DeLICMWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<DeLICMWrapperPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char DeLICMPrinterLegacyPass::ID = 0;
} // anonymous namespace
-Pass *polly::createDeLICMWrapperPass() { return new DeLICMWrapperPass(); }
-
-llvm::Pass *polly::createDeLICMPrinterLegacyPass(llvm::raw_ostream &OS) {
- return new DeLICMPrinterLegacyPass(OS);
-}
-
-llvm::PreservedAnalyses polly::DeLICMPass::run(Scop &S,
- ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- return runDeLICMUsingNPM(S, SAM, SAR, U, nullptr);
-}
-
-llvm::PreservedAnalyses DeLICMPrinterPass::run(Scop &S,
- ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- return runDeLICMUsingNPM(S, SAM, SAR, U, &OS);
-}
-
bool polly::isConflicting(
isl::union_set ExistingOccupied, isl::union_set ExistingUnused,
isl::union_map ExistingKnown, isl::union_map ExistingWrites,
@@ -1527,15 +1409,21 @@ bool polly::isConflicting(
return Knowledge::isConflicting(Existing, Proposed, OS, Indent);
}
-INITIALIZE_PASS_BEGIN(DeLICMWrapperPass, "polly-delicm", "Polly - DeLICM/DePRE",
- false, false)
-INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_END(DeLICMWrapperPass, "polly-delicm", "Polly - DeLICM/DePRE",
- false, false)
-
-INITIALIZE_PASS_BEGIN(DeLICMPrinterLegacyPass, "polly-print-delicm",
- "Polly - Print DeLICM/DePRE", false, false)
-INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass)
-INITIALIZE_PASS_END(DeLICMPrinterLegacyPass, "polly-print-delicm",
- "Polly - Print DeLICM/DePRE", false, false)
+bool polly::runDeLICM(Scop &S) {
+ LoopInfo &LI = *S.getLI();
+ std::unique_ptr<DeLICMImpl> Impl = runDeLICMImpl(S, LI);
+
+ if (PollyPrintDeLICM) {
+ outs() << "Printing analysis 'Polly - DeLICM/DePRE' for region: '"
+ << S.getName() << "' in function '" << S.getFunction().getName()
+ << "':\n";
+ if (Impl) {
+ assert(Impl->getScop() == &S);
+
+ outs() << "DeLICM result:\n";
+ Impl->print(outs());
+ }
+ }
+
+ return Impl->isModified();
+}
diff --git a/polly/lib/Transform/DeadCodeElimination.cpp b/polly/lib/Transform/DeadCodeElimination.cpp
index 5cb89fe..7cb7400 100644
--- a/polly/lib/Transform/DeadCodeElimination.cpp
+++ b/polly/lib/Transform/DeadCodeElimination.cpp
@@ -33,7 +33,6 @@
#include "polly/DeadCodeElimination.h"
#include "polly/DependenceInfo.h"
-#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
#include "llvm/Support/CommandLine.h"
@@ -51,20 +50,6 @@ cl::opt<int> DCEPreciseSteps(
"before the actual dead code elimination."),
cl::init(-1), cl::cat(PollyCategory));
-class DeadCodeElimWrapperPass final : public ScopPass {
-public:
- static char ID;
- explicit DeadCodeElimWrapperPass() : ScopPass(ID) {}
-
- /// Remove dead iterations from the schedule of @p S.
- bool runOnScop(Scop &S) override;
-
- /// Register all analyses and transformation required.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-};
-
-char DeadCodeElimWrapperPass::ID = 0;
-
/// Return the set of live iterations.
///
/// The set of live iterations are all iterations that write to memory and for
@@ -144,35 +129,9 @@ static bool runDeadCodeElimination(Scop &S, int PreciseSteps,
return S.restrictDomains(Live);
}
-bool DeadCodeElimWrapperPass::runOnScop(Scop &S) {
- auto &DI = getAnalysis<DependenceInfo>();
- const Dependences &Deps = DI.getDependences(Dependences::AL_Statement);
-
- bool Changed = runDeadCodeElimination(S, DCEPreciseSteps, Deps);
-
- // FIXME: We can probably avoid the recomputation of all dependences by
- // updating them explicitly.
- if (Changed)
- DI.recomputeDependences(Dependences::AL_Statement);
-
- return false;
-}
-
-void DeadCodeElimWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<DependenceInfo>();
-}
-
} // namespace
-Pass *polly::createDeadCodeElimWrapperPass() {
- return new DeadCodeElimWrapperPass();
-}
-
-llvm::PreservedAnalyses DeadCodeElimPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- DependenceAnalysis::Result &DA = SAM.getResult<DependenceAnalysis>(S, SAR);
+bool polly::runDeadCodeElim(Scop &S, DependenceAnalysis::Result &DA) {
const Dependences &Deps = DA.getDependences(Dependences::AL_Statement);
bool Changed = runDeadCodeElimination(S, DCEPreciseSteps, Deps);
@@ -182,19 +141,5 @@ llvm::PreservedAnalyses DeadCodeElimPass::run(Scop &S, ScopAnalysisManager &SAM,
if (Changed)
DA.recomputeDependences(Dependences::AL_Statement);
- if (!Changed)
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<AllAnalysesOn<Module>>();
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserveSet<AllAnalysesOn<Loop>>();
- return PA;
+ return Changed;
}
-
-INITIALIZE_PASS_BEGIN(DeadCodeElimWrapperPass, "polly-dce",
- "Polly - Remove dead iterations", false, false)
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
-INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass)
-INITIALIZE_PASS_END(DeadCodeElimWrapperPass, "polly-dce",
- "Polly - Remove dead iterations", false, false)
diff --git a/polly/lib/Transform/FlattenSchedule.cpp b/polly/lib/Transform/FlattenSchedule.cpp
index f514ef3..3bb3c2f 100644
--- a/polly/lib/Transform/FlattenSchedule.cpp
+++ b/polly/lib/Transform/FlattenSchedule.cpp
@@ -14,8 +14,8 @@
#include "polly/FlattenSchedule.h"
#include "polly/FlattenAlgo.h"
+#include "polly/Options.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Support/ISLOStream.h"
#include "polly/Support/ISLTools.h"
#include "polly/Support/PollyDebug.h"
@@ -26,6 +26,10 @@ using namespace llvm;
namespace {
+static cl::opt<bool> PollyPrintFlattenSchedule("polly-print-flatten-schedule",
+ cl::desc("A polly pass"),
+ cl::cat(PollyCategory));
+
/// Print a schedule to @p OS.
///
/// Prints the schedule for each statements on a new line.
@@ -34,119 +38,45 @@ void printSchedule(raw_ostream &OS, const isl::union_map &Schedule,
for (isl::map Map : Schedule.get_map_list())
OS.indent(indent) << Map << "\n";
}
+} // namespace
-/// Flatten the schedule stored in an polly::Scop.
-class FlattenSchedule final : public ScopPass {
-private:
- FlattenSchedule(const FlattenSchedule &) = delete;
- const FlattenSchedule &operator=(const FlattenSchedule &) = delete;
-
- std::shared_ptr<isl_ctx> IslCtx;
- isl::union_map OldSchedule;
-
-public:
- static char ID;
- explicit FlattenSchedule() : ScopPass(ID) {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequiredTransitive<ScopInfoRegionPass>();
- AU.setPreservesAll();
- }
-
- bool runOnScop(Scop &S) override {
- // Keep a reference to isl_ctx to ensure that it is not freed before we free
- // OldSchedule.
- IslCtx = S.getSharedIslCtx();
+void polly::runFlattenSchedulePass(Scop &S) {
+ // Keep a reference to isl_ctx to ensure that it is not freed before we free
+ // OldSchedule.
+ auto IslCtx = S.getSharedIslCtx();
- POLLY_DEBUG(dbgs() << "Going to flatten old schedule:\n");
- OldSchedule = S.getSchedule();
- POLLY_DEBUG(printSchedule(dbgs(), OldSchedule, 2));
+ POLLY_DEBUG(dbgs() << "Going to flatten old schedule:\n");
+ auto OldSchedule = S.getSchedule();
+ POLLY_DEBUG(printSchedule(dbgs(), OldSchedule, 2));
- auto Domains = S.getDomains();
- auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains);
- POLLY_DEBUG(dbgs() << "Old schedule with domains:\n");
- POLLY_DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2));
+ auto Domains = S.getDomains();
+ auto RestrictedOldSchedule = OldSchedule.intersect_domain(Domains);
+ POLLY_DEBUG(dbgs() << "Old schedule with domains:\n");
+ POLLY_DEBUG(printSchedule(dbgs(), RestrictedOldSchedule, 2));
- auto NewSchedule = flattenSchedule(RestrictedOldSchedule);
+ auto NewSchedule = flattenSchedule(RestrictedOldSchedule);
- POLLY_DEBUG(dbgs() << "Flattened new schedule:\n");
- POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
+ POLLY_DEBUG(dbgs() << "Flattened new schedule:\n");
+ POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
- NewSchedule = NewSchedule.gist_domain(Domains);
- POLLY_DEBUG(dbgs() << "Gisted, flattened new schedule:\n");
- POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
+ NewSchedule = NewSchedule.gist_domain(Domains);
+ POLLY_DEBUG(dbgs() << "Gisted, flattened new schedule:\n");
+ POLLY_DEBUG(printSchedule(dbgs(), NewSchedule, 2));
- S.setSchedule(NewSchedule);
- return false;
- }
+ S.setSchedule(NewSchedule);
- void printScop(raw_ostream &OS, Scop &S) const override {
- OS << "Schedule before flattening {\n";
- printSchedule(OS, OldSchedule, 4);
- OS << "}\n\n";
+ if (PollyPrintFlattenSchedule) {
+ outs()
+ << "Printing analysis 'Polly - Print flattened schedule' for region: '"
+ << S.getRegion().getNameStr() << "' in function '"
+ << S.getFunction().getName() << "':\n";
- OS << "Schedule after flattening {\n";
- printSchedule(OS, S.getSchedule(), 4);
- OS << "}\n";
- }
+ outs() << "Schedule before flattening {\n";
+ printSchedule(outs(), OldSchedule, 4);
+ outs() << "}\n\n";
- void releaseMemory() override {
- OldSchedule = {};
- IslCtx.reset();
+ outs() << "Schedule after flattening {\n";
+ printSchedule(outs(), S.getSchedule(), 4);
+ outs() << "}\n";
}
-};
-
-char FlattenSchedule::ID;
-
-/// Print result from FlattenSchedule.
-class FlattenSchedulePrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- FlattenSchedulePrinterLegacyPass()
- : FlattenSchedulePrinterLegacyPass(outs()) {}
- explicit FlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- FlattenSchedule &P = getAnalysis<FlattenSchedule>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<FlattenSchedule>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char FlattenSchedulePrinterLegacyPass::ID = 0;
-} // anonymous namespace
-
-Pass *polly::createFlattenSchedulePass() { return new FlattenSchedule(); }
-
-Pass *polly::createFlattenSchedulePrinterLegacyPass(llvm::raw_ostream &OS) {
- return new FlattenSchedulePrinterLegacyPass(OS);
}
-
-INITIALIZE_PASS_BEGIN(FlattenSchedule, "polly-flatten-schedule",
- "Polly - Flatten schedule", false, false)
-INITIALIZE_PASS_END(FlattenSchedule, "polly-flatten-schedule",
- "Polly - Flatten schedule", false, false)
-
-INITIALIZE_PASS_BEGIN(FlattenSchedulePrinterLegacyPass,
- "polly-print-flatten-schedule",
- "Polly - Print flattened schedule", false, false)
-INITIALIZE_PASS_DEPENDENCY(FlattenSchedule)
-INITIALIZE_PASS_END(FlattenSchedulePrinterLegacyPass,
- "polly-print-flatten-schedule",
- "Polly - Print flattened schedule", false, false)
diff --git a/polly/lib/Transform/ForwardOpTree.cpp b/polly/lib/Transform/ForwardOpTree.cpp
index e9be6c9..cf0ce79 100644
--- a/polly/lib/Transform/ForwardOpTree.cpp
+++ b/polly/lib/Transform/ForwardOpTree.cpp
@@ -14,7 +14,6 @@
#include "polly/Options.h"
#include "polly/ScopBuilder.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Support/GICHelper.h"
#include "polly/Support/ISLOStream.h"
#include "polly/Support/ISLTools.h"
@@ -28,7 +27,6 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
@@ -62,6 +60,11 @@ static cl::opt<unsigned>
"analysis; 0=no limit"),
cl::init(1000000), cl::cat(PollyCategory), cl::Hidden);
+static cl::opt<bool>
+ PollyPrintOptree("polly-print-optree",
+ cl::desc("Polly - Print forward operand tree result"),
+ cl::cat(PollyCategory));
+
STATISTIC(KnownAnalyzed, "Number of successfully analyzed SCoPs");
STATISTIC(KnownOutOfQuota,
"Analyses aborted because max_operations was reached");
@@ -1030,8 +1033,8 @@ public:
bool isModified() const { return Modified; }
};
-static std::unique_ptr<ForwardOpTreeImpl> runForwardOpTree(Scop &S,
- LoopInfo &LI) {
+static std::unique_ptr<ForwardOpTreeImpl> runForwardOpTreeImpl(Scop &S,
+ LoopInfo &LI) {
std::unique_ptr<ForwardOpTreeImpl> Impl;
{
IslMaxOperationsGuard MaxOpGuard(S.getIslCtx().get(), MaxOps, false);
@@ -1066,148 +1069,22 @@ static std::unique_ptr<ForwardOpTreeImpl> runForwardOpTree(Scop &S,
return Impl;
}
+} // namespace
-static PreservedAnalyses
-runForwardOpTreeUsingNPM(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR, SPMUpdater &U,
- raw_ostream *OS) {
- LoopInfo &LI = SAR.LI;
-
- std::unique_ptr<ForwardOpTreeImpl> Impl = runForwardOpTree(S, LI);
- if (OS) {
- *OS << "Printing analysis 'Polly - Forward operand tree' for region: '"
- << S.getName() << "' in function '" << S.getFunction().getName()
- << "':\n";
+bool polly::runForwardOpTree(Scop &S) {
+ LoopInfo &LI = *S.getLI();
+
+ std::unique_ptr<ForwardOpTreeImpl> Impl = runForwardOpTreeImpl(S, LI);
+ if (PollyPrintOptree) {
+ outs() << "Printing analysis 'Polly - Forward operand tree' for region: '"
+ << S.getName() << "' in function '" << S.getFunction().getName()
+ << "':\n";
if (Impl) {
assert(Impl->getScop() == &S);
- Impl->print(*OS);
+ Impl->print(outs());
}
}
- if (!Impl->isModified())
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<AllAnalysesOn<Module>>();
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserveSet<AllAnalysesOn<Loop>>();
- return PA;
-}
-
-/// Pass that redirects scalar reads to array elements that are known to contain
-/// the same value.
-///
-/// This reduces the number of scalar accesses and therefore potentially
-/// increases the freedom of the scheduler. In the ideal case, all reads of a
-/// scalar definition are redirected (We currently do not care about removing
-/// the write in this case). This is also useful for the main DeLICM pass as
-/// there are less scalars to be mapped.
-class ForwardOpTreeWrapperPass final : public ScopPass {
-private:
- /// The pass implementation, also holding per-scop data.
- std::unique_ptr<ForwardOpTreeImpl> Impl;
-
-public:
- static char ID;
-
- explicit ForwardOpTreeWrapperPass() : ScopPass(ID) {}
- ForwardOpTreeWrapperPass(const ForwardOpTreeWrapperPass &) = delete;
- ForwardOpTreeWrapperPass &
- operator=(const ForwardOpTreeWrapperPass &) = delete;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequiredTransitive<ScopInfoRegionPass>();
- AU.addRequired<LoopInfoWrapperPass>();
- AU.setPreservesAll();
- }
-
- bool runOnScop(Scop &S) override {
- // Free resources for previous SCoP's computation, if not yet done.
- releaseMemory();
-
- LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
-
- Impl = runForwardOpTree(S, LI);
-
- return false;
- }
-
- void printScop(raw_ostream &OS, Scop &S) const override {
- if (!Impl)
- return;
-
- assert(Impl->getScop() == &S);
- Impl->print(OS);
- }
-
- void releaseMemory() override { Impl.reset(); }
-}; // class ForwardOpTree
-
-char ForwardOpTreeWrapperPass::ID;
-
-/// Print result from ForwardOpTreeWrapperPass.
-class ForwardOpTreePrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- ForwardOpTreePrinterLegacyPass() : ForwardOpTreePrinterLegacyPass(outs()) {}
- explicit ForwardOpTreePrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- ForwardOpTreeWrapperPass &P = getAnalysis<ForwardOpTreeWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<ForwardOpTreeWrapperPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char ForwardOpTreePrinterLegacyPass::ID = 0;
-} // namespace
-
-Pass *polly::createForwardOpTreeWrapperPass() {
- return new ForwardOpTreeWrapperPass();
-}
-
-Pass *polly::createForwardOpTreePrinterLegacyPass(llvm::raw_ostream &OS) {
- return new ForwardOpTreePrinterLegacyPass(OS);
-}
-
-llvm::PreservedAnalyses ForwardOpTreePass::run(Scop &S,
- ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- return runForwardOpTreeUsingNPM(S, SAM, SAR, U, nullptr);
+ return Impl->isModified();
}
-
-llvm::PreservedAnalyses
-ForwardOpTreePrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR, SPMUpdater &U) {
- return runForwardOpTreeUsingNPM(S, SAM, SAR, U, &OS);
-}
-
-INITIALIZE_PASS_BEGIN(ForwardOpTreeWrapperPass, "polly-optree",
- "Polly - Forward operand tree", false, false)
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_END(ForwardOpTreeWrapperPass, "polly-optree",
- "Polly - Forward operand tree", false, false)
-
-INITIALIZE_PASS_BEGIN(ForwardOpTreePrinterLegacyPass, "polly-print-optree",
- "Polly - Print forward operand tree result", false, false)
-INITIALIZE_PASS_DEPENDENCY(ForwardOpTreeWrapperPass)
-INITIALIZE_PASS_END(ForwardOpTreePrinterLegacyPass, "polly-print-optree",
- "Polly - Print forward operand tree result", false, false)
diff --git a/polly/lib/Transform/MatmulOptimizer.cpp b/polly/lib/Transform/MatmulOptimizer.cpp
index 01d431a..7a6b3d2 100644
--- a/polly/lib/Transform/MatmulOptimizer.cpp
+++ b/polly/lib/Transform/MatmulOptimizer.cpp
@@ -11,7 +11,6 @@
#include "polly/Options.h"
#include "polly/ScheduleTreeTransform.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Simplify.h"
#include "polly/Support/GICHelper.h"
#include "polly/Support/ISLTools.h"
diff --git a/polly/lib/Transform/MaximalStaticExpansion.cpp b/polly/lib/Transform/MaximalStaticExpansion.cpp
index 0719840..514a21f 100644
--- a/polly/lib/Transform/MaximalStaticExpansion.cpp
+++ b/polly/lib/Transform/MaximalStaticExpansion.cpp
@@ -13,14 +13,12 @@
#include "polly/MaximalStaticExpansion.h"
#include "polly/DependenceInfo.h"
-#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Support/ISLTools.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/InitializePasses.h"
#include "isl/isl-noexceptions.h"
#include "isl/union_map.h"
#include <cassert>
@@ -35,28 +33,10 @@ using namespace polly;
namespace {
-class MaximalStaticExpanderWrapperPass final : public ScopPass {
-public:
- static char ID;
-
- explicit MaximalStaticExpanderWrapperPass() : ScopPass(ID) {}
-
- ~MaximalStaticExpanderWrapperPass() override = default;
-
- /// Expand the accesses of the SCoP.
- ///
- /// @param S The SCoP that must be expanded.
- bool runOnScop(Scop &S) override;
-
- /// Print the SCoP.
- ///
- /// @param OS The stream where to print.
- /// @param S The SCop that must be printed.
- void printScop(raw_ostream &OS, Scop &S) const override;
-
- /// Register all analyses and transformations required.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-};
+static cl::opt<bool>
+ PollyPrintMSE("polly-print-mse",
+ cl::desc("Polly - Print Maximal static expansion of SCoP"),
+ cl::cat(PollyCategory));
#ifndef NDEBUG
/// Whether a dimension of a set is bounded (lower and upper) by a constant,
@@ -458,8 +438,8 @@ public:
};
static std::unique_ptr<MaximalStaticExpansionImpl>
-runMaximalStaticExpansion(Scop &S, OptimizationRemarkEmitter &ORE,
- const Dependences &D) {
+runMaximalStaticExpansionImpl(Scop &S, OptimizationRemarkEmitter &ORE,
+ const Dependences &D) {
auto Dependences = D.getDependences(Dependences::TYPE_RAW);
std::unique_ptr<MaximalStaticExpansionImpl> Impl =
@@ -468,85 +448,26 @@ runMaximalStaticExpansion(Scop &S, OptimizationRemarkEmitter &ORE,
Impl->expand();
return Impl;
}
+} // namespace
-static PreservedAnalyses runMSEUsingNPM(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- raw_ostream *OS) {
+void polly::runMaximalStaticExpansion(Scop &S, DependenceAnalysis::Result &DI) {
OptimizationRemarkEmitter ORE(&S.getFunction());
- auto &DI = SAM.getResult<DependenceAnalysis>(S, SAR);
auto &D = DI.getDependences(Dependences::AL_Reference);
std::unique_ptr<MaximalStaticExpansionImpl> Impl =
- runMaximalStaticExpansion(S, ORE, D);
+ runMaximalStaticExpansionImpl(S, ORE, D);
- if (OS) {
- *OS << "Printing analysis 'Polly - Maximal static expansion of SCoP' for "
+ if (PollyPrintMSE) {
+ outs()
+ << "Printing analysis 'Polly - Maximal static expansion of SCoP' for "
"region: '"
<< S.getName() << "' in function '" << S.getFunction().getName()
<< "':\n";
if (Impl) {
- *OS << "MSE result:\n";
- Impl->print(*OS);
+ outs() << "MSE result:\n";
+ Impl->print(llvm::outs());
}
}
-
- return PreservedAnalyses::all();
-}
-
-} // namespace
-
-PreservedAnalyses
-MaximalStaticExpansionPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &) {
- return runMSEUsingNPM(S, SAM, SAR, nullptr);
-}
-
-PreservedAnalyses
-MaximalStaticExpansionPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &) {
- return runMSEUsingNPM(S, SAM, SAR, &OS);
-}
-
-char MaximalStaticExpanderWrapperPass::ID = 0;
-
-bool MaximalStaticExpanderWrapperPass::runOnScop(Scop &S) {
- // Get the ORE from OptimizationRemarkEmitterWrapperPass.
- OptimizationRemarkEmitter *ORE =
- &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
-
- // Get the RAW Dependences.
- auto &DI = getAnalysis<DependenceInfo>();
- auto &D = DI.getDependences(Dependences::AL_Reference);
-
- std::unique_ptr<MaximalStaticExpansionImpl> Impl =
- runMaximalStaticExpansion(S, *ORE, D);
-
- return false;
-}
-
-void MaximalStaticExpanderWrapperPass::printScop(raw_ostream &OS,
- Scop &S) const {
- S.print(OS, false);
-}
-
-void MaximalStaticExpanderWrapperPass::getAnalysisUsage(
- AnalysisUsage &AU) const {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<DependenceInfo>();
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
-}
-
-Pass *polly::createMaximalStaticExpansionPass() {
- return new MaximalStaticExpanderWrapperPass();
}
-
-INITIALIZE_PASS_BEGIN(MaximalStaticExpanderWrapperPass, "polly-mse",
- "Polly - Maximal static expansion of SCoP", false, false);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
-INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass);
-INITIALIZE_PASS_END(MaximalStaticExpanderWrapperPass, "polly-mse",
- "Polly - Maximal static expansion of SCoP", false, false)
diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp
index f01d3de..b9b9abb 100644
--- a/polly/lib/Transform/ScheduleOptimizer.cpp
+++ b/polly/lib/Transform/ScheduleOptimizer.cpp
@@ -52,12 +52,12 @@
#include "polly/MatmulOptimizer.h"
#include "polly/Options.h"
#include "polly/ScheduleTreeTransform.h"
+#include "polly/ScopInfo.h"
#include "polly/Support/ISLOStream.h"
#include "polly/Support/ISLTools.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "isl/options.h"
@@ -198,6 +198,10 @@ static cl::opt<bool> OptimizedScops(
"transformations is applied on the schedule tree"),
cl::cat(PollyCategory));
+static cl::opt<bool> PollyPrintOptIsl("polly-print-opt-isl",
+ cl::desc("A polly pass"),
+ cl::cat(PollyCategory));
+
STATISTIC(ScopsProcessed, "Number of scops processed");
STATISTIC(ScopsRescheduled, "Number of scops rescheduled");
STATISTIC(ScopsOptimized, "Number of scops optimized");
@@ -638,34 +642,6 @@ bool ScheduleTreeOptimizer::isProfitableSchedule(Scop &S,
return changed;
}
-class IslScheduleOptimizerWrapperPass final : public ScopPass {
-public:
- static char ID;
-
- explicit IslScheduleOptimizerWrapperPass() : ScopPass(ID) {}
-
- /// Optimize the schedule of the SCoP @p S.
- bool runOnScop(Scop &S) override;
-
- /// Print the new schedule for the SCoP @p S.
- void printScop(raw_ostream &OS, Scop &S) const override;
-
- /// Register all analyses and transformation required.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- /// Release the internal memory.
- void releaseMemory() override {
- LastSchedule = {};
- IslCtx.reset();
- }
-
-private:
- std::shared_ptr<isl_ctx> IslCtx;
- isl::schedule LastSchedule;
-};
-
-char IslScheduleOptimizerWrapperPass::ID = 0;
-
#ifndef NDEBUG
static void printSchedule(llvm::raw_ostream &OS, const isl::schedule &Schedule,
StringRef Desc) {
@@ -733,7 +709,7 @@ static void walkScheduleTreeForStatistics(isl::schedule Schedule, int Version) {
&Version);
}
-static void runIslScheduleOptimizer(
+static void runIslScheduleOptimizerImpl(
Scop &S,
function_ref<const Dependences &(Dependences::AnalysisLevel)> GetDeps,
TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE,
@@ -966,30 +942,6 @@ static void runIslScheduleOptimizer(
errs() << S;
}
-bool IslScheduleOptimizerWrapperPass::runOnScop(Scop &S) {
- releaseMemory();
-
- Function &F = S.getFunction();
- IslCtx = S.getSharedIslCtx();
-
- auto getDependences =
- [this](Dependences::AnalysisLevel) -> const Dependences & {
- return getAnalysis<DependenceInfo>().getDependences(
- Dependences::AL_Statement);
- };
- OptimizationRemarkEmitter &ORE =
- getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
- TargetTransformInfo *TTI =
- &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
-
- bool DepsChanged = false;
- runIslScheduleOptimizer(S, getDependences, TTI, &ORE, LastSchedule,
- DepsChanged);
- if (DepsChanged)
- getAnalysis<DependenceInfo>().abandonDependences();
- return false;
-}
-
static void runScheduleOptimizerPrinter(raw_ostream &OS,
isl::schedule LastSchedule) {
isl_printer *p;
@@ -1013,120 +965,25 @@ static void runScheduleOptimizerPrinter(raw_ostream &OS,
free(ScheduleStr);
}
-void IslScheduleOptimizerWrapperPass::printScop(raw_ostream &OS, Scop &) const {
- runScheduleOptimizerPrinter(OS, LastSchedule);
-}
-
-void IslScheduleOptimizerWrapperPass::getAnalysisUsage(
- AnalysisUsage &AU) const {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<DependenceInfo>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
-
- AU.addPreserved<DependenceInfo>();
- AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
-}
-
} // namespace
-Pass *polly::createIslScheduleOptimizerWrapperPass() {
- return new IslScheduleOptimizerWrapperPass();
-}
-
-INITIALIZE_PASS_BEGIN(IslScheduleOptimizerWrapperPass, "polly-opt-isl",
- "Polly - Optimize schedule of SCoP", false, false);
-INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
-INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass);
-INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass);
-INITIALIZE_PASS_END(IslScheduleOptimizerWrapperPass, "polly-opt-isl",
- "Polly - Optimize schedule of SCoP", false, false)
-
-static llvm::PreservedAnalyses
-runIslScheduleOptimizerUsingNPM(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR, SPMUpdater &U,
- raw_ostream *OS) {
- DependenceAnalysis::Result &Deps = SAM.getResult<DependenceAnalysis>(S, SAR);
+void polly::runIslScheduleOptimizer(Scop &S, TargetTransformInfo *TTI,
+ DependenceAnalysis::Result &Deps) {
auto GetDeps = [&Deps](Dependences::AnalysisLevel) -> const Dependences & {
return Deps.getDependences(Dependences::AL_Statement);
};
OptimizationRemarkEmitter ORE(&S.getFunction());
- TargetTransformInfo *TTI = &SAR.TTI;
isl::schedule LastSchedule;
bool DepsChanged = false;
- runIslScheduleOptimizer(S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
+ runIslScheduleOptimizerImpl(S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
if (DepsChanged)
Deps.abandonDependences();
- if (OS) {
- *OS << "Printing analysis 'Polly - Optimize schedule of SCoP' for region: '"
+ if (PollyPrintOptIsl) {
+ outs()
+ << "Printing analysis 'Polly - Optimize schedule of SCoP' for region: '"
<< S.getName() << "' in function '" << S.getFunction().getName()
<< "':\n";
- runScheduleOptimizerPrinter(*OS, LastSchedule);
+ runScheduleOptimizerPrinter(outs(), LastSchedule);
}
- return PreservedAnalyses::all();
-}
-
-llvm::PreservedAnalyses
-IslScheduleOptimizerPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR, SPMUpdater &U) {
- return runIslScheduleOptimizerUsingNPM(S, SAM, SAR, U, nullptr);
}
-
-llvm::PreservedAnalyses
-IslScheduleOptimizerPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- return runIslScheduleOptimizerUsingNPM(S, SAM, SAR, U, &OS);
-}
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from IslScheduleOptimizerWrapperPass.
-class IslScheduleOptimizerPrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- IslScheduleOptimizerPrinterLegacyPass()
- : IslScheduleOptimizerPrinterLegacyPass(outs()) {}
- explicit IslScheduleOptimizerPrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- IslScheduleOptimizerWrapperPass &P =
- getAnalysis<IslScheduleOptimizerWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<IslScheduleOptimizerWrapperPass>();
- AU.setPreservesAll();
- }
-
-private:
- llvm::raw_ostream &OS;
-};
-
-char IslScheduleOptimizerPrinterLegacyPass::ID = 0;
-} // namespace
-
-Pass *polly::createIslScheduleOptimizerPrinterLegacyPass(raw_ostream &OS) {
- return new IslScheduleOptimizerPrinterLegacyPass(OS);
-}
-
-INITIALIZE_PASS_BEGIN(IslScheduleOptimizerPrinterLegacyPass,
- "polly-print-opt-isl",
- "Polly - Print optimizer schedule of SCoP", false, false);
-INITIALIZE_PASS_DEPENDENCY(IslScheduleOptimizerWrapperPass)
-INITIALIZE_PASS_END(IslScheduleOptimizerPrinterLegacyPass,
- "polly-print-opt-isl",
- "Polly - Print optimizer schedule of SCoP", false, false)
diff --git a/polly/lib/Transform/ScopInliner.cpp b/polly/lib/Transform/ScopInliner.cpp
index c04ba34..794ba98 100644
--- a/polly/lib/Transform/ScopInliner.cpp
+++ b/polly/lib/Transform/ScopInliner.cpp
@@ -21,7 +21,6 @@
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
@@ -95,53 +94,7 @@ template <typename SCC_t> bool runScopInlinerImpl(Function *F, SCC_t &SCC) {
return Changed;
}
-
-class ScopInlinerWrapperPass final : public CallGraphSCCPass {
- using llvm::Pass::doInitialization;
-
-public:
- static char ID;
-
- ScopInlinerWrapperPass() : CallGraphSCCPass(ID) {}
-
- bool doInitialization(CallGraph &CG) override {
- if (!polly::PollyAllowFullFunction) {
- report_fatal_error(
- "Aborting from ScopInliner because it only makes sense to run with "
- "-polly-allow-full-function. "
- "The heurtistic for ScopInliner checks that the full function is a "
- "Scop, which happens if and only if polly-allow-full-function is "
- " enabled. "
- " If not, the entry block is not included in the Scop");
- }
- return true;
- }
-
- bool runOnSCC(CallGraphSCC &SCC) override {
- Function *F = (*SCC.begin())->getFunction();
- return runScopInlinerImpl(F, SCC);
- };
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- CallGraphSCCPass::getAnalysisUsage(AU);
- }
-};
} // namespace
-char ScopInlinerWrapperPass::ID;
-
-Pass *polly::createScopInlinerWrapperPass() {
- ScopInlinerWrapperPass *pass = new ScopInlinerWrapperPass();
- return pass;
-}
-
-INITIALIZE_PASS_BEGIN(
- ScopInlinerWrapperPass, "polly-scop-inliner",
- "inline functions based on how much of the function is a scop.", false,
- false)
-INITIALIZE_PASS_END(
- ScopInlinerWrapperPass, "polly-scop-inliner",
- "inline functions based on how much of the function is a scop.", false,
- false)
polly::ScopInlinerPass::ScopInlinerPass() {
if (!polly::PollyAllowFullFunction) {
diff --git a/polly/lib/Transform/Simplify.cpp b/polly/lib/Transform/Simplify.cpp
index 75e91cd..df88b5e 100644
--- a/polly/lib/Transform/Simplify.cpp
+++ b/polly/lib/Transform/Simplify.cpp
@@ -11,14 +11,13 @@
//===----------------------------------------------------------------------===//
#include "polly/Simplify.h"
+#include "polly/Options.h"
#include "polly/ScopInfo.h"
-#include "polly/ScopPass.h"
#include "polly/Support/GICHelper.h"
#include "polly/Support/ISLOStream.h"
#include "polly/Support/ISLTools.h"
#include "polly/Support/VirtualInstruction.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include <optional>
@@ -30,6 +29,11 @@ using namespace polly;
namespace {
+static cl::opt<bool>
+ PollyPrintSimplify("polly-print-simplify",
+ cl::desc("Polly - Print Simplify actions"),
+ cl::cat(PollyCategory));
+
#define TWO_STATISTICS(VARNAME, DESC) \
static llvm::Statistic VARNAME[2] = { \
{DEBUG_TYPE, #VARNAME "0", DESC " (first)"}, \
@@ -756,75 +760,8 @@ void SimplifyImpl::printScop(raw_ostream &OS, Scop &S) const {
printAccesses(OS);
}
-class SimplifyWrapperPass final : public ScopPass {
-public:
- static char ID;
- int CallNo;
- std::optional<SimplifyImpl> Impl;
-
- explicit SimplifyWrapperPass(int CallNo = 0) : ScopPass(ID), CallNo(CallNo) {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequiredTransitive<ScopInfoRegionPass>();
- AU.addRequired<LoopInfoWrapperPass>();
- AU.setPreservesAll();
- }
-
- bool runOnScop(Scop &S) override {
- LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
-
- Impl.emplace(CallNo);
- Impl->run(S, LI);
-
- return false;
- }
-
- void printScop(raw_ostream &OS, Scop &S) const override {
- if (Impl)
- Impl->printScop(OS, S);
- }
-
- void releaseMemory() override { Impl.reset(); }
-};
-
-char SimplifyWrapperPass::ID;
-
-static llvm::PreservedAnalyses
-runSimplifyUsingNPM(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR, SPMUpdater &U, int CallNo,
- raw_ostream *OS) {
- SimplifyImpl Impl(CallNo);
- Impl.run(S, &SAR.LI);
- if (OS) {
- *OS << "Printing analysis 'Polly - Simplify' for region: '" << S.getName()
- << "' in function '" << S.getFunction().getName() << "':\n";
- Impl.printScop(*OS, S);
- }
-
- if (!Impl.isModified())
- return llvm::PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<AllAnalysesOn<Module>>();
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserveSet<AllAnalysesOn<Loop>>();
- return PA;
-}
-
} // anonymous namespace
-llvm::PreservedAnalyses SimplifyPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR,
- SPMUpdater &U) {
- return runSimplifyUsingNPM(S, SAM, SAR, U, CallNo, nullptr);
-}
-
-llvm::PreservedAnalyses
-SimplifyPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
- ScopStandardAnalysisResults &SAR, SPMUpdater &U) {
- return runSimplifyUsingNPM(S, SAM, SAR, U, CallNo, &OS);
-}
-
SmallVector<MemoryAccess *, 32> polly::getAccessesInOrder(ScopStmt &Stmt) {
SmallVector<MemoryAccess *, 32> Accesses;
@@ -843,58 +780,15 @@ SmallVector<MemoryAccess *, 32> polly::getAccessesInOrder(ScopStmt &Stmt) {
return Accesses;
}
-Pass *polly::createSimplifyWrapperPass(int CallNo) {
- return new SimplifyWrapperPass(CallNo);
-}
-
-INITIALIZE_PASS_BEGIN(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify",
- false, false)
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_END(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify",
- false, false)
-
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Print result from SimplifyWrapperPass.
-class SimplifyPrinterLegacyPass final : public ScopPass {
-public:
- static char ID;
-
- SimplifyPrinterLegacyPass() : SimplifyPrinterLegacyPass(outs()) {}
- explicit SimplifyPrinterLegacyPass(llvm::raw_ostream &OS)
- : ScopPass(ID), OS(OS) {}
-
- bool runOnScop(Scop &S) override {
- SimplifyWrapperPass &P = getAnalysis<SimplifyWrapperPass>();
-
- OS << "Printing analysis '" << P.getPassName() << "' for region: '"
- << S.getRegion().getNameStr() << "' in function '"
- << S.getFunction().getName() << "':\n";
- P.printScop(OS, S);
-
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- ScopPass::getAnalysisUsage(AU);
- AU.addRequired<SimplifyWrapperPass>();
- AU.setPreservesAll();
+bool polly::runSimplify(Scop &S, int CallNo) {
+ SimplifyImpl Impl(CallNo);
+ Impl.run(S, S.getLI());
+ if (PollyPrintSimplify) {
+ outs() << "Printing analysis 'Polly - Simplify' for region: '"
+ << S.getName() << "' in function '" << S.getFunction().getName()
+ << "':\n";
+ Impl.printScop(outs(), S);
}
-private:
- llvm::raw_ostream &OS;
-};
-
-char SimplifyPrinterLegacyPass::ID = 0;
-} // namespace
-
-Pass *polly::createSimplifyPrinterLegacyPass(raw_ostream &OS) {
- return new SimplifyPrinterLegacyPass(OS);
+ return Impl.isModified();
}
-
-INITIALIZE_PASS_BEGIN(SimplifyPrinterLegacyPass, "polly-print-simplify",
- "Polly - Print Simplify actions", false, false)
-INITIALIZE_PASS_DEPENDENCY(SimplifyWrapperPass)
-INITIALIZE_PASS_END(SimplifyPrinterLegacyPass, "polly-print-simplify",
- "Polly - Print Simplify actions", false, false)