Home | History | Annotate | Download | only in Analysis
      1 //===- CGSCCPassManager.h - Call graph pass management ----------*- C++ -*-===//
      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 /// \file
     10 ///
     11 /// This header provides classes for managing passes over SCCs of the call
     12 /// graph. These passes form an important component of LLVM's interprocedural
     13 /// optimizations. Because they operate on the SCCs of the call graph, and they
     14 /// wtraverse the graph in post order, they can effectively do pair-wise
     15 /// interprocedural optimizations for all call edges in the program. At each
     16 /// call site edge, the callee has already been optimized as much as is
     17 /// possible. This in turn allows very accurate analysis of it for IPO.
     18 ///
     19 //===----------------------------------------------------------------------===//
     20 
     21 #ifndef LLVM_ANALYSIS_CGSCC_PASS_MANAGER_H
     22 #define LLVM_ANALYSIS_CGSCC_PASS_MANAGER_H
     23 
     24 #include "llvm/IR/PassManager.h"
     25 #include "llvm/Analysis/LazyCallGraph.h"
     26 
     27 namespace llvm {
     28 
     29 class CGSCCAnalysisManager;
     30 
     31 class CGSCCPassManager {
     32 public:
     33   // We have to explicitly define all the special member functions because MSVC
     34   // refuses to generate them.
     35   CGSCCPassManager() {}
     36   CGSCCPassManager(CGSCCPassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
     37   CGSCCPassManager &operator=(CGSCCPassManager &&RHS) {
     38     Passes = std::move(RHS.Passes);
     39     return *this;
     40   }
     41 
     42   /// \brief Run all of the CGSCC passes in this pass manager over a SCC.
     43   PreservedAnalyses run(LazyCallGraph::SCC *C,
     44                         CGSCCAnalysisManager *AM = nullptr);
     45 
     46   template <typename CGSCCPassT> void addPass(CGSCCPassT Pass) {
     47     Passes.emplace_back(new CGSCCPassModel<CGSCCPassT>(std::move(Pass)));
     48   }
     49 
     50   static StringRef name() { return "CGSCCPassManager"; }
     51 
     52 private:
     53   // Pull in the concept type and model template specialized for SCCs.
     54   typedef detail::PassConcept<LazyCallGraph::SCC *, CGSCCAnalysisManager>
     55   CGSCCPassConcept;
     56   template <typename PassT>
     57   struct CGSCCPassModel
     58       : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT> {
     59     CGSCCPassModel(PassT Pass)
     60         : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT>(
     61               std::move(Pass)) {}
     62   };
     63 
     64   CGSCCPassManager(const CGSCCPassManager &) LLVM_DELETED_FUNCTION;
     65   CGSCCPassManager &operator=(const CGSCCPassManager &) LLVM_DELETED_FUNCTION;
     66 
     67   std::vector<std::unique_ptr<CGSCCPassConcept>> Passes;
     68 };
     69 
     70 /// \brief A function analysis manager to coordinate and cache analyses run over
     71 /// a module.
     72 class CGSCCAnalysisManager : public detail::AnalysisManagerBase<
     73                                  CGSCCAnalysisManager, LazyCallGraph::SCC *> {
     74   friend class detail::AnalysisManagerBase<CGSCCAnalysisManager,
     75                                            LazyCallGraph::SCC *>;
     76   typedef detail::AnalysisManagerBase<CGSCCAnalysisManager,
     77                                       LazyCallGraph::SCC *> BaseT;
     78   typedef BaseT::ResultConceptT ResultConceptT;
     79   typedef BaseT::PassConceptT PassConceptT;
     80 
     81 public:
     82   // Most public APIs are inherited from the CRTP base class.
     83 
     84   // We have to explicitly define all the special member functions because MSVC
     85   // refuses to generate them.
     86   CGSCCAnalysisManager() {}
     87   CGSCCAnalysisManager(CGSCCAnalysisManager &&Arg)
     88       : BaseT(std::move(static_cast<BaseT &>(Arg))),
     89         CGSCCAnalysisResults(std::move(Arg.CGSCCAnalysisResults)) {}
     90   CGSCCAnalysisManager &operator=(CGSCCAnalysisManager &&RHS) {
     91     BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
     92     CGSCCAnalysisResults = std::move(RHS.CGSCCAnalysisResults);
     93     return *this;
     94   }
     95 
     96   /// \brief Returns true if the analysis manager has an empty results cache.
     97   bool empty() const;
     98 
     99   /// \brief Clear the function analysis result cache.
    100   ///
    101   /// This routine allows cleaning up when the set of functions itself has
    102   /// potentially changed, and thus we can't even look up a a result and
    103   /// invalidate it directly. Notably, this does *not* call invalidate
    104   /// functions as there is nothing to be done for them.
    105   void clear();
    106 
    107 private:
    108   CGSCCAnalysisManager(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
    109   CGSCCAnalysisManager &
    110   operator=(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
    111 
    112   /// \brief Get a function pass result, running the pass if necessary.
    113   ResultConceptT &getResultImpl(void *PassID, LazyCallGraph::SCC *C);
    114 
    115   /// \brief Get a cached function pass result or return null.
    116   ResultConceptT *getCachedResultImpl(void *PassID,
    117                                       LazyCallGraph::SCC *C) const;
    118 
    119   /// \brief Invalidate a function pass result.
    120   void invalidateImpl(void *PassID, LazyCallGraph::SCC *C);
    121 
    122   /// \brief Invalidate the results for a function..
    123   void invalidateImpl(LazyCallGraph::SCC *C, const PreservedAnalyses &PA);
    124 
    125   /// \brief List of function analysis pass IDs and associated concept pointers.
    126   ///
    127   /// Requires iterators to be valid across appending new entries and arbitrary
    128   /// erases. Provides both the pass ID and concept pointer such that it is
    129   /// half of a bijection and provides storage for the actual result concept.
    130   typedef std::list<
    131       std::pair<void *, std::unique_ptr<detail::AnalysisResultConcept<
    132                             LazyCallGraph::SCC *>>>> CGSCCAnalysisResultListT;
    133 
    134   /// \brief Map type from function pointer to our custom list type.
    135   typedef DenseMap<LazyCallGraph::SCC *, CGSCCAnalysisResultListT>
    136   CGSCCAnalysisResultListMapT;
    137 
    138   /// \brief Map from function to a list of function analysis results.
    139   ///
    140   /// Provides linear time removal of all analysis results for a function and
    141   /// the ultimate storage for a particular cached analysis result.
    142   CGSCCAnalysisResultListMapT CGSCCAnalysisResultLists;
    143 
    144   /// \brief Map type from a pair of analysis ID and function pointer to an
    145   /// iterator into a particular result list.
    146   typedef DenseMap<std::pair<void *, LazyCallGraph::SCC *>,
    147                    CGSCCAnalysisResultListT::iterator> CGSCCAnalysisResultMapT;
    148 
    149   /// \brief Map from an analysis ID and function to a particular cached
    150   /// analysis result.
    151   CGSCCAnalysisResultMapT CGSCCAnalysisResults;
    152 };
    153 
    154 /// \brief A module analysis which acts as a proxy for a CGSCC analysis
    155 /// manager.
    156 ///
    157 /// This primarily proxies invalidation information from the module analysis
    158 /// manager and module pass manager to a CGSCC analysis manager. You should
    159 /// never use a CGSCC analysis manager from within (transitively) a module
    160 /// pass manager unless your parent module pass has received a proxy result
    161 /// object for it.
    162 class CGSCCAnalysisManagerModuleProxy {
    163 public:
    164   class Result {
    165   public:
    166     explicit Result(CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
    167     // We have to explicitly define all the special member functions because
    168     // MSVC refuses to generate them.
    169     Result(const Result &Arg) : CGAM(Arg.CGAM) {}
    170     Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
    171     Result &operator=(Result RHS) {
    172       std::swap(CGAM, RHS.CGAM);
    173       return *this;
    174     }
    175     ~Result();
    176 
    177     /// \brief Accessor for the \c CGSCCAnalysisManager.
    178     CGSCCAnalysisManager &getManager() { return *CGAM; }
    179 
    180     /// \brief Handler for invalidation of the module.
    181     ///
    182     /// If this analysis itself is preserved, then we assume that the call
    183     /// graph of the module hasn't changed and thus we don't need to invalidate
    184     /// *all* cached data associated with a \c SCC* in the \c
    185     /// CGSCCAnalysisManager.
    186     ///
    187     /// Regardless of whether this analysis is marked as preserved, all of the
    188     /// analyses in the \c CGSCCAnalysisManager are potentially invalidated
    189     /// based on the set of preserved analyses.
    190     bool invalidate(Module *M, const PreservedAnalyses &PA);
    191 
    192   private:
    193     CGSCCAnalysisManager *CGAM;
    194   };
    195 
    196   static void *ID() { return (void *)&PassID; }
    197 
    198   explicit CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManager &CGAM)
    199       : CGAM(&CGAM) {}
    200   // We have to explicitly define all the special member functions because MSVC
    201   // refuses to generate them.
    202   CGSCCAnalysisManagerModuleProxy(
    203       const CGSCCAnalysisManagerModuleProxy &Arg)
    204       : CGAM(Arg.CGAM) {}
    205   CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManagerModuleProxy &&Arg)
    206       : CGAM(std::move(Arg.CGAM)) {}
    207   CGSCCAnalysisManagerModuleProxy &
    208   operator=(CGSCCAnalysisManagerModuleProxy RHS) {
    209     std::swap(CGAM, RHS.CGAM);
    210     return *this;
    211   }
    212 
    213   /// \brief Run the analysis pass and create our proxy result object.
    214   ///
    215   /// This doesn't do any interesting work, it is primarily used to insert our
    216   /// proxy result object into the module analysis cache so that we can proxy
    217   /// invalidation to the CGSCC analysis manager.
    218   ///
    219   /// In debug builds, it will also assert that the analysis manager is empty
    220   /// as no queries should arrive at the CGSCC analysis manager prior to
    221   /// this analysis being requested.
    222   Result run(Module *M);
    223 
    224 private:
    225   static char PassID;
    226 
    227   CGSCCAnalysisManager *CGAM;
    228 };
    229 
    230 /// \brief A CGSCC analysis which acts as a proxy for a module analysis
    231 /// manager.
    232 ///
    233 /// This primarily provides an accessor to a parent module analysis manager to
    234 /// CGSCC passes. Only the const interface of the module analysis manager is
    235 /// provided to indicate that once inside of a CGSCC analysis pass you
    236 /// cannot request a module analysis to actually run. Instead, the user must
    237 /// rely on the \c getCachedResult API.
    238 ///
    239 /// This proxy *doesn't* manage the invalidation in any way. That is handled by
    240 /// the recursive return path of each layer of the pass manager and the
    241 /// returned PreservedAnalysis set.
    242 class ModuleAnalysisManagerCGSCCProxy {
    243 public:
    244   /// \brief Result proxy object for \c ModuleAnalysisManagerCGSCCProxy.
    245   class Result {
    246   public:
    247     explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
    248     // We have to explicitly define all the special member functions because
    249     // MSVC refuses to generate them.
    250     Result(const Result &Arg) : MAM(Arg.MAM) {}
    251     Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
    252     Result &operator=(Result RHS) {
    253       std::swap(MAM, RHS.MAM);
    254       return *this;
    255     }
    256 
    257     const ModuleAnalysisManager &getManager() const { return *MAM; }
    258 
    259     /// \brief Handle invalidation by ignoring it, this pass is immutable.
    260     bool invalidate(LazyCallGraph::SCC *) { return false; }
    261 
    262   private:
    263     const ModuleAnalysisManager *MAM;
    264   };
    265 
    266   static void *ID() { return (void *)&PassID; }
    267 
    268   ModuleAnalysisManagerCGSCCProxy(const ModuleAnalysisManager &MAM)
    269       : MAM(&MAM) {}
    270   // We have to explicitly define all the special member functions because MSVC
    271   // refuses to generate them.
    272   ModuleAnalysisManagerCGSCCProxy(
    273       const ModuleAnalysisManagerCGSCCProxy &Arg)
    274       : MAM(Arg.MAM) {}
    275   ModuleAnalysisManagerCGSCCProxy(ModuleAnalysisManagerCGSCCProxy &&Arg)
    276       : MAM(std::move(Arg.MAM)) {}
    277   ModuleAnalysisManagerCGSCCProxy &
    278   operator=(ModuleAnalysisManagerCGSCCProxy RHS) {
    279     std::swap(MAM, RHS.MAM);
    280     return *this;
    281   }
    282 
    283   /// \brief Run the analysis pass and create our proxy result object.
    284   /// Nothing to see here, it just forwards the \c MAM reference into the
    285   /// result.
    286   Result run(LazyCallGraph::SCC *) { return Result(*MAM); }
    287 
    288 private:
    289   static char PassID;
    290 
    291   const ModuleAnalysisManager *MAM;
    292 };
    293 
    294 /// \brief The core module pass which does a post-order walk of the SCCs and
    295 /// runs a CGSCC pass over each one.
    296 ///
    297 /// Designed to allow composition of a CGSCCPass(Manager) and
    298 /// a ModulePassManager. Note that this pass must be run with a module analysis
    299 /// manager as it uses the LazyCallGraph analysis. It will also run the
    300 /// \c CGSCCAnalysisManagerModuleProxy analysis prior to running the CGSCC
    301 /// pass over the module to enable a \c FunctionAnalysisManager to be used
    302 /// within this run safely.
    303 template <typename CGSCCPassT> class ModuleToPostOrderCGSCCPassAdaptor {
    304 public:
    305   explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass)
    306       : Pass(std::move(Pass)) {}
    307   // We have to explicitly define all the special member functions because MSVC
    308   // refuses to generate them.
    309   ModuleToPostOrderCGSCCPassAdaptor(
    310       const ModuleToPostOrderCGSCCPassAdaptor &Arg)
    311       : Pass(Arg.Pass) {}
    312   ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
    313       : Pass(std::move(Arg.Pass)) {}
    314   friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
    315                    ModuleToPostOrderCGSCCPassAdaptor &RHS) {
    316     using std::swap;
    317     swap(LHS.Pass, RHS.Pass);
    318   }
    319   ModuleToPostOrderCGSCCPassAdaptor &
    320   operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
    321     swap(*this, RHS);
    322     return *this;
    323   }
    324 
    325   /// \brief Runs the CGSCC pass across every SCC in the module.
    326   PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
    327     assert(AM && "We need analyses to compute the call graph!");
    328 
    329     // Setup the CGSCC analysis manager from its proxy.
    330     CGSCCAnalysisManager &CGAM =
    331         AM->getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
    332 
    333     // Get the call graph for this module.
    334     LazyCallGraph &CG = AM->getResult<LazyCallGraphAnalysis>(M);
    335 
    336     PreservedAnalyses PA = PreservedAnalyses::all();
    337     for (LazyCallGraph::SCC &C : CG.postorder_sccs()) {
    338       PreservedAnalyses PassPA = Pass.run(&C, &CGAM);
    339 
    340       // We know that the CGSCC pass couldn't have invalidated any other
    341       // SCC's analyses (that's the contract of a CGSCC pass), so
    342       // directly handle the CGSCC analysis manager's invalidation here.
    343       // FIXME: This isn't quite correct. We need to handle the case where the
    344       // pass updated the CG, particularly some child of the current SCC, and
    345       // invalidate its analyses.
    346       CGAM.invalidate(&C, PassPA);
    347 
    348       // Then intersect the preserved set so that invalidation of module
    349       // analyses will eventually occur when the module pass completes.
    350       PA.intersect(std::move(PassPA));
    351     }
    352 
    353     // By definition we preserve the proxy. This precludes *any* invalidation
    354     // of CGSCC analyses by the proxy, but that's OK because we've taken
    355     // care to invalidate analyses in the CGSCC analysis manager
    356     // incrementally above.
    357     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
    358     return PA;
    359   }
    360 
    361   static StringRef name() { return "ModuleToPostOrderCGSCCPassAdaptor"; }
    362 
    363 private:
    364   CGSCCPassT Pass;
    365 };
    366 
    367 /// \brief A function to deduce a function pass type and wrap it in the
    368 /// templated adaptor.
    369 template <typename CGSCCPassT>
    370 ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>
    371 createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
    372   return std::move(
    373       ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass)));
    374 }
    375 
    376 /// \brief A CGSCC analysis which acts as a proxy for a function analysis
    377 /// manager.
    378 ///
    379 /// This primarily proxies invalidation information from the CGSCC analysis
    380 /// manager and CGSCC pass manager to a function analysis manager. You should
    381 /// never use a function analysis manager from within (transitively) a CGSCC
    382 /// pass manager unless your parent CGSCC pass has received a proxy result
    383 /// object for it.
    384 class FunctionAnalysisManagerCGSCCProxy {
    385 public:
    386   class Result {
    387   public:
    388     explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
    389     // We have to explicitly define all the special member functions because
    390     // MSVC refuses to generate them.
    391     Result(const Result &Arg) : FAM(Arg.FAM) {}
    392     Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
    393     Result &operator=(Result RHS) {
    394       std::swap(FAM, RHS.FAM);
    395       return *this;
    396     }
    397     ~Result();
    398 
    399     /// \brief Accessor for the \c FunctionAnalysisManager.
    400     FunctionAnalysisManager &getManager() { return *FAM; }
    401 
    402     /// \brief Handler for invalidation of the SCC.
    403     ///
    404     /// If this analysis itself is preserved, then we assume that the set of \c
    405     /// Function objects in the \c SCC hasn't changed and thus we don't need
    406     /// to invalidate *all* cached data associated with a \c Function* in the \c
    407     /// FunctionAnalysisManager.
    408     ///
    409     /// Regardless of whether this analysis is marked as preserved, all of the
    410     /// analyses in the \c FunctionAnalysisManager are potentially invalidated
    411     /// based on the set of preserved analyses.
    412     bool invalidate(LazyCallGraph::SCC *C, const PreservedAnalyses &PA);
    413 
    414   private:
    415     FunctionAnalysisManager *FAM;
    416   };
    417 
    418   static void *ID() { return (void *)&PassID; }
    419 
    420   explicit FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManager &FAM)
    421       : FAM(&FAM) {}
    422   // We have to explicitly define all the special member functions because MSVC
    423   // refuses to generate them.
    424   FunctionAnalysisManagerCGSCCProxy(
    425       const FunctionAnalysisManagerCGSCCProxy &Arg)
    426       : FAM(Arg.FAM) {}
    427   FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManagerCGSCCProxy &&Arg)
    428       : FAM(std::move(Arg.FAM)) {}
    429   FunctionAnalysisManagerCGSCCProxy &
    430   operator=(FunctionAnalysisManagerCGSCCProxy RHS) {
    431     std::swap(FAM, RHS.FAM);
    432     return *this;
    433   }
    434 
    435   /// \brief Run the analysis pass and create our proxy result object.
    436   ///
    437   /// This doesn't do any interesting work, it is primarily used to insert our
    438   /// proxy result object into the module analysis cache so that we can proxy
    439   /// invalidation to the function analysis manager.
    440   ///
    441   /// In debug builds, it will also assert that the analysis manager is empty
    442   /// as no queries should arrive at the function analysis manager prior to
    443   /// this analysis being requested.
    444   Result run(LazyCallGraph::SCC *C);
    445 
    446 private:
    447   static char PassID;
    448 
    449   FunctionAnalysisManager *FAM;
    450 };
    451 
    452 /// \brief A function analysis which acts as a proxy for a CGSCC analysis
    453 /// manager.
    454 ///
    455 /// This primarily provides an accessor to a parent CGSCC analysis manager to
    456 /// function passes. Only the const interface of the CGSCC analysis manager is
    457 /// provided to indicate that once inside of a function analysis pass you
    458 /// cannot request a CGSCC analysis to actually run. Instead, the user must
    459 /// rely on the \c getCachedResult API.
    460 ///
    461 /// This proxy *doesn't* manage the invalidation in any way. That is handled by
    462 /// the recursive return path of each layer of the pass manager and the
    463 /// returned PreservedAnalysis set.
    464 class CGSCCAnalysisManagerFunctionProxy {
    465 public:
    466   /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
    467   class Result {
    468   public:
    469     explicit Result(const CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
    470     // We have to explicitly define all the special member functions because
    471     // MSVC refuses to generate them.
    472     Result(const Result &Arg) : CGAM(Arg.CGAM) {}
    473     Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
    474     Result &operator=(Result RHS) {
    475       std::swap(CGAM, RHS.CGAM);
    476       return *this;
    477     }
    478 
    479     const CGSCCAnalysisManager &getManager() const { return *CGAM; }
    480 
    481     /// \brief Handle invalidation by ignoring it, this pass is immutable.
    482     bool invalidate(Function *) { return false; }
    483 
    484   private:
    485     const CGSCCAnalysisManager *CGAM;
    486   };
    487 
    488   static void *ID() { return (void *)&PassID; }
    489 
    490   CGSCCAnalysisManagerFunctionProxy(const CGSCCAnalysisManager &CGAM)
    491       : CGAM(&CGAM) {}
    492   // We have to explicitly define all the special member functions because MSVC
    493   // refuses to generate them.
    494   CGSCCAnalysisManagerFunctionProxy(
    495       const CGSCCAnalysisManagerFunctionProxy &Arg)
    496       : CGAM(Arg.CGAM) {}
    497   CGSCCAnalysisManagerFunctionProxy(CGSCCAnalysisManagerFunctionProxy &&Arg)
    498       : CGAM(std::move(Arg.CGAM)) {}
    499   CGSCCAnalysisManagerFunctionProxy &
    500   operator=(CGSCCAnalysisManagerFunctionProxy RHS) {
    501     std::swap(CGAM, RHS.CGAM);
    502     return *this;
    503   }
    504 
    505   /// \brief Run the analysis pass and create our proxy result object.
    506   /// Nothing to see here, it just forwards the \c CGAM reference into the
    507   /// result.
    508   Result run(Function *) { return Result(*CGAM); }
    509 
    510 private:
    511   static char PassID;
    512 
    513   const CGSCCAnalysisManager *CGAM;
    514 };
    515 
    516 /// \brief Adaptor that maps from a SCC to its functions.
    517 ///
    518 /// Designed to allow composition of a FunctionPass(Manager) and
    519 /// a CGSCCPassManager. Note that if this pass is constructed with a pointer
    520 /// to a \c CGSCCAnalysisManager it will run the
    521 /// \c FunctionAnalysisManagerCGSCCProxy analysis prior to running the function
    522 /// pass over the SCC to enable a \c FunctionAnalysisManager to be used
    523 /// within this run safely.
    524 template <typename FunctionPassT> class CGSCCToFunctionPassAdaptor {
    525 public:
    526   explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass)
    527       : Pass(std::move(Pass)) {}
    528   // We have to explicitly define all the special member functions because MSVC
    529   // refuses to generate them.
    530   CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
    531       : Pass(Arg.Pass) {}
    532   CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
    533       : Pass(std::move(Arg.Pass)) {}
    534   friend void swap(CGSCCToFunctionPassAdaptor &LHS, CGSCCToFunctionPassAdaptor &RHS) {
    535     using std::swap;
    536     swap(LHS.Pass, RHS.Pass);
    537   }
    538   CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
    539     swap(*this, RHS);
    540     return *this;
    541   }
    542 
    543   /// \brief Runs the function pass across every function in the module.
    544   PreservedAnalyses run(LazyCallGraph::SCC *C, CGSCCAnalysisManager *AM) {
    545     FunctionAnalysisManager *FAM = nullptr;
    546     if (AM)
    547       // Setup the function analysis manager from its proxy.
    548       FAM = &AM->getResult<FunctionAnalysisManagerCGSCCProxy>(C).getManager();
    549 
    550     PreservedAnalyses PA = PreservedAnalyses::all();
    551     for (LazyCallGraph::Node *N : *C) {
    552       PreservedAnalyses PassPA = Pass.run(&N->getFunction(), FAM);
    553 
    554       // We know that the function pass couldn't have invalidated any other
    555       // function's analyses (that's the contract of a function pass), so
    556       // directly handle the function analysis manager's invalidation here.
    557       if (FAM)
    558         FAM->invalidate(&N->getFunction(), PassPA);
    559 
    560       // Then intersect the preserved set so that invalidation of module
    561       // analyses will eventually occur when the module pass completes.
    562       PA.intersect(std::move(PassPA));
    563     }
    564 
    565     // By definition we preserve the proxy. This precludes *any* invalidation
    566     // of function analyses by the proxy, but that's OK because we've taken
    567     // care to invalidate analyses in the function analysis manager
    568     // incrementally above.
    569     // FIXME: We need to update the call graph here to account for any deleted
    570     // edges!
    571     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
    572     return PA;
    573   }
    574 
    575   static StringRef name() { return "CGSCCToFunctionPassAdaptor"; }
    576 
    577 private:
    578   FunctionPassT Pass;
    579 };
    580 
    581 /// \brief A function to deduce a function pass type and wrap it in the
    582 /// templated adaptor.
    583 template <typename FunctionPassT>
    584 CGSCCToFunctionPassAdaptor<FunctionPassT>
    585 createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
    586   return std::move(CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
    587 }
    588 
    589 }
    590 
    591 #endif
    592