Home | History | Annotate | Line # | Download | only in IR
      1 //===- PassManager.cpp - Infrastructure for managing & running IR passes --===//
      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 #include "llvm/IR/PassManager.h"
     10 #include "llvm/ADT/STLExtras.h"
     11 #include "llvm/IR/LLVMContext.h"
     12 #include "llvm/IR/PassManagerImpl.h"
     13 
     14 using namespace llvm;
     15 
     16 // Explicit template instantiations and specialization defininitions for core
     17 // template typedefs.
     18 namespace llvm {
     19 template class AllAnalysesOn<Module>;
     20 template class AllAnalysesOn<Function>;
     21 template class PassManager<Module>;
     22 template class PassManager<Function>;
     23 template class AnalysisManager<Module>;
     24 template class AnalysisManager<Function>;
     25 template class InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
     26 template class OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
     27 
     28 template <>
     29 bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
     30     Module &M, const PreservedAnalyses &PA,
     31     ModuleAnalysisManager::Invalidator &Inv) {
     32   // If literally everything is preserved, we're done.
     33   if (PA.areAllPreserved())
     34     return false; // This is still a valid proxy.
     35 
     36   // If this proxy isn't marked as preserved, then even if the result remains
     37   // valid, the key itself may no longer be valid, so we clear everything.
     38   //
     39   // Note that in order to preserve this proxy, a module pass must ensure that
     40   // the FAM has been completely updated to handle the deletion of functions.
     41   // Specifically, any FAM-cached results for those functions need to have been
     42   // forcibly cleared. When preserved, this proxy will only invalidate results
     43   // cached on functions *still in the module* at the end of the module pass.
     44   auto PAC = PA.getChecker<FunctionAnalysisManagerModuleProxy>();
     45   if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
     46     InnerAM->clear();
     47     return true;
     48   }
     49 
     50   // Directly check if the relevant set is preserved.
     51   bool AreFunctionAnalysesPreserved =
     52       PA.allAnalysesInSetPreserved<AllAnalysesOn<Function>>();
     53 
     54   // Now walk all the functions to see if any inner analysis invalidation is
     55   // necessary.
     56   for (Function &F : M) {
     57     Optional<PreservedAnalyses> FunctionPA;
     58 
     59     // Check to see whether the preserved set needs to be pruned based on
     60     // module-level analysis invalidation that triggers deferred invalidation
     61     // registered with the outer analysis manager proxy for this function.
     62     if (auto *OuterProxy =
     63             InnerAM->getCachedResult<ModuleAnalysisManagerFunctionProxy>(F))
     64       for (const auto &OuterInvalidationPair :
     65            OuterProxy->getOuterInvalidations()) {
     66         AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first;
     67         const auto &InnerAnalysisIDs = OuterInvalidationPair.second;
     68         if (Inv.invalidate(OuterAnalysisID, M, PA)) {
     69           if (!FunctionPA)
     70             FunctionPA = PA;
     71           for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs)
     72             FunctionPA->abandon(InnerAnalysisID);
     73         }
     74       }
     75 
     76     // Check if we needed a custom PA set, and if so we'll need to run the
     77     // inner invalidation.
     78     if (FunctionPA) {
     79       InnerAM->invalidate(F, *FunctionPA);
     80       continue;
     81     }
     82 
     83     // Otherwise we only need to do invalidation if the original PA set didn't
     84     // preserve all function analyses.
     85     if (!AreFunctionAnalysesPreserved)
     86       InnerAM->invalidate(F, PA);
     87   }
     88 
     89   // Return false to indicate that this result is still a valid proxy.
     90   return false;
     91 }
     92 } // namespace llvm
     93 
     94 PreservedAnalyses ModuleToFunctionPassAdaptor::run(Module &M,
     95                                                    ModuleAnalysisManager &AM) {
     96   FunctionAnalysisManager &FAM =
     97       AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
     98 
     99   // Request PassInstrumentation from analysis manager, will use it to run
    100   // instrumenting callbacks for the passes later.
    101   PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
    102 
    103   PreservedAnalyses PA = PreservedAnalyses::all();
    104   for (Function &F : M) {
    105     if (F.isDeclaration())
    106       continue;
    107 
    108     // Check the PassInstrumentation's BeforePass callbacks before running the
    109     // pass, skip its execution completely if asked to (callback returns
    110     // false).
    111     if (!PI.runBeforePass<Function>(*Pass, F))
    112       continue;
    113 
    114     PreservedAnalyses PassPA;
    115     {
    116       TimeTraceScope TimeScope(Pass->name(), F.getName());
    117       PassPA = Pass->run(F, FAM);
    118     }
    119 
    120     PI.runAfterPass(*Pass, F, PassPA);
    121 
    122     // We know that the function pass couldn't have invalidated any other
    123     // function's analyses (that's the contract of a function pass), so
    124     // directly handle the function analysis manager's invalidation here.
    125     FAM.invalidate(F, PassPA);
    126 
    127     // Then intersect the preserved set so that invalidation of module
    128     // analyses will eventually occur when the module pass completes.
    129     PA.intersect(std::move(PassPA));
    130   }
    131 
    132   // The FunctionAnalysisManagerModuleProxy is preserved because (we assume)
    133   // the function passes we ran didn't add or remove any functions.
    134   //
    135   // We also preserve all analyses on Functions, because we did all the
    136   // invalidation we needed to do above.
    137   PA.preserveSet<AllAnalysesOn<Function>>();
    138   PA.preserve<FunctionAnalysisManagerModuleProxy>();
    139   return PA;
    140 }
    141 
    142 AnalysisSetKey CFGAnalyses::SetKey;
    143 
    144 AnalysisSetKey PreservedAnalyses::AllAnalysesKey;
    145