aboutsummaryrefslogtreecommitdiff
path: root/polly/lib/Transform
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib/Transform')
-rw-r--r--polly/lib/Transform/Canonicalization.cpp65
-rw-r--r--polly/lib/Transform/CodePreparation.cpp91
-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.cpp238
-rw-r--r--polly/lib/Transform/ScheduleTreeTransform.cpp5
-rw-r--r--polly/lib/Transform/ScopInliner.cpp47
-rw-r--r--polly/lib/Transform/Simplify.cpp136
12 files changed, 193 insertions, 1023 deletions
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 7c8579eb..3e76dbd 100644
--- a/polly/lib/Transform/CodePreparation.cpp
+++ b/polly/lib/Transform/CodePreparation.cpp
@@ -16,49 +16,17 @@
//===----------------------------------------------------------------------===//
#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;
-namespace {
-
-/// Prepare the IR for the scop detection.
-///
-class CodePreparation final : public FunctionPass {
- CodePreparation(const CodePreparation &) = delete;
- const CodePreparation &operator=(const CodePreparation &) = delete;
-
- LoopInfo *LI;
- ScalarEvolution *SE;
-
- 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) {
-
+static bool runCodePreprationImpl(Function &F, DominatorTree *DT, LoopInfo *LI,
+ RegionInfo *RI) {
// Find first non-alloca instruction. Every basic block has a non-alloca
// instruction, as every well formed basic block has a terminator.
auto &EntryBlock = F.getEntryBlock();
@@ -66,55 +34,18 @@ PreservedAnalyses CodePreparationPass::run(Function &F,
while (isa<AllocaInst>(I))
++I;
- auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
- auto &LI = FAM.getResult<LoopAnalysis>(F);
-
- // splitBlock updates DT, LI and RI.
- splitEntryBlockForAlloca(&EntryBlock, &DT, &LI, nullptr);
-
- 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.addRequired<ScalarEvolutionWrapperPass>();
-
- AU.addPreserved<LoopInfoWrapperPass>();
- AU.addPreserved<RegionInfoPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- AU.addPreserved<DominanceFrontierWrapperPass>();
-}
-
-bool CodePreparation::runOnFunction(Function &F) {
- if (skipFunction(F))
+ // Abort if not necessary to split
+ if (I->isTerminator() && isa<BranchInst>(I) &&
+ cast<BranchInst>(I)->isUnconditional())
return false;
- LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
-
- splitEntryBlockForAlloca(&F.getEntryBlock(), this);
+ // splitBlock updates DT, LI and RI.
+ splitEntryBlockForAlloca(&EntryBlock, 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)
+bool polly::runCodePreparation(Function &F, DominatorTree *DT, LoopInfo *LI,
+ RegionInfo *RI) {
+ return runCodePreprationImpl(F, DT, LI, RI);
+}
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 070700a..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");
@@ -237,6 +241,7 @@ struct OptimizerAdditionalInfoTy {
bool Postopts;
bool Prevect;
bool &DepsChanged;
+ IslMaxOperationsGuard &MaxOpGuard;
};
class ScheduleTreeOptimizer final {
@@ -381,6 +386,8 @@ private:
isl::schedule_node
ScheduleTreeOptimizer::isolateFullPartialTiles(isl::schedule_node Node,
int VectorWidth) {
+ if (Node.is_null())
+ return {};
assert(isl_schedule_node_get_type(Node.get()) == isl_schedule_node_band);
Node = Node.child(0).child(0);
isl::union_map SchedRelUMap = Node.get_prefix_schedule_relation();
@@ -391,6 +398,8 @@ ScheduleTreeOptimizer::isolateFullPartialTiles(isl::schedule_node Node,
isl::union_set IsolateOption = getIsolateOptions(IsolateDomain, 1);
Node = Node.parent().parent();
isl::union_set Options = IsolateOption.unite(AtomicOption);
+ if (Node.is_null())
+ return {};
isl::schedule_node_band Result =
Node.as<isl::schedule_node_band>().set_ast_build_options(Options);
return Result;
@@ -411,9 +420,13 @@ struct InsertSimdMarkers final : ScheduleNodeRewriter<InsertSimdMarkers> {
isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand(
isl::schedule_node Node, unsigned DimToVectorize, int VectorWidth) {
+ if (Node.is_null())
+ return {};
assert(isl_schedule_node_get_type(Node.get()) == isl_schedule_node_band);
auto Space = isl::manage(isl_schedule_node_band_get_space(Node.get()));
+ if (Space.is_null())
+ return {};
unsigned ScheduleDimensions = unsignedFromIslSize(Space.dim(isl::dim::set));
assert(DimToVectorize < ScheduleDimensions);
@@ -439,12 +452,15 @@ isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand(
// Sink the inner loop into the smallest possible statements to make them
// represent a single vector instruction if possible.
Node = isl::manage(isl_schedule_node_band_sink(Node.release()));
+ if (Node.is_null())
+ return {};
// Add SIMD markers to those vector statements.
InsertSimdMarkers SimdMarkerInserter;
Node = SimdMarkerInserter.visit(Node);
- PrevectOpts++;
+ if (!Node.is_null())
+ PrevectOpts++;
return Node.parent();
}
@@ -535,6 +551,8 @@ ScheduleTreeOptimizer::applyTileBandOpt(isl::schedule_node Node) {
isl::schedule_node
ScheduleTreeOptimizer::applyPrevectBandOpt(isl::schedule_node Node) {
auto Space = isl::manage(isl_schedule_node_band_get_space(Node.get()));
+ if (Space.is_null())
+ return {};
int Dims = unsignedFromIslSize(Space.dim(isl::dim::set));
for (int i = Dims - 1; i >= 0; i--)
@@ -572,9 +590,14 @@ ScheduleTreeOptimizer::optimizeBand(__isl_take isl_schedule_node *NodeArg,
Node = applyTileBandOpt(Node);
if (OAI->Prevect) {
+ IslQuotaScope MaxScope = OAI->MaxOpGuard.enter();
+
// FIXME: Prevectorization requirements are different from those checked by
// isTileableBandNode.
Node = applyPrevectBandOpt(Node);
+
+ if (OAI->MaxOpGuard.hasQuotaExceeded() || Node.is_null())
+ return (isl::schedule_node()).release();
}
return Node.release();
@@ -619,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) {
@@ -714,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,
@@ -771,6 +766,10 @@ static void runIslScheduleOptimizer(
return;
}
+ isl_ctx *Ctx = S.getIslCtx().get();
+ IslMaxOperationsGuard MaxOpGuard(Ctx, ScheduleComputeOut,
+ /*AutoEnter=*/false);
+
// Apply ISL's algorithm only if not overridden by the user. Note that
// post-rescheduling optimizations (tiling, pattern-based, prevectorization)
// rely on the coincidence/permutable annotations on schedule tree bands that
@@ -853,8 +852,6 @@ static void runIslScheduleOptimizer(
IslOuterCoincidence = 0;
}
- isl_ctx *Ctx = S.getIslCtx().get();
-
isl_options_set_schedule_outer_coincidence(Ctx, IslOuterCoincidence);
isl_options_set_schedule_maximize_band_depth(Ctx, IslMaximizeBands);
isl_options_set_schedule_max_constant_term(Ctx, MaxConstantTerm);
@@ -870,28 +867,20 @@ static void runIslScheduleOptimizer(
SC = SC.set_coincidence(Validity);
{
- IslMaxOperationsGuard MaxOpGuard(Ctx, ScheduleComputeOut);
+ IslQuotaScope MaxOpScope = MaxOpGuard.enter();
Schedule = SC.compute_schedule();
-
- if (MaxOpGuard.hasQuotaExceeded())
- POLLY_DEBUG(
- dbgs() << "Schedule optimizer calculation exceeds ISL quota\n");
}
isl_options_set_on_error(Ctx, OnErrorStatus);
- ScopsRescheduled++;
+ if (!Schedule.is_null())
+ ScopsRescheduled++;
POLLY_DEBUG(printSchedule(dbgs(), Schedule, "After rescheduling"));
}
walkScheduleTreeForStatistics(Schedule, 1);
- // In cases the scheduler is not able to optimize the code, we just do not
- // touch the schedule.
- if (Schedule.is_null())
- return;
-
- if (GreedyFusion) {
+ if (GreedyFusion && !Schedule.is_null()) {
isl::union_map Validity = D.getDependences(
Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW);
Schedule = applyGreedyFusion(Schedule, Validity);
@@ -905,14 +894,36 @@ static void runIslScheduleOptimizer(
/*PatternOpts=*/!HasUserTransformation && PMBasedOpts,
/*Postopts=*/!HasUserTransformation && EnablePostopts,
/*Prevect=*/PollyVectorizerChoice != VECTORIZER_NONE,
- DepsChanged};
- if (OAI.PatternOpts || OAI.Postopts || OAI.Prevect) {
+ DepsChanged,
+ MaxOpGuard};
+ if (!Schedule.is_null() && (OAI.PatternOpts || OAI.Postopts || OAI.Prevect)) {
Schedule = ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI);
Schedule = hoistExtensionNodes(Schedule);
POLLY_DEBUG(printSchedule(dbgs(), Schedule, "After post-optimizations"));
walkScheduleTreeForStatistics(Schedule, 2);
}
+ // Check for why any computation could have failed
+ if (MaxOpGuard.hasQuotaExceeded()) {
+ POLLY_DEBUG(dbgs() << "Schedule optimizer calculation exceeds ISL quota\n");
+ return;
+ } else if (isl_ctx_last_error(Ctx) != isl_error_none) {
+ POLLY_DEBUG({
+ const char *File = isl_ctx_last_error_file(Ctx);
+ int Line = isl_ctx_last_error_line(Ctx);
+ const char *Msg = isl_ctx_last_error_msg(Ctx);
+ dbgs() << "ISL reported an error during the computation of a new "
+ "schedule at "
+ << File << ":" << Line << ": " << Msg;
+ });
+ isl_ctx_reset_error(Ctx);
+ return;
+ } else if (Schedule.is_null()) {
+ POLLY_DEBUG(dbgs() << "Schedule optimizer did not compute a new schedule "
+ "for unknown reasons\n");
+ return;
+ }
+
// Skip profitability check if user transformation(s) have been applied.
if (!HasUserTransformation &&
!ScheduleTreeOptimizer::isProfitableSchedule(S, Schedule))
@@ -931,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;
@@ -978,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/ScheduleTreeTransform.cpp b/polly/lib/Transform/ScheduleTreeTransform.cpp
index 3f36300..c95c558 100644
--- a/polly/lib/Transform/ScheduleTreeTransform.cpp
+++ b/polly/lib/Transform/ScheduleTreeTransform.cpp
@@ -972,6 +972,9 @@ BandAttr *polly::getBandAttr(isl::schedule_node MarkOrBand) {
}
isl::schedule polly::hoistExtensionNodes(isl::schedule Sched) {
+ if (Sched.is_null())
+ return {};
+
// If there is no extension node in the first place, return the original
// schedule tree.
if (!containsExtensionNode(Sched))
@@ -1126,6 +1129,8 @@ isl::set polly::getPartialTilePrefixes(isl::set ScheduleRange,
isl::union_set polly::getIsolateOptions(isl::set IsolateDomain,
unsigned OutDimsNum) {
+ if (IsolateDomain.is_null())
+ return {};
unsigned Dims = unsignedFromIslSize(IsolateDomain.tuple_dim());
assert(OutDimsNum <= Dims &&
"The isl::set IsolateDomain is used to describe the range of schedule "
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)