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