diff options
Diffstat (limited to 'llvm/lib/IR/PassManager.cpp')
| -rw-r--r-- | llvm/lib/IR/PassManager.cpp | 95 | 
1 files changed, 95 insertions, 0 deletions
| diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp new file mode 100644 index 0000000000000..cde9b873795eb --- /dev/null +++ b/llvm/lib/IR/PassManager.cpp @@ -0,0 +1,95 @@ +//===- PassManager.cpp - Infrastructure for managing & running IR passes --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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; | 
