2011-04-29 14:27:02 +08:00
|
|
|
//===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains the definitions of the ScopPass members.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "polly/ScopPass.h"
|
|
|
|
#include "polly/ScopInfo.h"
|
|
|
|
|
2017-05-15 21:43:01 +08:00
|
|
|
#include "llvm/Analysis/AssumptionCache.h"
|
|
|
|
|
2011-04-29 14:27:02 +08:00
|
|
|
using namespace llvm;
|
|
|
|
using namespace polly;
|
|
|
|
|
|
|
|
bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) {
|
2014-11-14 19:12:31 +08:00
|
|
|
S = nullptr;
|
2011-04-29 14:27:02 +08:00
|
|
|
|
2017-06-02 05:29:05 +08:00
|
|
|
if (skipRegion(*R))
|
|
|
|
return false;
|
|
|
|
|
2016-05-31 17:41:04 +08:00
|
|
|
if ((S = getAnalysis<ScopInfoRegionPass>().getScop()))
|
2011-04-29 14:27:02 +08:00
|
|
|
return runOnScop(*S);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScopPass::print(raw_ostream &OS, const Module *M) const {
|
|
|
|
if (S)
|
2015-03-02 02:40:25 +08:00
|
|
|
printScop(OS, *S);
|
2011-04-29 14:27:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
2016-05-31 17:41:04 +08:00
|
|
|
AU.addRequired<ScopInfoRegionPass>();
|
2011-04-29 14:27:02 +08:00
|
|
|
AU.setPreservesAll();
|
|
|
|
}
|
2017-05-15 21:43:01 +08:00
|
|
|
|
|
|
|
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>>() ||
|
[PM] Fix proxy invalidation
Summary: I made a mistake in handling transitive invalidation of analysis results. I've updated the list of preserved analyses as well as the correct result dependences.
The Invalidator passed through the invalidate() path can be used to
transitively invalidate analyses. It frequently happens that analysis
results depend on other analyses, and thus store references to their
results. When the dependee now gets invalidated, the depender needs to
be invalidated as well. This is the purpose of the Invalidator object,
which can be used to check whether some dependee analysis is in the
process of being invalidated. I originally was checking the wrong
dependee analyses, which is an actual error, you can only check analysis
results that are in the cache (which they are if you've captured their
reference). The invalidation I'm handling inside the proxy deals with
the standard analyses the proxy passes into the Scop pipeline, since I'm
capturing their reference.
This checking allows us to actually preserve a couple of results outside
of the proxy, since the Scop pipeline shouldn't break those, or
otherwise should update them accordingly.
Reviewers: grosser, Meinersbur, bollu
Reviewed By: grosser
Subscribers: pollydev, llvm-commits
Differential Revision: https://reviews.llvm.org/D36216
llvm-svn: 309811
2017-08-02 21:18:49 +08:00
|
|
|
Inv.invalidate<ScopInfoAnalysis>(F, PA) ||
|
2017-05-15 21:43:01 +08:00
|
|
|
Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
|
|
|
|
Inv.invalidate<LoopAnalysis>(F, PA) ||
|
[PM] Fix proxy invalidation
Summary: I made a mistake in handling transitive invalidation of analysis results. I've updated the list of preserved analyses as well as the correct result dependences.
The Invalidator passed through the invalidate() path can be used to
transitively invalidate analyses. It frequently happens that analysis
results depend on other analyses, and thus store references to their
results. When the dependee now gets invalidated, the depender needs to
be invalidated as well. This is the purpose of the Invalidator object,
which can be used to check whether some dependee analysis is in the
process of being invalidated. I originally was checking the wrong
dependee analyses, which is an actual error, you can only check analysis
results that are in the cache (which they are if you've captured their
reference). The invalidation I'm handling inside the proxy deals with
the standard analyses the proxy passes into the Scop pipeline, since I'm
capturing their reference.
This checking allows us to actually preserve a couple of results outside
of the proxy, since the Scop pipeline shouldn't break those, or
otherwise should update them accordingly.
Reviewers: grosser, Meinersbur, bollu
Reviewed By: grosser
Subscribers: pollydev, llvm-commits
Differential Revision: https://reviews.llvm.org/D36216
llvm-svn: 309811
2017-08-02 21:18:49 +08:00
|
|
|
Inv.invalidate<DominatorTreeAnalysis>(F, PA))) {
|
2017-05-15 21:43:01 +08:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
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) {
|
|
|
|
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
|