From a4f447c2a43194f6fb1ab7c9312b9a0f49b01d14 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Mon, 28 Aug 2017 14:07:33 +0000 Subject: [PATCH] [PM] Properly require and preserve OptimizationRemarkEmitter. NFCI. Properly require and preserve the OptimizationRemarkEmitter for use in ScopPass. Previously one had to get the ORE from ScopDetection because CodeGeneration did not mark it as preserved. It would need to be recomputed which results in the legacy PM to throw away all previous SCoP analysis. This also changes the implementation of ScopPass::getAnalysisUsage to not unconditionally preserve all passes, but only those needed to be preserved by any SCoP pass (at least when using the legacy PM). This allows invalidating DependenceInfo (and IslAstInfo) in case the pass would cause them to change (e.g. OpTree, DeLICM, MaximalArrayExpansion) JSONImporter should also invalidate the DependenceInfo. In this patch it marks DependenceInfo as preserved anyway because some regression tests depend on it. Differential Revision: https://reviews.llvm.org/D37010 llvm-svn: 311888 --- polly/include/polly/ScopBuilder.h | 6 ++++-- polly/include/polly/ScopDetection.h | 1 + polly/include/polly/ScopInfo.h | 3 ++- polly/lib/Analysis/ScopBuilder.cpp | 22 ++++++++++++---------- polly/lib/Analysis/ScopInfo.cpp | 17 +++++++++++------ polly/lib/Analysis/ScopPass.cpp | 19 ++++++++++++++++++- polly/lib/CodeGen/CodeGeneration.cpp | 13 ++----------- polly/lib/CodeGen/IslAst.cpp | 2 ++ polly/lib/CodeGen/PPCGCodeGeneration.cpp | 13 ++----------- polly/lib/Exchange/JSONExporter.cpp | 3 +++ polly/lib/Transform/ScheduleOptimizer.cpp | 2 ++ 11 files changed, 59 insertions(+), 42 deletions(-) diff --git a/polly/include/polly/ScopBuilder.h b/polly/include/polly/ScopBuilder.h index 5336cbbba4f46..a890d925e065c 100644 --- a/polly/include/polly/ScopBuilder.h +++ b/polly/include/polly/ScopBuilder.h @@ -143,7 +143,8 @@ class ScopBuilder { // @} // Build the SCoP for Region @p R. - void buildScop(Region &R, AssumptionCache &AC); + void buildScop(Region &R, AssumptionCache &AC, + OptimizationRemarkEmitter &ORE); /// Try to build a multi-dimensional fixed sized MemoryAccess from the /// Load/Store instruction. @@ -337,7 +338,8 @@ class ScopBuilder { public: explicit ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA, const DataLayout &DL, DominatorTree &DT, LoopInfo &LI, - ScopDetection &SD, ScalarEvolution &SE); + ScopDetection &SD, ScalarEvolution &SE, + OptimizationRemarkEmitter &ORE); ScopBuilder(const ScopBuilder &) = delete; ScopBuilder &operator=(const ScopBuilder &) = delete; ~ScopBuilder() = default; diff --git a/polly/include/polly/ScopDetection.h b/polly/include/polly/ScopDetection.h index cd50a77fa04e0..7e61c06cf9cef 100644 --- a/polly/include/polly/ScopDetection.h +++ b/polly/include/polly/ScopDetection.h @@ -630,6 +630,7 @@ class ScopDetection { countBeneficialLoops(Region *R, ScalarEvolution &SE, LoopInfo &LI, unsigned MinProfitableTrips); +private: /// OptimizationRemarkEmitter object used to emit diagnostic remarks OptimizationRemarkEmitter &ORE; }; diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index bba8405d03e31..98e17ba6b58bc 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -3096,11 +3096,12 @@ class ScopInfo { AliasAnalysis &AA; DominatorTree &DT; AssumptionCache &AC; + OptimizationRemarkEmitter &ORE; public: ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE, LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT, - AssumptionCache &AC); + AssumptionCache &AC, OptimizationRemarkEmitter &ORE); /// Get the Scop object for the given Region. /// diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp index 720b5f3f1e615..3355546d99826 100644 --- a/polly/lib/Analysis/ScopBuilder.cpp +++ b/polly/lib/Analysis/ScopBuilder.cpp @@ -964,8 +964,9 @@ static inline BasicBlock *getRegionNodeBasicBlock(RegionNode *RN) { : RN->getNodeAs(); } -void ScopBuilder::buildScop(Region &R, AssumptionCache &AC) { - scop.reset(new Scop(R, SE, LI, *SD.getDetectionContext(&R), SD.ORE)); +void ScopBuilder::buildScop(Region &R, AssumptionCache &AC, + OptimizationRemarkEmitter &ORE) { + scop.reset(new Scop(R, SE, LI, *SD.getDetectionContext(&R), ORE)); buildStmts(R); buildAccessFunctions(); @@ -1064,17 +1065,18 @@ void ScopBuilder::buildScop(Region &R, AssumptionCache &AC) { ScopBuilder::ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA, const DataLayout &DL, DominatorTree &DT, LoopInfo &LI, - ScopDetection &SD, ScalarEvolution &SE) + ScopDetection &SD, ScalarEvolution &SE, + OptimizationRemarkEmitter &ORE) : AA(AA), DL(DL), DT(DT), LI(LI), SD(SD), SE(SE) { DebugLoc Beg, End; auto P = getBBPairForRegion(R); getDebugLocations(P, Beg, End); std::string Msg = "SCoP begins here."; - SD.ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEntry", Beg, P.first) - << Msg); + ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEntry", Beg, P.first) + << Msg); - buildScop(*R, AC); + buildScop(*R, AC, ORE); DEBUG(dbgs() << *scop); @@ -1090,9 +1092,9 @@ ScopBuilder::ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA, } if (R->isTopLevelRegion()) - SD.ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.first) - << Msg); + ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.first) + << Msg); else - SD.ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.second) - << Msg); + ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.second) + << Msg); } diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 4941b24220234..55eef18ab0083 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -5230,6 +5230,7 @@ void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredTransitive(); AU.addRequired(); AU.addRequired(); + AU.addRequired(); AU.setPreservesAll(); } @@ -5279,8 +5280,9 @@ bool ScopInfoRegionPass::runOnRegion(Region *R, RGPassManager &RGM) { auto const &DL = F->getParent()->getDataLayout(); auto &DT = getAnalysis().getDomTree(); auto &AC = getAnalysis().getAssumptionCache(*F); + auto &ORE = getAnalysis().getORE(); - ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE); + 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) @@ -5322,8 +5324,8 @@ INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops", //===----------------------------------------------------------------------===// ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE, LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT, - AssumptionCache &AC) - : DL(DL), SD(SD), SE(SE), LI(LI), AA(AA), DT(DT), AC(AC) { + AssumptionCache &AC, OptimizationRemarkEmitter &ORE) + : DL(DL), SD(SD), SE(SE), LI(LI), AA(AA), DT(DT), AC(AC), ORE(ORE) { recompute(); } @@ -5336,7 +5338,7 @@ void ScopInfo::recompute() { if (!SD.isMaxRegionInScop(*R)) continue; - ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE); + ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE); std::unique_ptr S = SB.getScop(); if (!S) continue; @@ -5376,7 +5378,8 @@ ScopInfoAnalysis::Result ScopInfoAnalysis::run(Function &F, auto &DT = FAM.getResult(F); auto &AC = FAM.getResult(F); auto &DL = F.getParent()->getDataLayout(); - return {DL, SD, SE, LI, AA, DT, AC}; + auto &ORE = FAM.getResult(F); + return {DL, SD, SE, LI, AA, DT, AC, ORE}; } PreservedAnalyses ScopInfoPrinterPass::run(Function &F, @@ -5401,6 +5404,7 @@ void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredTransitive(); AU.addRequired(); AU.addRequired(); + AU.addRequired(); AU.setPreservesAll(); } @@ -5412,8 +5416,9 @@ bool ScopInfoWrapperPass::runOnFunction(Function &F) { auto const &DL = F.getParent()->getDataLayout(); auto &DT = getAnalysis().getDomTree(); auto &AC = getAnalysis().getAssumptionCache(F); + auto &ORE = getAnalysis().getORE(); - Result.reset(new ScopInfo{DL, SD, SE, LI, AA, DT, AC}); + Result.reset(new ScopInfo{DL, SD, SE, LI, AA, DT, AC, ORE}); return false; } diff --git a/polly/lib/Analysis/ScopPass.cpp b/polly/lib/Analysis/ScopPass.cpp index d0f50167e2585..105acdf41cd3a 100644 --- a/polly/lib/Analysis/ScopPass.cpp +++ b/polly/lib/Analysis/ScopPass.cpp @@ -15,6 +15,11 @@ #include "polly/ScopInfo.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/OptimizationDiagnosticInfo.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" +#include "llvm/Analysis/TargetTransformInfo.h" using namespace llvm; using namespace polly; @@ -38,7 +43,19 @@ void ScopPass::print(raw_ostream &OS, const Module *M) const { void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); - AU.setPreservesAll(); + + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); } namespace polly { diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index 2e42add56c6b6..240ce23c1b469 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -333,6 +333,8 @@ class CodeGeneration : public ScopPass { /// Register all analyses and transformation required. void getAnalysisUsage(AnalysisUsage &AU) const override { + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -342,21 +344,10 @@ class CodeGeneration : public ScopPass { AU.addRequired(); AU.addPreserved(); - - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); // FIXME: We do not yet add regions for the newly generated code to the // region tree. - AU.addPreserved(); - AU.addPreserved(); } }; diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp index 32e22cee57df4..b1204e01a5bad 100644 --- a/polly/lib/CodeGen/IslAst.cpp +++ b/polly/lib/CodeGen/IslAst.cpp @@ -771,6 +771,8 @@ void IslAstInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { ScopPass::getAnalysisUsage(AU); AU.addRequired(); AU.addRequired(); + + AU.addPreserved(); } void IslAstInfoWrapperPass::printScop(raw_ostream &OS, Scop &S) const { diff --git a/polly/lib/CodeGen/PPCGCodeGeneration.cpp b/polly/lib/CodeGen/PPCGCodeGeneration.cpp index 61c3fd0bc6cb3..21edbc7be1acf 100644 --- a/polly/lib/CodeGen/PPCGCodeGeneration.cpp +++ b/polly/lib/CodeGen/PPCGCodeGeneration.cpp @@ -3520,6 +3520,8 @@ class PPCGCodeGeneration : public ScopPass { void printScop(raw_ostream &, Scop &) const override {} void getAnalysisUsage(AnalysisUsage &AU) const override { + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -3527,19 +3529,8 @@ class PPCGCodeGeneration : public ScopPass { AU.addRequired(); AU.addRequired(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - // FIXME: We do not yet add regions for the newly generated code to the // region tree. - AU.addPreserved(); - AU.addPreserved(); } }; } // namespace diff --git a/polly/lib/Exchange/JSONExporter.cpp b/polly/lib/Exchange/JSONExporter.cpp index 289cfebaa4518..6bf4198e904df 100644 --- a/polly/lib/Exchange/JSONExporter.cpp +++ b/polly/lib/Exchange/JSONExporter.cpp @@ -792,6 +792,9 @@ bool JSONImporter::runOnScop(Scop &S) { void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const { ScopPass::getAnalysisUsage(AU); AU.addRequired(); + + // TODO: JSONImporter should throw away DependenceInfo. + AU.addPreserved(); } Pass *polly::createJSONImporterPass() { return new JSONImporter(); } diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp index 99e01f2bcb9e0..93dea294ce19b 100644 --- a/polly/lib/Transform/ScheduleOptimizer.cpp +++ b/polly/lib/Transform/ScheduleOptimizer.cpp @@ -1591,6 +1591,8 @@ void IslScheduleOptimizer::getAnalysisUsage(AnalysisUsage &AU) const { ScopPass::getAnalysisUsage(AU); AU.addRequired(); AU.addRequired(); + + AU.addPreserved(); } Pass *polly::createIslScheduleOptimizerPass() {