LLVM API Documentation

CGSCCPassManager.cpp
Go to the documentation of this file.
00001 //===- CGSCCPassManager.cpp - Managing & running CGSCC passes -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/Analysis/CGSCCPassManager.h"
00011 #include "llvm/Support/CommandLine.h"
00012 #include "llvm/Support/Debug.h"
00013 
00014 using namespace llvm;
00015 
00016 static cl::opt<bool>
00017 DebugPM("debug-cgscc-pass-manager", cl::Hidden,
00018         cl::desc("Print CGSCC pass management debugging information"));
00019 
00020 PreservedAnalyses CGSCCPassManager::run(LazyCallGraph::SCC *C,
00021                                         CGSCCAnalysisManager *AM) {
00022   PreservedAnalyses PA = PreservedAnalyses::all();
00023 
00024   if (DebugPM)
00025     dbgs() << "Starting CGSCC pass manager run.\n";
00026 
00027   for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
00028     if (DebugPM)
00029       dbgs() << "Running CGSCC pass: " << Passes[Idx]->name() << "\n";
00030 
00031     PreservedAnalyses PassPA = Passes[Idx]->run(C, AM);
00032     if (AM)
00033       AM->invalidate(C, PassPA);
00034     PA.intersect(std::move(PassPA));
00035   }
00036 
00037   if (DebugPM)
00038     dbgs() << "Finished CGSCC pass manager run.\n";
00039 
00040   return PA;
00041 }
00042 
00043 bool CGSCCAnalysisManager::empty() const {
00044   assert(CGSCCAnalysisResults.empty() == CGSCCAnalysisResultLists.empty() &&
00045          "The storage and index of analysis results disagree on how many there "
00046          "are!");
00047   return CGSCCAnalysisResults.empty();
00048 }
00049 
00050 void CGSCCAnalysisManager::clear() {
00051   CGSCCAnalysisResults.clear();
00052   CGSCCAnalysisResultLists.clear();
00053 }
00054 
00055 CGSCCAnalysisManager::ResultConceptT &
00056 CGSCCAnalysisManager::getResultImpl(void *PassID, LazyCallGraph::SCC *C) {
00057   CGSCCAnalysisResultMapT::iterator RI;
00058   bool Inserted;
00059   std::tie(RI, Inserted) = CGSCCAnalysisResults.insert(std::make_pair(
00060       std::make_pair(PassID, C), CGSCCAnalysisResultListT::iterator()));
00061 
00062   // If we don't have a cached result for this function, look up the pass and
00063   // run it to produce a result, which we then add to the cache.
00064   if (Inserted) {
00065     CGSCCAnalysisResultListT &ResultList = CGSCCAnalysisResultLists[C];
00066     ResultList.emplace_back(PassID, lookupPass(PassID).run(C, this));
00067     RI->second = std::prev(ResultList.end());
00068   }
00069 
00070   return *RI->second->second;
00071 }
00072 
00073 CGSCCAnalysisManager::ResultConceptT *
00074 CGSCCAnalysisManager::getCachedResultImpl(void *PassID,
00075                                           LazyCallGraph::SCC *C) const {
00076   CGSCCAnalysisResultMapT::const_iterator RI =
00077       CGSCCAnalysisResults.find(std::make_pair(PassID, C));
00078   return RI == CGSCCAnalysisResults.end() ? nullptr : &*RI->second->second;
00079 }
00080 
00081 void CGSCCAnalysisManager::invalidateImpl(void *PassID, LazyCallGraph::SCC *C) {
00082   CGSCCAnalysisResultMapT::iterator RI =
00083       CGSCCAnalysisResults.find(std::make_pair(PassID, C));
00084   if (RI == CGSCCAnalysisResults.end())
00085     return;
00086 
00087   CGSCCAnalysisResultLists[C].erase(RI->second);
00088 }
00089 
00090 void CGSCCAnalysisManager::invalidateImpl(LazyCallGraph::SCC *C,
00091                                           const PreservedAnalyses &PA) {
00092   // Clear all the invalidated results associated specifically with this
00093   // function.
00094   SmallVector<void *, 8> InvalidatedPassIDs;
00095   CGSCCAnalysisResultListT &ResultsList = CGSCCAnalysisResultLists[C];
00096   for (CGSCCAnalysisResultListT::iterator I = ResultsList.begin(),
00097                                           E = ResultsList.end();
00098        I != E;)
00099     if (I->second->invalidate(C, PA)) {
00100       InvalidatedPassIDs.push_back(I->first);
00101       I = ResultsList.erase(I);
00102     } else {
00103       ++I;
00104     }
00105   while (!InvalidatedPassIDs.empty())
00106     CGSCCAnalysisResults.erase(
00107         std::make_pair(InvalidatedPassIDs.pop_back_val(), C));
00108   CGSCCAnalysisResultLists.erase(C);
00109 }
00110 
00111 char CGSCCAnalysisManagerModuleProxy::PassID;
00112 
00113 CGSCCAnalysisManagerModuleProxy::Result
00114 CGSCCAnalysisManagerModuleProxy::run(Module *M) {
00115   assert(CGAM->empty() && "CGSCC analyses ran prior to the module proxy!");
00116   return Result(*CGAM);
00117 }
00118 
00119 CGSCCAnalysisManagerModuleProxy::Result::~Result() {
00120   // Clear out the analysis manager if we're being destroyed -- it means we
00121   // didn't even see an invalidate call when we got invalidated.
00122   CGAM->clear();
00123 }
00124 
00125 bool CGSCCAnalysisManagerModuleProxy::Result::invalidate(
00126     Module *M, const PreservedAnalyses &PA) {
00127   // If this proxy isn't marked as preserved, then we can't even invalidate
00128   // individual CGSCC analyses, there may be an invalid set of SCC objects in
00129   // the cache making it impossible to incrementally preserve them.
00130   // Just clear the entire manager.
00131   if (!PA.preserved(ID()))
00132     CGAM->clear();
00133 
00134   // Return false to indicate that this result is still a valid proxy.
00135   return false;
00136 }
00137 
00138 char ModuleAnalysisManagerCGSCCProxy::PassID;
00139 
00140 char FunctionAnalysisManagerCGSCCProxy::PassID;
00141 
00142 FunctionAnalysisManagerCGSCCProxy::Result
00143 FunctionAnalysisManagerCGSCCProxy::run(LazyCallGraph::SCC *C) {
00144   assert(FAM->empty() && "Function analyses ran prior to the CGSCC proxy!");
00145   return Result(*FAM);
00146 }
00147 
00148 FunctionAnalysisManagerCGSCCProxy::Result::~Result() {
00149   // Clear out the analysis manager if we're being destroyed -- it means we
00150   // didn't even see an invalidate call when we got invalidated.
00151   FAM->clear();
00152 }
00153 
00154 bool FunctionAnalysisManagerCGSCCProxy::Result::invalidate(
00155     LazyCallGraph::SCC *C, const PreservedAnalyses &PA) {
00156   // If this proxy isn't marked as preserved, then we can't even invalidate
00157   // individual function analyses, there may be an invalid set of Function
00158   // objects in the cache making it impossible to incrementally preserve them.
00159   // Just clear the entire manager.
00160   if (!PA.preserved(ID()))
00161     FAM->clear();
00162 
00163   // Return false to indicate that this result is still a valid proxy.
00164   return false;
00165 }
00166 
00167 char CGSCCAnalysisManagerFunctionProxy::PassID;