LLVM API Documentation

CGSCCPassManager.h
Go to the documentation of this file.
00001 //===- CGSCCPassManager.h - Call graph pass management ----------*- C++ -*-===//
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 /// \file
00010 ///
00011 /// This header provides classes for managing passes over SCCs of the call
00012 /// graph. These passes form an important component of LLVM's interprocedural
00013 /// optimizations. Because they operate on the SCCs of the call graph, and they
00014 /// wtraverse the graph in post order, they can effectively do pair-wise
00015 /// interprocedural optimizations for all call edges in the program. At each
00016 /// call site edge, the callee has already been optimized as much as is
00017 /// possible. This in turn allows very accurate analysis of it for IPO.
00018 ///
00019 //===----------------------------------------------------------------------===//
00020 
00021 #ifndef LLVM_ANALYSIS_CGSCCPASSMANAGER_H
00022 #define LLVM_ANALYSIS_CGSCCPASSMANAGER_H
00023 
00024 #include "llvm/IR/PassManager.h"
00025 #include "llvm/Analysis/LazyCallGraph.h"
00026 
00027 namespace llvm {
00028 
00029 class CGSCCAnalysisManager;
00030 
00031 class CGSCCPassManager {
00032 public:
00033   // We have to explicitly define all the special member functions because MSVC
00034   // refuses to generate them.
00035   CGSCCPassManager() {}
00036   CGSCCPassManager(CGSCCPassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
00037   CGSCCPassManager &operator=(CGSCCPassManager &&RHS) {
00038     Passes = std::move(RHS.Passes);
00039     return *this;
00040   }
00041 
00042   /// \brief Run all of the CGSCC passes in this pass manager over a SCC.
00043   PreservedAnalyses run(LazyCallGraph::SCC *C,
00044                         CGSCCAnalysisManager *AM = nullptr);
00045 
00046   template <typename CGSCCPassT> void addPass(CGSCCPassT Pass) {
00047     Passes.emplace_back(new CGSCCPassModel<CGSCCPassT>(std::move(Pass)));
00048   }
00049 
00050   static StringRef name() { return "CGSCCPassManager"; }
00051 
00052 private:
00053   // Pull in the concept type and model template specialized for SCCs.
00054   typedef detail::PassConcept<LazyCallGraph::SCC *, CGSCCAnalysisManager>
00055   CGSCCPassConcept;
00056   template <typename PassT>
00057   struct CGSCCPassModel
00058       : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT> {
00059     CGSCCPassModel(PassT Pass)
00060         : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT>(
00061               std::move(Pass)) {}
00062   };
00063 
00064   CGSCCPassManager(const CGSCCPassManager &) LLVM_DELETED_FUNCTION;
00065   CGSCCPassManager &operator=(const CGSCCPassManager &) LLVM_DELETED_FUNCTION;
00066 
00067   std::vector<std::unique_ptr<CGSCCPassConcept>> Passes;
00068 };
00069 
00070 /// \brief A function analysis manager to coordinate and cache analyses run over
00071 /// a module.
00072 class CGSCCAnalysisManager : public detail::AnalysisManagerBase<
00073                                  CGSCCAnalysisManager, LazyCallGraph::SCC *> {
00074   friend class detail::AnalysisManagerBase<CGSCCAnalysisManager,
00075                                            LazyCallGraph::SCC *>;
00076   typedef detail::AnalysisManagerBase<CGSCCAnalysisManager,
00077                                       LazyCallGraph::SCC *> BaseT;
00078   typedef BaseT::ResultConceptT ResultConceptT;
00079   typedef BaseT::PassConceptT PassConceptT;
00080 
00081 public:
00082   // Most public APIs are inherited from the CRTP base class.
00083 
00084   // We have to explicitly define all the special member functions because MSVC
00085   // refuses to generate them.
00086   CGSCCAnalysisManager() {}
00087   CGSCCAnalysisManager(CGSCCAnalysisManager &&Arg)
00088       : BaseT(std::move(static_cast<BaseT &>(Arg))),
00089         CGSCCAnalysisResults(std::move(Arg.CGSCCAnalysisResults)) {}
00090   CGSCCAnalysisManager &operator=(CGSCCAnalysisManager &&RHS) {
00091     BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
00092     CGSCCAnalysisResults = std::move(RHS.CGSCCAnalysisResults);
00093     return *this;
00094   }
00095 
00096   /// \brief Returns true if the analysis manager has an empty results cache.
00097   bool empty() const;
00098 
00099   /// \brief Clear the function analysis result cache.
00100   ///
00101   /// This routine allows cleaning up when the set of functions itself has
00102   /// potentially changed, and thus we can't even look up a a result and
00103   /// invalidate it directly. Notably, this does *not* call invalidate
00104   /// functions as there is nothing to be done for them.
00105   void clear();
00106 
00107 private:
00108   CGSCCAnalysisManager(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
00109   CGSCCAnalysisManager &
00110   operator=(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
00111 
00112   /// \brief Get a function pass result, running the pass if necessary.
00113   ResultConceptT &getResultImpl(void *PassID, LazyCallGraph::SCC *C);
00114 
00115   /// \brief Get a cached function pass result or return null.
00116   ResultConceptT *getCachedResultImpl(void *PassID,
00117                                       LazyCallGraph::SCC *C) const;
00118 
00119   /// \brief Invalidate a function pass result.
00120   void invalidateImpl(void *PassID, LazyCallGraph::SCC *C);
00121 
00122   /// \brief Invalidate the results for a function..
00123   void invalidateImpl(LazyCallGraph::SCC *C, const PreservedAnalyses &PA);
00124 
00125   /// \brief List of function analysis pass IDs and associated concept pointers.
00126   ///
00127   /// Requires iterators to be valid across appending new entries and arbitrary
00128   /// erases. Provides both the pass ID and concept pointer such that it is
00129   /// half of a bijection and provides storage for the actual result concept.
00130   typedef std::list<
00131       std::pair<void *, std::unique_ptr<detail::AnalysisResultConcept<
00132                             LazyCallGraph::SCC *>>>> CGSCCAnalysisResultListT;
00133 
00134   /// \brief Map type from function pointer to our custom list type.
00135   typedef DenseMap<LazyCallGraph::SCC *, CGSCCAnalysisResultListT>
00136   CGSCCAnalysisResultListMapT;
00137 
00138   /// \brief Map from function to a list of function analysis results.
00139   ///
00140   /// Provides linear time removal of all analysis results for a function and
00141   /// the ultimate storage for a particular cached analysis result.
00142   CGSCCAnalysisResultListMapT CGSCCAnalysisResultLists;
00143 
00144   /// \brief Map type from a pair of analysis ID and function pointer to an
00145   /// iterator into a particular result list.
00146   typedef DenseMap<std::pair<void *, LazyCallGraph::SCC *>,
00147                    CGSCCAnalysisResultListT::iterator> CGSCCAnalysisResultMapT;
00148 
00149   /// \brief Map from an analysis ID and function to a particular cached
00150   /// analysis result.
00151   CGSCCAnalysisResultMapT CGSCCAnalysisResults;
00152 };
00153 
00154 /// \brief A module analysis which acts as a proxy for a CGSCC analysis
00155 /// manager.
00156 ///
00157 /// This primarily proxies invalidation information from the module analysis
00158 /// manager and module pass manager to a CGSCC analysis manager. You should
00159 /// never use a CGSCC analysis manager from within (transitively) a module
00160 /// pass manager unless your parent module pass has received a proxy result
00161 /// object for it.
00162 class CGSCCAnalysisManagerModuleProxy {
00163 public:
00164   class Result {
00165   public:
00166     explicit Result(CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
00167     // We have to explicitly define all the special member functions because
00168     // MSVC refuses to generate them.
00169     Result(const Result &Arg) : CGAM(Arg.CGAM) {}
00170     Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
00171     Result &operator=(Result RHS) {
00172       std::swap(CGAM, RHS.CGAM);
00173       return *this;
00174     }
00175     ~Result();
00176 
00177     /// \brief Accessor for the \c CGSCCAnalysisManager.
00178     CGSCCAnalysisManager &getManager() { return *CGAM; }
00179 
00180     /// \brief Handler for invalidation of the module.
00181     ///
00182     /// If this analysis itself is preserved, then we assume that the call
00183     /// graph of the module hasn't changed and thus we don't need to invalidate
00184     /// *all* cached data associated with a \c SCC* in the \c
00185     /// CGSCCAnalysisManager.
00186     ///
00187     /// Regardless of whether this analysis is marked as preserved, all of the
00188     /// analyses in the \c CGSCCAnalysisManager are potentially invalidated
00189     /// based on the set of preserved analyses.
00190     bool invalidate(Module *M, const PreservedAnalyses &PA);
00191 
00192   private:
00193     CGSCCAnalysisManager *CGAM;
00194   };
00195 
00196   static void *ID() { return (void *)&PassID; }
00197 
00198   explicit CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManager &CGAM)
00199       : CGAM(&CGAM) {}
00200   // We have to explicitly define all the special member functions because MSVC
00201   // refuses to generate them.
00202   CGSCCAnalysisManagerModuleProxy(
00203       const CGSCCAnalysisManagerModuleProxy &Arg)
00204       : CGAM(Arg.CGAM) {}
00205   CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManagerModuleProxy &&Arg)
00206       : CGAM(std::move(Arg.CGAM)) {}
00207   CGSCCAnalysisManagerModuleProxy &
00208   operator=(CGSCCAnalysisManagerModuleProxy RHS) {
00209     std::swap(CGAM, RHS.CGAM);
00210     return *this;
00211   }
00212 
00213   /// \brief Run the analysis pass and create our proxy result object.
00214   ///
00215   /// This doesn't do any interesting work, it is primarily used to insert our
00216   /// proxy result object into the module analysis cache so that we can proxy
00217   /// invalidation to the CGSCC analysis manager.
00218   ///
00219   /// In debug builds, it will also assert that the analysis manager is empty
00220   /// as no queries should arrive at the CGSCC analysis manager prior to
00221   /// this analysis being requested.
00222   Result run(Module *M);
00223 
00224 private:
00225   static char PassID;
00226 
00227   CGSCCAnalysisManager *CGAM;
00228 };
00229 
00230 /// \brief A CGSCC analysis which acts as a proxy for a module analysis
00231 /// manager.
00232 ///
00233 /// This primarily provides an accessor to a parent module analysis manager to
00234 /// CGSCC passes. Only the const interface of the module analysis manager is
00235 /// provided to indicate that once inside of a CGSCC analysis pass you
00236 /// cannot request a module analysis to actually run. Instead, the user must
00237 /// rely on the \c getCachedResult API.
00238 ///
00239 /// This proxy *doesn't* manage the invalidation in any way. That is handled by
00240 /// the recursive return path of each layer of the pass manager and the
00241 /// returned PreservedAnalysis set.
00242 class ModuleAnalysisManagerCGSCCProxy {
00243 public:
00244   /// \brief Result proxy object for \c ModuleAnalysisManagerCGSCCProxy.
00245   class Result {
00246   public:
00247     explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
00248     // We have to explicitly define all the special member functions because
00249     // MSVC refuses to generate them.
00250     Result(const Result &Arg) : MAM(Arg.MAM) {}
00251     Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
00252     Result &operator=(Result RHS) {
00253       std::swap(MAM, RHS.MAM);
00254       return *this;
00255     }
00256 
00257     const ModuleAnalysisManager &getManager() const { return *MAM; }
00258 
00259     /// \brief Handle invalidation by ignoring it, this pass is immutable.
00260     bool invalidate(LazyCallGraph::SCC *) { return false; }
00261 
00262   private:
00263     const ModuleAnalysisManager *MAM;
00264   };
00265 
00266   static void *ID() { return (void *)&PassID; }
00267 
00268   ModuleAnalysisManagerCGSCCProxy(const ModuleAnalysisManager &MAM)
00269       : MAM(&MAM) {}
00270   // We have to explicitly define all the special member functions because MSVC
00271   // refuses to generate them.
00272   ModuleAnalysisManagerCGSCCProxy(
00273       const ModuleAnalysisManagerCGSCCProxy &Arg)
00274       : MAM(Arg.MAM) {}
00275   ModuleAnalysisManagerCGSCCProxy(ModuleAnalysisManagerCGSCCProxy &&Arg)
00276       : MAM(std::move(Arg.MAM)) {}
00277   ModuleAnalysisManagerCGSCCProxy &
00278   operator=(ModuleAnalysisManagerCGSCCProxy RHS) {
00279     std::swap(MAM, RHS.MAM);
00280     return *this;
00281   }
00282 
00283   /// \brief Run the analysis pass and create our proxy result object.
00284   /// Nothing to see here, it just forwards the \c MAM reference into the
00285   /// result.
00286   Result run(LazyCallGraph::SCC *) { return Result(*MAM); }
00287 
00288 private:
00289   static char PassID;
00290 
00291   const ModuleAnalysisManager *MAM;
00292 };
00293 
00294 /// \brief The core module pass which does a post-order walk of the SCCs and
00295 /// runs a CGSCC pass over each one.
00296 ///
00297 /// Designed to allow composition of a CGSCCPass(Manager) and
00298 /// a ModulePassManager. Note that this pass must be run with a module analysis
00299 /// manager as it uses the LazyCallGraph analysis. It will also run the
00300 /// \c CGSCCAnalysisManagerModuleProxy analysis prior to running the CGSCC
00301 /// pass over the module to enable a \c FunctionAnalysisManager to be used
00302 /// within this run safely.
00303 template <typename CGSCCPassT> class ModuleToPostOrderCGSCCPassAdaptor {
00304 public:
00305   explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass)
00306       : Pass(std::move(Pass)) {}
00307   // We have to explicitly define all the special member functions because MSVC
00308   // refuses to generate them.
00309   ModuleToPostOrderCGSCCPassAdaptor(
00310       const ModuleToPostOrderCGSCCPassAdaptor &Arg)
00311       : Pass(Arg.Pass) {}
00312   ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
00313       : Pass(std::move(Arg.Pass)) {}
00314   friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
00315                    ModuleToPostOrderCGSCCPassAdaptor &RHS) {
00316     using std::swap;
00317     swap(LHS.Pass, RHS.Pass);
00318   }
00319   ModuleToPostOrderCGSCCPassAdaptor &
00320   operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
00321     swap(*this, RHS);
00322     return *this;
00323   }
00324 
00325   /// \brief Runs the CGSCC pass across every SCC in the module.
00326   PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
00327     assert(AM && "We need analyses to compute the call graph!");
00328 
00329     // Setup the CGSCC analysis manager from its proxy.
00330     CGSCCAnalysisManager &CGAM =
00331         AM->getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
00332 
00333     // Get the call graph for this module.
00334     LazyCallGraph &CG = AM->getResult<LazyCallGraphAnalysis>(M);
00335 
00336     PreservedAnalyses PA = PreservedAnalyses::all();
00337     for (LazyCallGraph::SCC &C : CG.postorder_sccs()) {
00338       PreservedAnalyses PassPA = Pass.run(&C, &CGAM);
00339 
00340       // We know that the CGSCC pass couldn't have invalidated any other
00341       // SCC's analyses (that's the contract of a CGSCC pass), so
00342       // directly handle the CGSCC analysis manager's invalidation here.
00343       // FIXME: This isn't quite correct. We need to handle the case where the
00344       // pass updated the CG, particularly some child of the current SCC, and
00345       // invalidate its analyses.
00346       CGAM.invalidate(&C, PassPA);
00347 
00348       // Then intersect the preserved set so that invalidation of module
00349       // analyses will eventually occur when the module pass completes.
00350       PA.intersect(std::move(PassPA));
00351     }
00352 
00353     // By definition we preserve the proxy. This precludes *any* invalidation
00354     // of CGSCC analyses by the proxy, but that's OK because we've taken
00355     // care to invalidate analyses in the CGSCC analysis manager
00356     // incrementally above.
00357     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
00358     return PA;
00359   }
00360 
00361   static StringRef name() { return "ModuleToPostOrderCGSCCPassAdaptor"; }
00362 
00363 private:
00364   CGSCCPassT Pass;
00365 };
00366 
00367 /// \brief A function to deduce a function pass type and wrap it in the
00368 /// templated adaptor.
00369 template <typename CGSCCPassT>
00370 ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>
00371 createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
00372   return std::move(
00373       ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass)));
00374 }
00375 
00376 /// \brief A CGSCC analysis which acts as a proxy for a function analysis
00377 /// manager.
00378 ///
00379 /// This primarily proxies invalidation information from the CGSCC analysis
00380 /// manager and CGSCC pass manager to a function analysis manager. You should
00381 /// never use a function analysis manager from within (transitively) a CGSCC
00382 /// pass manager unless your parent CGSCC pass has received a proxy result
00383 /// object for it.
00384 class FunctionAnalysisManagerCGSCCProxy {
00385 public:
00386   class Result {
00387   public:
00388     explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
00389     // We have to explicitly define all the special member functions because
00390     // MSVC refuses to generate them.
00391     Result(const Result &Arg) : FAM(Arg.FAM) {}
00392     Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
00393     Result &operator=(Result RHS) {
00394       std::swap(FAM, RHS.FAM);
00395       return *this;
00396     }
00397     ~Result();
00398 
00399     /// \brief Accessor for the \c FunctionAnalysisManager.
00400     FunctionAnalysisManager &getManager() { return *FAM; }
00401 
00402     /// \brief Handler for invalidation of the SCC.
00403     ///
00404     /// If this analysis itself is preserved, then we assume that the set of \c
00405     /// Function objects in the \c SCC hasn't changed and thus we don't need
00406     /// to invalidate *all* cached data associated with a \c Function* in the \c
00407     /// FunctionAnalysisManager.
00408     ///
00409     /// Regardless of whether this analysis is marked as preserved, all of the
00410     /// analyses in the \c FunctionAnalysisManager are potentially invalidated
00411     /// based on the set of preserved analyses.
00412     bool invalidate(LazyCallGraph::SCC *C, const PreservedAnalyses &PA);
00413 
00414   private:
00415     FunctionAnalysisManager *FAM;
00416   };
00417 
00418   static void *ID() { return (void *)&PassID; }
00419 
00420   explicit FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManager &FAM)
00421       : FAM(&FAM) {}
00422   // We have to explicitly define all the special member functions because MSVC
00423   // refuses to generate them.
00424   FunctionAnalysisManagerCGSCCProxy(
00425       const FunctionAnalysisManagerCGSCCProxy &Arg)
00426       : FAM(Arg.FAM) {}
00427   FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManagerCGSCCProxy &&Arg)
00428       : FAM(std::move(Arg.FAM)) {}
00429   FunctionAnalysisManagerCGSCCProxy &
00430   operator=(FunctionAnalysisManagerCGSCCProxy RHS) {
00431     std::swap(FAM, RHS.FAM);
00432     return *this;
00433   }
00434 
00435   /// \brief Run the analysis pass and create our proxy result object.
00436   ///
00437   /// This doesn't do any interesting work, it is primarily used to insert our
00438   /// proxy result object into the module analysis cache so that we can proxy
00439   /// invalidation to the function analysis manager.
00440   ///
00441   /// In debug builds, it will also assert that the analysis manager is empty
00442   /// as no queries should arrive at the function analysis manager prior to
00443   /// this analysis being requested.
00444   Result run(LazyCallGraph::SCC *C);
00445 
00446 private:
00447   static char PassID;
00448 
00449   FunctionAnalysisManager *FAM;
00450 };
00451 
00452 /// \brief A function analysis which acts as a proxy for a CGSCC analysis
00453 /// manager.
00454 ///
00455 /// This primarily provides an accessor to a parent CGSCC analysis manager to
00456 /// function passes. Only the const interface of the CGSCC analysis manager is
00457 /// provided to indicate that once inside of a function analysis pass you
00458 /// cannot request a CGSCC analysis to actually run. Instead, the user must
00459 /// rely on the \c getCachedResult API.
00460 ///
00461 /// This proxy *doesn't* manage the invalidation in any way. That is handled by
00462 /// the recursive return path of each layer of the pass manager and the
00463 /// returned PreservedAnalysis set.
00464 class CGSCCAnalysisManagerFunctionProxy {
00465 public:
00466   /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
00467   class Result {
00468   public:
00469     explicit Result(const CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
00470     // We have to explicitly define all the special member functions because
00471     // MSVC refuses to generate them.
00472     Result(const Result &Arg) : CGAM(Arg.CGAM) {}
00473     Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
00474     Result &operator=(Result RHS) {
00475       std::swap(CGAM, RHS.CGAM);
00476       return *this;
00477     }
00478 
00479     const CGSCCAnalysisManager &getManager() const { return *CGAM; }
00480 
00481     /// \brief Handle invalidation by ignoring it, this pass is immutable.
00482     bool invalidate(Function *) { return false; }
00483 
00484   private:
00485     const CGSCCAnalysisManager *CGAM;
00486   };
00487 
00488   static void *ID() { return (void *)&PassID; }
00489 
00490   CGSCCAnalysisManagerFunctionProxy(const CGSCCAnalysisManager &CGAM)
00491       : CGAM(&CGAM) {}
00492   // We have to explicitly define all the special member functions because MSVC
00493   // refuses to generate them.
00494   CGSCCAnalysisManagerFunctionProxy(
00495       const CGSCCAnalysisManagerFunctionProxy &Arg)
00496       : CGAM(Arg.CGAM) {}
00497   CGSCCAnalysisManagerFunctionProxy(CGSCCAnalysisManagerFunctionProxy &&Arg)
00498       : CGAM(std::move(Arg.CGAM)) {}
00499   CGSCCAnalysisManagerFunctionProxy &
00500   operator=(CGSCCAnalysisManagerFunctionProxy RHS) {
00501     std::swap(CGAM, RHS.CGAM);
00502     return *this;
00503   }
00504 
00505   /// \brief Run the analysis pass and create our proxy result object.
00506   /// Nothing to see here, it just forwards the \c CGAM reference into the
00507   /// result.
00508   Result run(Function *) { return Result(*CGAM); }
00509 
00510 private:
00511   static char PassID;
00512 
00513   const CGSCCAnalysisManager *CGAM;
00514 };
00515 
00516 /// \brief Adaptor that maps from a SCC to its functions.
00517 ///
00518 /// Designed to allow composition of a FunctionPass(Manager) and
00519 /// a CGSCCPassManager. Note that if this pass is constructed with a pointer
00520 /// to a \c CGSCCAnalysisManager it will run the
00521 /// \c FunctionAnalysisManagerCGSCCProxy analysis prior to running the function
00522 /// pass over the SCC to enable a \c FunctionAnalysisManager to be used
00523 /// within this run safely.
00524 template <typename FunctionPassT> class CGSCCToFunctionPassAdaptor {
00525 public:
00526   explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass)
00527       : Pass(std::move(Pass)) {}
00528   // We have to explicitly define all the special member functions because MSVC
00529   // refuses to generate them.
00530   CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
00531       : Pass(Arg.Pass) {}
00532   CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
00533       : Pass(std::move(Arg.Pass)) {}
00534   friend void swap(CGSCCToFunctionPassAdaptor &LHS, CGSCCToFunctionPassAdaptor &RHS) {
00535     using std::swap;
00536     swap(LHS.Pass, RHS.Pass);
00537   }
00538   CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
00539     swap(*this, RHS);
00540     return *this;
00541   }
00542 
00543   /// \brief Runs the function pass across every function in the module.
00544   PreservedAnalyses run(LazyCallGraph::SCC *C, CGSCCAnalysisManager *AM) {
00545     FunctionAnalysisManager *FAM = nullptr;
00546     if (AM)
00547       // Setup the function analysis manager from its proxy.
00548       FAM = &AM->getResult<FunctionAnalysisManagerCGSCCProxy>(C).getManager();
00549 
00550     PreservedAnalyses PA = PreservedAnalyses::all();
00551     for (LazyCallGraph::Node *N : *C) {
00552       PreservedAnalyses PassPA = Pass.run(&N->getFunction(), FAM);
00553 
00554       // We know that the function pass couldn't have invalidated any other
00555       // function's analyses (that's the contract of a function pass), so
00556       // directly handle the function analysis manager's invalidation here.
00557       if (FAM)
00558         FAM->invalidate(&N->getFunction(), PassPA);
00559 
00560       // Then intersect the preserved set so that invalidation of module
00561       // analyses will eventually occur when the module pass completes.
00562       PA.intersect(std::move(PassPA));
00563     }
00564 
00565     // By definition we preserve the proxy. This precludes *any* invalidation
00566     // of function analyses by the proxy, but that's OK because we've taken
00567     // care to invalidate analyses in the function analysis manager
00568     // incrementally above.
00569     // FIXME: We need to update the call graph here to account for any deleted
00570     // edges!
00571     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
00572     return PA;
00573   }
00574 
00575   static StringRef name() { return "CGSCCToFunctionPassAdaptor"; }
00576 
00577 private:
00578   FunctionPassT Pass;
00579 };
00580 
00581 /// \brief A function to deduce a function pass type and wrap it in the
00582 /// templated adaptor.
00583 template <typename FunctionPassT>
00584 CGSCCToFunctionPassAdaptor<FunctionPassT>
00585 createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
00586   return std::move(CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
00587 }
00588 
00589 }
00590 
00591 #endif