|  | //===- PassManager.cpp - Infrastructure for managing & running IR passes --===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm/IR/PassManager.h" | 
|  | #include "llvm/ADT/STLExtras.h" | 
|  | #include "llvm/IR/LLVMContext.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | // Explicit template instantiations and specialization defininitions for core | 
|  | // template typedefs. | 
|  | namespace llvm { | 
|  | template class AllAnalysesOn<Module>; | 
|  | template class AllAnalysesOn<Function>; | 
|  | template class PassManager<Module>; | 
|  | template class PassManager<Function>; | 
|  | template class AnalysisManager<Module>; | 
|  | template class AnalysisManager<Function>; | 
|  | template class InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>; | 
|  | template class OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>; | 
|  |  | 
|  | template <> | 
|  | bool FunctionAnalysisManagerModuleProxy::Result::invalidate( | 
|  | Module &M, const PreservedAnalyses &PA, | 
|  | ModuleAnalysisManager::Invalidator &Inv) { | 
|  | // If literally everything is preserved, we're done. | 
|  | if (PA.areAllPreserved()) | 
|  | return false; // This is still a valid proxy. | 
|  |  | 
|  | // If this proxy isn't marked as preserved, then even if the result remains | 
|  | // valid, the key itself may no longer be valid, so we clear everything. | 
|  | // | 
|  | // Note that in order to preserve this proxy, a module pass must ensure that | 
|  | // the FAM has been completely updated to handle the deletion of functions. | 
|  | // Specifically, any FAM-cached results for those functions need to have been | 
|  | // forcibly cleared. When preserved, this proxy will only invalidate results | 
|  | // cached on functions *still in the module* at the end of the module pass. | 
|  | auto PAC = PA.getChecker<FunctionAnalysisManagerModuleProxy>(); | 
|  | if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) { | 
|  | InnerAM->clear(); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Directly check if the relevant set is preserved. | 
|  | bool AreFunctionAnalysesPreserved = | 
|  | PA.allAnalysesInSetPreserved<AllAnalysesOn<Function>>(); | 
|  |  | 
|  | // Now walk all the functions to see if any inner analysis invalidation is | 
|  | // necessary. | 
|  | for (Function &F : M) { | 
|  | Optional<PreservedAnalyses> FunctionPA; | 
|  |  | 
|  | // Check to see whether the preserved set needs to be pruned based on | 
|  | // module-level analysis invalidation that triggers deferred invalidation | 
|  | // registered with the outer analysis manager proxy for this function. | 
|  | if (auto *OuterProxy = | 
|  | InnerAM->getCachedResult<ModuleAnalysisManagerFunctionProxy>(F)) | 
|  | for (const auto &OuterInvalidationPair : | 
|  | OuterProxy->getOuterInvalidations()) { | 
|  | AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first; | 
|  | const auto &InnerAnalysisIDs = OuterInvalidationPair.second; | 
|  | if (Inv.invalidate(OuterAnalysisID, M, PA)) { | 
|  | if (!FunctionPA) | 
|  | FunctionPA = PA; | 
|  | for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs) | 
|  | FunctionPA->abandon(InnerAnalysisID); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Check if we needed a custom PA set, and if so we'll need to run the | 
|  | // inner invalidation. | 
|  | if (FunctionPA) { | 
|  | InnerAM->invalidate(F, *FunctionPA); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | // Otherwise we only need to do invalidation if the original PA set didn't | 
|  | // preserve all function analyses. | 
|  | if (!AreFunctionAnalysesPreserved) | 
|  | InnerAM->invalidate(F, PA); | 
|  | } | 
|  |  | 
|  | // Return false to indicate that this result is still a valid proxy. | 
|  | return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | AnalysisSetKey CFGAnalyses::SetKey; | 
|  |  | 
|  | AnalysisSetKey PreservedAnalyses::AllAnalysesKey; |