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