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 #include "llvm/Analysis/BasicAliasAnalysis.h" 19 #include "llvm/Analysis/GlobalsModRef.h" 20 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 21 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 22 #include "llvm/Analysis/TargetTransformInfo.h" 23 24 using namespace llvm; 25 using namespace polly; 26 27 bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) { 28 S = nullptr; 29 30 if (skipRegion(*R)) 31 return false; 32 33 if ((S = getAnalysis<ScopInfoRegionPass>().getScop())) 34 return runOnScop(*S); 35 36 return false; 37 } 38 39 void ScopPass::print(raw_ostream &OS, const Module *M) const { 40 if (S) 41 printScop(OS, *S); 42 } 43 44 void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const { 45 AU.addRequired<ScopInfoRegionPass>(); 46 47 AU.addPreserved<AAResultsWrapperPass>(); 48 AU.addPreserved<BasicAAWrapperPass>(); 49 AU.addPreserved<LoopInfoWrapperPass>(); 50 AU.addPreserved<DominatorTreeWrapperPass>(); 51 AU.addPreserved<GlobalsAAWrapperPass>(); 52 AU.addPreserved<ScopDetectionWrapperPass>(); 53 AU.addPreserved<ScalarEvolutionWrapperPass>(); 54 AU.addPreserved<SCEVAAWrapperPass>(); 55 AU.addPreserved<OptimizationRemarkEmitterWrapperPass>(); 56 AU.addPreserved<RegionInfoPass>(); 57 AU.addPreserved<ScopInfoRegionPass>(); 58 AU.addPreserved<TargetTransformInfoWrapperPass>(); 59 } 60 61 namespace polly { 62 template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>; 63 } 64 65 namespace llvm { 66 67 template class PassManager<Scop, ScopAnalysisManager, 68 ScopStandardAnalysisResults &, SPMUpdater &>; 69 template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>; 70 template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop, 71 ScopStandardAnalysisResults &>; 72 73 template <> 74 PreservedAnalyses 75 PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &, 76 SPMUpdater &>::run(Scop &S, ScopAnalysisManager &AM, 77 ScopStandardAnalysisResults &AR, SPMUpdater &U) { 78 auto PA = PreservedAnalyses::all(); 79 for (auto &Pass : Passes) { 80 auto PassPA = Pass->run(S, AM, AR, U); 81 82 AM.invalidate(S, PassPA); 83 PA.intersect(std::move(PassPA)); 84 } 85 86 // All analyses for 'this' Scop have been invalidated above. 87 // If ScopPasses affect break other scops they have to propagate this 88 // information through the updater 89 PA.preserveSet<AllAnalysesOn<Scop>>(); 90 return PA; 91 } 92 93 bool ScopAnalysisManagerFunctionProxy::Result::invalidate( 94 Function &F, const PreservedAnalyses &PA, 95 FunctionAnalysisManager::Invalidator &Inv) { 96 97 // First, check whether our ScopInfo is about to be invalidated 98 auto PAC = PA.getChecker<ScopAnalysisManagerFunctionProxy>(); 99 if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) || 100 Inv.invalidate<ScopInfoAnalysis>(F, PA) || 101 Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) || 102 Inv.invalidate<LoopAnalysis>(F, PA) || 103 Inv.invalidate<DominatorTreeAnalysis>(F, PA)) { 104 105 // As everything depends on ScopInfo, we must drop all existing results 106 for (auto &S : *SI) 107 if (auto *scop = S.second.get()) 108 if (InnerAM) 109 InnerAM->clear(*scop, scop->getName()); 110 111 InnerAM = nullptr; 112 return true; // Invalidate the proxy result as well. 113 } 114 115 bool allPreserved = PA.allAnalysesInSetPreserved<AllAnalysesOn<Scop>>(); 116 117 // Invalidate all non-preserved analyses 118 // Even if all analyses were preserved, we still need to run deferred 119 // invalidation 120 for (auto &S : *SI) { 121 Optional<PreservedAnalyses> InnerPA; 122 auto *scop = S.second.get(); 123 if (!scop) 124 continue; 125 126 if (auto *OuterProxy = 127 InnerAM->getCachedResult<FunctionAnalysisManagerScopProxy>(*scop)) { 128 for (const auto &InvPair : OuterProxy->getOuterInvalidations()) { 129 auto *OuterAnalysisID = InvPair.first; 130 const auto &InnerAnalysisIDs = InvPair.second; 131 132 if (Inv.invalidate(OuterAnalysisID, F, PA)) { 133 if (!InnerPA) 134 InnerPA = PA; 135 for (auto *InnerAnalysisID : InnerAnalysisIDs) 136 InnerPA->abandon(InnerAnalysisID); 137 } 138 } 139 140 if (InnerPA) { 141 InnerAM->invalidate(*scop, *InnerPA); 142 continue; 143 } 144 } 145 146 if (!allPreserved) 147 InnerAM->invalidate(*scop, PA); 148 } 149 150 return false; // This proxy is still valid 151 } 152 153 template <> 154 ScopAnalysisManagerFunctionProxy::Result 155 ScopAnalysisManagerFunctionProxy::run(Function &F, 156 FunctionAnalysisManager &FAM) { 157 return Result(*InnerAM, FAM.getResult<ScopInfoAnalysis>(F)); 158 } 159 } // namespace llvm 160 161 namespace polly { 162 template <> 163 OwningScopAnalysisManagerFunctionProxy::Result 164 OwningScopAnalysisManagerFunctionProxy::run(Function &F, 165 FunctionAnalysisManager &FAM) { 166 return Result(InnerAM, FAM.getResult<ScopInfoAnalysis>(F)); 167 } 168 } // namespace polly 169