summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Pfaffe <philip.pfaffe@gmail.com>2017-08-10 07:43:46 +0000
committerPhilip Pfaffe <philip.pfaffe@gmail.com>2017-08-10 07:43:46 +0000
commitf43e7c2e9733448624fe05cd186cc440daf83e4b (patch)
tree0ca16341a3ac523ebd41204e480fa8318cea4f1e
parent2f4e2e2758abc28ebc2215c293f5f77b7711ed89 (diff)
downloadbcm5719-llvm-f43e7c2e9733448624fe05cd186cc440daf83e4b.tar.gz
bcm5719-llvm-f43e7c2e9733448624fe05cd186cc440daf83e4b.zip
[Polly][PM] Improve invalidation in the Scop-Pipeline
Summary: During code generation for a Scop we modify the IR of a function. While this shouldn't affect a Scop in the formal sense, the implementation caches various information about the IR such as SCEV expressions for bounds or parameters. This cached information needs to be updated or invalidated. To this end, SPMUpdater allows passes to report when they've invalidated a Scop to the PassManager, which will then flush and recompute all Scops. This in turn invalidates all iterators, so references to Scops shouldn't be held. Reviewers: grosser, Meinersbur, bollu Reviewed By: grosser Subscribers: llvm-commits, pollydev Differential Revision: https://reviews.llvm.org/D36524 llvm-svn: 310551
-rw-r--r--polly/include/polly/ScopInfo.h16
-rw-r--r--polly/include/polly/ScopPass.h46
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp22
-rw-r--r--polly/lib/Analysis/ScopPass.cpp10
-rw-r--r--polly/lib/CodeGen/CodeGeneration.cpp4
5 files changed, 77 insertions, 21 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 524a186163a..ae67bbcdba1 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -3044,6 +3044,13 @@ private:
/// A map of Region to its Scop object containing
/// Polly IR of static control part.
RegionToScopMapTy RegionToScopMap;
+ const DataLayout &DL;
+ ScopDetection &SD;
+ ScalarEvolution &SE;
+ LoopInfo &LI;
+ AliasAnalysis &AA;
+ DominatorTree &DT;
+ AssumptionCache &AC;
public:
ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE,
@@ -3063,6 +3070,15 @@ public:
return nullptr;
}
+ /// Recompute the Scop-Information for a function.
+ ///
+ /// This invalidates any iterators.
+ void recompute();
+
+ /// Handle invalidation explicitly
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
+
iterator begin() { return RegionToScopMap.begin(); }
iterator end() { return RegionToScopMap.end(); }
const_iterator begin() const { return RegionToScopMap.begin(); }
diff --git a/polly/include/polly/ScopPass.h b/polly/include/polly/ScopPass.h
index 3711b539862..5ac25c22977 100644
--- a/polly/include/polly/ScopPass.h
+++ b/polly/include/polly/ScopPass.h
@@ -180,18 +180,26 @@ struct ScopStandardAnalysisResults {
class SPMUpdater {
public:
- SPMUpdater(SmallPriorityWorklist<Scop *, 4> &Worklist,
+ SPMUpdater(SmallPriorityWorklist<Region *, 4> &Worklist,
ScopAnalysisManager &SAM)
- : Worklist(Worklist), SAM(SAM) {}
+ : Worklist(Worklist), SAM(SAM), InvalidateCurrentScop(false) {}
- void SkipScop(Scop &S) {
- if (Worklist.erase(&S))
- SAM.clear(S);
+ bool invalidateCurrentScop() const { return InvalidateCurrentScop; }
+
+ void invalidateScop(Scop &S) {
+ if (&S == CurrentScop)
+ InvalidateCurrentScop = true;
+
+ Worklist.erase(&S.getRegion());
+ SAM.clear(S);
}
private:
- SmallPriorityWorklist<Scop *, 4> &Worklist;
+ Scop *CurrentScop;
+ bool InvalidateCurrentScop;
+ SmallPriorityWorklist<Region *, 4> &Worklist;
ScopAnalysisManager &SAM;
+ template <typename ScopPassT> friend class FunctionToScopPassAdaptor;
};
template <typename ScopPassT>
@@ -202,10 +210,16 @@ public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
PreservedAnalyses PA = PreservedAnalyses::all();
- auto &Scops = AM.getResult<ScopInfoAnalysis>(F);
- if (Scops.empty())
+ auto &SD = AM.getResult<ScopAnalysis>(F);
+ auto &SI = AM.getResult<ScopInfoAnalysis>(F);
+ if (SI.empty())
return PA;
+ SmallPriorityWorklist<Region *, 4> Worklist;
+ for (auto &S : SI)
+ if (S.second)
+ Worklist.insert(S.first);
+
ScopStandardAnalysisResults AR = {AM.getResult<DominatorTreeAnalysis>(F),
AM.getResult<ScopInfoAnalysis>(F),
AM.getResult<ScalarEvolutionAnalysis>(F),
@@ -215,19 +229,23 @@ public:
ScopAnalysisManager &SAM =
AM.getResult<ScopAnalysisManagerFunctionProxy>(F).getManager();
- SmallPriorityWorklist<Scop *, 4> Worklist;
SPMUpdater Updater{Worklist, SAM};
- for (auto &S : Scops)
- if (auto *scop = S.second.get())
- Worklist.insert(scop);
-
while (!Worklist.empty()) {
- Scop *scop = Worklist.pop_back_val();
+ Region *R = Worklist.pop_back_val();
+ if (!SD.isMaxRegionInScop(*R))
+ continue;
+ Scop *scop = SI.getScop(R);
+ if (!scop)
+ continue;
+ Updater.CurrentScop = scop;
+ Updater.InvalidateCurrentScop = false;
PreservedAnalyses PassPA = Pass.run(*scop, SAM, AR, Updater);
SAM.invalidate(*scop, PassPA);
PA.intersect(std::move(PassPA));
+ if (Updater.invalidateCurrentScop())
+ SI.recompute();
};
PA.preserveSet<AllAnalysesOn<Scop>>();
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 3d2ee793558..69c5d113d83 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -5227,7 +5227,13 @@ INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops",
//===----------------------------------------------------------------------===//
ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE,
LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT,
- AssumptionCache &AC) {
+ AssumptionCache &AC)
+ : DL(DL), SD(SD), SE(SE), LI(LI), AA(AA), DT(DT), AC(AC) {
+ recompute();
+}
+
+void ScopInfo::recompute() {
+ RegionToScopMap.clear();
/// Create polyhedral description of scops for all the valid regions of a
/// function.
for (auto &It : SD) {
@@ -5248,6 +5254,20 @@ ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE,
}
}
+bool ScopInfo::invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv) {
+ // Check whether the analysis, all analyses on functions have been preserved
+ // or anything we're holding references to is being invalidated
+ auto PAC = PA.getChecker<ScopInfoAnalysis>();
+ return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
+ Inv.invalidate<ScopAnalysis>(F, PA) ||
+ Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
+ Inv.invalidate<LoopAnalysis>(F, PA) ||
+ Inv.invalidate<AAManager>(F, PA) ||
+ Inv.invalidate<DominatorTreeAnalysis>(F, PA) ||
+ Inv.invalidate<AssumptionAnalysis>(F, PA);
+}
+
AnalysisKey ScopInfoAnalysis::Key;
ScopInfoAnalysis::Result ScopInfoAnalysis::run(Function &F,
diff --git a/polly/lib/Analysis/ScopPass.cpp b/polly/lib/Analysis/ScopPass.cpp
index cbbb8709238..d0f50167e25 100644
--- a/polly/lib/Analysis/ScopPass.cpp
+++ b/polly/lib/Analysis/ScopPass.cpp
@@ -79,11 +79,11 @@ bool ScopAnalysisManagerFunctionProxy::Result::invalidate(
// 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))) {
+ 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)
diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp
index 9f46715c580..76022d7b594 100644
--- a/polly/lib/CodeGen/CodeGeneration.cpp
+++ b/polly/lib/CodeGen/CodeGeneration.cpp
@@ -328,8 +328,10 @@ PreservedAnalyses
polly::CodeGenerationPass::run(Scop &S, ScopAnalysisManager &SAM,
ScopStandardAnalysisResults &AR, SPMUpdater &U) {
auto &AI = SAM.getResult<IslAstAnalysis>(S, AR);
- if (CodeGen(S, AI, AR.LI, AR.DT, AR.SE, AR.RI))
+ if (CodeGen(S, AI, AR.LI, AR.DT, AR.SE, AR.RI)) {
+ U.invalidateScop(S);
return PreservedAnalyses::none();
+ }
return PreservedAnalyses::all();
}
OpenPOWER on IntegriCloud