Home | History | Annotate | Download | only in IR
      1 //===- PassManager.cpp - Infrastructure for managing & running IR passes --===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/ADT/STLExtras.h"
     11 #include "llvm/IR/LLVMContext.h"
     12 #include "llvm/IR/PassManager.h"
     13 #include "llvm/Support/CommandLine.h"
     14 #include "llvm/Support/Debug.h"
     15 
     16 using namespace llvm;
     17 
     18 static cl::opt<bool>
     19 DebugPM("debug-pass-manager", cl::Hidden,
     20         cl::desc("Print pass management debugging information"));
     21 
     22 PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) {
     23   PreservedAnalyses PA = PreservedAnalyses::all();
     24 
     25   if (DebugPM)
     26     dbgs() << "Starting module pass manager run.\n";
     27 
     28   for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
     29     if (DebugPM)
     30       dbgs() << "Running module pass: " << Passes[Idx]->name() << "\n";
     31 
     32     PreservedAnalyses PassPA = Passes[Idx]->run(M, AM);
     33     if (AM)
     34       AM->invalidate(M, PassPA);
     35     PA.intersect(std::move(PassPA));
     36 
     37     M->getContext().yield();
     38   }
     39 
     40   if (DebugPM)
     41     dbgs() << "Finished module pass manager run.\n";
     42 
     43   return PA;
     44 }
     45 
     46 ModuleAnalysisManager::ResultConceptT &
     47 ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) {
     48   ModuleAnalysisResultMapT::iterator RI;
     49   bool Inserted;
     50   std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
     51       PassID, std::unique_ptr<detail::AnalysisResultConcept<Module *>>()));
     52 
     53   // If we don't have a cached result for this module, look up the pass and run
     54   // it to produce a result, which we then add to the cache.
     55   if (Inserted)
     56     RI->second = std::move(lookupPass(PassID).run(M, this));
     57 
     58   return *RI->second;
     59 }
     60 
     61 ModuleAnalysisManager::ResultConceptT *
     62 ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const {
     63   ModuleAnalysisResultMapT::const_iterator RI =
     64       ModuleAnalysisResults.find(PassID);
     65   return RI == ModuleAnalysisResults.end() ? nullptr : &*RI->second;
     66 }
     67 
     68 void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
     69   ModuleAnalysisResults.erase(PassID);
     70 }
     71 
     72 void ModuleAnalysisManager::invalidateImpl(Module *M,
     73                                            const PreservedAnalyses &PA) {
     74   // FIXME: This is a total hack based on the fact that erasure doesn't
     75   // invalidate iteration for DenseMap.
     76   for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(),
     77                                           E = ModuleAnalysisResults.end();
     78        I != E; ++I)
     79     if (I->second->invalidate(M, PA))
     80       ModuleAnalysisResults.erase(I);
     81 }
     82 
     83 PreservedAnalyses FunctionPassManager::run(Function *F,
     84                                            FunctionAnalysisManager *AM) {
     85   PreservedAnalyses PA = PreservedAnalyses::all();
     86 
     87   if (DebugPM)
     88     dbgs() << "Starting function pass manager run.\n";
     89 
     90   for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
     91     if (DebugPM)
     92       dbgs() << "Running function pass: " << Passes[Idx]->name() << "\n";
     93 
     94     PreservedAnalyses PassPA = Passes[Idx]->run(F, AM);
     95     if (AM)
     96       AM->invalidate(F, PassPA);
     97     PA.intersect(std::move(PassPA));
     98 
     99     F->getContext().yield();
    100   }
    101 
    102   if (DebugPM)
    103     dbgs() << "Finished function pass manager run.\n";
    104 
    105   return PA;
    106 }
    107 
    108 bool FunctionAnalysisManager::empty() const {
    109   assert(FunctionAnalysisResults.empty() ==
    110              FunctionAnalysisResultLists.empty() &&
    111          "The storage and index of analysis results disagree on how many there "
    112          "are!");
    113   return FunctionAnalysisResults.empty();
    114 }
    115 
    116 void FunctionAnalysisManager::clear() {
    117   FunctionAnalysisResults.clear();
    118   FunctionAnalysisResultLists.clear();
    119 }
    120 
    121 FunctionAnalysisManager::ResultConceptT &
    122 FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
    123   FunctionAnalysisResultMapT::iterator RI;
    124   bool Inserted;
    125   std::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
    126       std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator()));
    127 
    128   // If we don't have a cached result for this function, look up the pass and
    129   // run it to produce a result, which we then add to the cache.
    130   if (Inserted) {
    131     FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F];
    132     ResultList.emplace_back(PassID, lookupPass(PassID).run(F, this));
    133     RI->second = std::prev(ResultList.end());
    134   }
    135 
    136   return *RI->second->second;
    137 }
    138 
    139 FunctionAnalysisManager::ResultConceptT *
    140 FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const {
    141   FunctionAnalysisResultMapT::const_iterator RI =
    142       FunctionAnalysisResults.find(std::make_pair(PassID, F));
    143   return RI == FunctionAnalysisResults.end() ? nullptr : &*RI->second->second;
    144 }
    145 
    146 void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
    147   FunctionAnalysisResultMapT::iterator RI =
    148       FunctionAnalysisResults.find(std::make_pair(PassID, F));
    149   if (RI == FunctionAnalysisResults.end())
    150     return;
    151 
    152   FunctionAnalysisResultLists[F].erase(RI->second);
    153 }
    154 
    155 void FunctionAnalysisManager::invalidateImpl(Function *F,
    156                                              const PreservedAnalyses &PA) {
    157   // Clear all the invalidated results associated specifically with this
    158   // function.
    159   SmallVector<void *, 8> InvalidatedPassIDs;
    160   FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F];
    161   for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
    162                                              E = ResultsList.end();
    163        I != E;)
    164     if (I->second->invalidate(F, PA)) {
    165       InvalidatedPassIDs.push_back(I->first);
    166       I = ResultsList.erase(I);
    167     } else {
    168       ++I;
    169     }
    170   while (!InvalidatedPassIDs.empty())
    171     FunctionAnalysisResults.erase(
    172         std::make_pair(InvalidatedPassIDs.pop_back_val(), F));
    173   if (ResultsList.empty())
    174     FunctionAnalysisResultLists.erase(F);
    175 }
    176 
    177 char FunctionAnalysisManagerModuleProxy::PassID;
    178 
    179 FunctionAnalysisManagerModuleProxy::Result
    180 FunctionAnalysisManagerModuleProxy::run(Module *M) {
    181   assert(FAM->empty() && "Function analyses ran prior to the module proxy!");
    182   return Result(*FAM);
    183 }
    184 
    185 FunctionAnalysisManagerModuleProxy::Result::~Result() {
    186   // Clear out the analysis manager if we're being destroyed -- it means we
    187   // didn't even see an invalidate call when we got invalidated.
    188   FAM->clear();
    189 }
    190 
    191 bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
    192     Module *M, const PreservedAnalyses &PA) {
    193   // If this proxy isn't marked as preserved, then we can't even invalidate
    194   // individual function analyses, there may be an invalid set of Function
    195   // objects in the cache making it impossible to incrementally preserve them.
    196   // Just clear the entire manager.
    197   if (!PA.preserved(ID()))
    198     FAM->clear();
    199 
    200   // Return false to indicate that this result is still a valid proxy.
    201   return false;
    202 }
    203 
    204 char ModuleAnalysisManagerFunctionProxy::PassID;
    205