//===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file contains the definitions of the ScopPass members. // //===----------------------------------------------------------------------===// #include "polly/ScopPass.h" #include "polly/ScopInfo.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetTransformInfo.h" using namespace llvm; using namespace polly; bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) { S = nullptr; if (skipRegion(*R)) return false; if ((S = getAnalysis().getScop())) return runOnScop(*S); return false; } void ScopPass::print(raw_ostream &OS, const Module *M) const { if (S) printScop(OS, *S); } void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); 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 { template class OwningInnerAnalysisManagerProxy; } namespace llvm { template class PassManager; template class InnerAnalysisManagerProxy; template class OuterAnalysisManagerProxy; template <> PreservedAnalyses PassManager::run(Scop &S, ScopAnalysisManager &AM, ScopStandardAnalysisResults &AR, SPMUpdater &U) { auto PA = PreservedAnalyses::all(); for (auto &Pass : Passes) { auto PassPA = Pass->run(S, AM, AR, U); AM.invalidate(S, PassPA); PA.intersect(std::move(PassPA)); } // All analyses for 'this' Scop have been invalidated above. // If ScopPasses affect break other scops they have to propagate this // information through the updater PA.preserveSet>(); return PA; } bool ScopAnalysisManagerFunctionProxy::Result::invalidate( Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv) { // First, check whether our ScopInfo is about to be invalidated auto PAC = PA.getChecker(); if (!(PAC.preserved() || PAC.preservedSet>()) || Inv.invalidate(F, PA) || Inv.invalidate(F, PA) || Inv.invalidate(F, PA) || Inv.invalidate(F, PA)) { // As everything depends on ScopInfo, we must drop all existing results for (auto &S : *SI) if (auto *scop = S.second.get()) if (InnerAM) InnerAM->clear(*scop, scop->getName()); InnerAM = nullptr; return true; // Invalidate the proxy result as well. } bool allPreserved = PA.allAnalysesInSetPreserved>(); // Invalidate all non-preserved analyses // Even if all analyses were preserved, we still need to run deferred // invalidation for (auto &S : *SI) { Optional InnerPA; auto *scop = S.second.get(); if (!scop) continue; if (auto *OuterProxy = InnerAM->getCachedResult(*scop)) { for (const auto &InvPair : OuterProxy->getOuterInvalidations()) { auto *OuterAnalysisID = InvPair.first; const auto &InnerAnalysisIDs = InvPair.second; if (Inv.invalidate(OuterAnalysisID, F, PA)) { if (!InnerPA) InnerPA = PA; for (auto *InnerAnalysisID : InnerAnalysisIDs) InnerPA->abandon(InnerAnalysisID); } } if (InnerPA) { InnerAM->invalidate(*scop, *InnerPA); continue; } } if (!allPreserved) InnerAM->invalidate(*scop, PA); } return false; // This proxy is still valid } template <> ScopAnalysisManagerFunctionProxy::Result ScopAnalysisManagerFunctionProxy::run(Function &F, FunctionAnalysisManager &FAM) { return Result(*InnerAM, FAM.getResult(F)); } } // namespace llvm namespace polly { template <> OwningScopAnalysisManagerFunctionProxy::Result OwningScopAnalysisManagerFunctionProxy::run(Function &F, FunctionAnalysisManager &FAM) { return Result(InnerAM, FAM.getResult(F)); } } // namespace polly