1 //===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the definitions of the ScopPass members. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "polly/ScopPass.h" 15 #include "polly/ScopInfo.h" 16 17 #include "llvm/Analysis/AssumptionCache.h" 18 19 using namespace llvm; 20 using namespace polly; 21 22 bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) { 23 S = nullptr; 24 25 if (skipRegion(*R)) 26 return false; 27 28 if ((S = getAnalysis<ScopInfoRegionPass>().getScop())) 29 return runOnScop(*S); 30 31 return false; 32 } 33 34 void ScopPass::print(raw_ostream &OS, const Module *M) const { 35 if (S) 36 printScop(OS, *S); 37 } 38 39 void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const { 40 AU.addRequired<ScopInfoRegionPass>(); 41 AU.setPreservesAll(); 42 } 43 44 namespace llvm { 45 46 template class PassManager<Scop, ScopAnalysisManager, 47 ScopStandardAnalysisResults &, SPMUpdater &>; 48 template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>; 49 template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop, 50 ScopStandardAnalysisResults &>; 51 52 template <> 53 PreservedAnalyses 54 PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &, 55 SPMUpdater &>::run(Scop &S, ScopAnalysisManager &AM, 56 ScopStandardAnalysisResults &AR, SPMUpdater &U) { 57 auto PA = PreservedAnalyses::all(); 58 for (auto &Pass : Passes) { 59 auto PassPA = Pass->run(S, AM, AR, U); 60 61 AM.invalidate(S, PassPA); 62 PA.intersect(std::move(PassPA)); 63 } 64 65 // All analyses for 'this' Scop have been invalidated above. 66 // If ScopPasses affect break other scops they have to propagate this 67 // information through the updater 68 PA.preserveSet<AllAnalysesOn<Scop>>(); 69 return PA; 70 } 71 72 bool ScopAnalysisManagerFunctionProxy::Result::invalidate( 73 Function &F, const PreservedAnalyses &PA, 74 FunctionAnalysisManager::Invalidator &Inv) { 75 76 // First, check whether our ScopInfo is about to be invalidated 77 auto PAC = PA.getChecker<ScopAnalysisManagerFunctionProxy>(); 78 if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() || 79 Inv.invalidate<ScopAnalysis>(F, PA) || 80 Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) || 81 Inv.invalidate<LoopAnalysis>(F, PA) || 82 Inv.invalidate<AAManager>(F, PA) || 83 Inv.invalidate<DominatorTreeAnalysis>(F, PA) || 84 Inv.invalidate<AssumptionAnalysis>(F, PA))) { 85 86 // As everything depends on ScopInfo, we must drop all existing results 87 for (auto &S : *SI) 88 if (auto *scop = S.second.get()) 89 if (InnerAM) 90 InnerAM->clear(*scop); 91 92 InnerAM = nullptr; 93 return true; // Invalidate the proxy result as well. 94 } 95 96 bool allPreserved = PA.allAnalysesInSetPreserved<AllAnalysesOn<Scop>>(); 97 98 // Invalidate all non-preserved analyses 99 // Even if all analyses were preserved, we still need to run deferred 100 // invalidation 101 for (auto &S : *SI) { 102 Optional<PreservedAnalyses> InnerPA; 103 auto *scop = S.second.get(); 104 if (!scop) 105 continue; 106 107 if (auto *OuterProxy = 108 InnerAM->getCachedResult<FunctionAnalysisManagerScopProxy>(*scop)) { 109 for (const auto &InvPair : OuterProxy->getOuterInvalidations()) { 110 auto *OuterAnalysisID = InvPair.first; 111 const auto &InnerAnalysisIDs = InvPair.second; 112 113 if (Inv.invalidate(OuterAnalysisID, F, PA)) { 114 if (!InnerPA) 115 InnerPA = PA; 116 for (auto *InnerAnalysisID : InnerAnalysisIDs) 117 InnerPA->abandon(InnerAnalysisID); 118 } 119 } 120 121 if (InnerPA) { 122 InnerAM->invalidate(*scop, *InnerPA); 123 continue; 124 } 125 } 126 127 if (!allPreserved) 128 InnerAM->invalidate(*scop, PA); 129 } 130 131 return false; // This proxy is still valid 132 } 133 134 template <> 135 ScopAnalysisManagerFunctionProxy::Result 136 ScopAnalysisManagerFunctionProxy::run(Function &F, 137 FunctionAnalysisManager &FAM) { 138 return Result(*InnerAM, FAM.getResult<ScopInfoAnalysis>(F)); 139 } 140 } // namespace llvm 141