Home | History | Annotate | Line # | Download | only in Analysis
      1 //===- CGSCCPassManager.h - Call graph pass management ----------*- C++ -*-===//
      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 /// \file
      9 ///
     10 /// This header provides classes for managing passes over SCCs of the call
     11 /// graph. These passes form an important component of LLVM's interprocedural
     12 /// optimizations. Because they operate on the SCCs of the call graph, and they
     13 /// traverse the graph in post-order, they can effectively do pair-wise
     14 /// interprocedural optimizations for all call edges in the program while
     15 /// incrementally refining it and improving the context of these pair-wise
     16 /// optimizations. At each call site edge, the callee has already been
     17 /// optimized as much as is possible. This in turn allows very accurate
     18 /// analysis of it for IPO.
     19 ///
     20 /// A secondary more general goal is to be able to isolate optimization on
     21 /// unrelated parts of the IR module. This is useful to ensure our
     22 /// optimizations are principled and don't miss oportunities where refinement
     23 /// of one part of the module influence transformations in another part of the
     24 /// module. But this is also useful if we want to parallelize the optimizations
     25 /// across common large module graph shapes which tend to be very wide and have
     26 /// large regions of unrelated cliques.
     27 ///
     28 /// To satisfy these goals, we use the LazyCallGraph which provides two graphs
     29 /// nested inside each other (and built lazily from the bottom-up): the call
     30 /// graph proper, and a reference graph. The reference graph is super set of
     31 /// the call graph and is a conservative approximation of what could through
     32 /// scalar or CGSCC transforms *become* the call graph. Using this allows us to
     33 /// ensure we optimize functions prior to them being introduced into the call
     34 /// graph by devirtualization or other technique, and thus ensures that
     35 /// subsequent pair-wise interprocedural optimizations observe the optimized
     36 /// form of these functions. The (potentially transitive) reference
     37 /// reachability used by the reference graph is a conservative approximation
     38 /// that still allows us to have independent regions of the graph.
     39 ///
     40 /// FIXME: There is one major drawback of the reference graph: in its naive
     41 /// form it is quadratic because it contains a distinct edge for each
     42 /// (potentially indirect) reference, even if are all through some common
     43 /// global table of function pointers. This can be fixed in a number of ways
     44 /// that essentially preserve enough of the normalization. While it isn't
     45 /// expected to completely preclude the usability of this, it will need to be
     46 /// addressed.
     47 ///
     48 ///
     49 /// All of these issues are made substantially more complex in the face of
     50 /// mutations to the call graph while optimization passes are being run. When
     51 /// mutations to the call graph occur we want to achieve two different things:
     52 ///
     53 /// - We need to update the call graph in-flight and invalidate analyses
     54 ///   cached on entities in the graph. Because of the cache-based analysis
     55 ///   design of the pass manager, it is essential to have stable identities for
     56 ///   the elements of the IR that passes traverse, and to invalidate any
     57 ///   analyses cached on these elements as the mutations take place.
     58 ///
     59 /// - We want to preserve the incremental and post-order traversal of the
     60 ///   graph even as it is refined and mutated. This means we want optimization
     61 ///   to observe the most refined form of the call graph and to do so in
     62 ///   post-order.
     63 ///
     64 /// To address this, the CGSCC manager uses both worklists that can be expanded
     65 /// by passes which transform the IR, and provides invalidation tests to skip
     66 /// entries that become dead. This extra data is provided to every SCC pass so
     67 /// that it can carefully update the manager's traversal as the call graph
     68 /// mutates.
     69 ///
     70 /// We also provide support for running function passes within the CGSCC walk,
     71 /// and there we provide automatic update of the call graph including of the
     72 /// pass manager to reflect call graph changes that fall out naturally as part
     73 /// of scalar transformations.
     74 ///
     75 /// The patterns used to ensure the goals of post-order visitation of the fully
     76 /// refined graph:
     77 ///
     78 /// 1) Sink toward the "bottom" as the graph is refined. This means that any
     79 ///    iteration continues in some valid post-order sequence after the mutation
     80 ///    has altered the structure.
     81 ///
     82 /// 2) Enqueue in post-order, including the current entity. If the current
     83 ///    entity's shape changes, it and everything after it in post-order needs
     84 ///    to be visited to observe that shape.
     85 ///
     86 //===----------------------------------------------------------------------===//
     87 
     88 #ifndef LLVM_ANALYSIS_CGSCCPASSMANAGER_H
     89 #define LLVM_ANALYSIS_CGSCCPASSMANAGER_H
     90 
     91 #include "llvm/ADT/DenseMap.h"
     92 #include "llvm/ADT/DenseSet.h"
     93 #include "llvm/ADT/MapVector.h"
     94 #include "llvm/ADT/PriorityWorklist.h"
     95 #include "llvm/ADT/STLExtras.h"
     96 #include "llvm/ADT/SmallPtrSet.h"
     97 #include "llvm/ADT/SmallVector.h"
     98 #include "llvm/Analysis/LazyCallGraph.h"
     99 #include "llvm/IR/Function.h"
    100 #include "llvm/IR/InstIterator.h"
    101 #include "llvm/IR/PassManager.h"
    102 #include "llvm/IR/ValueHandle.h"
    103 #include "llvm/Support/Debug.h"
    104 #include "llvm/Support/raw_ostream.h"
    105 #include <algorithm>
    106 #include <cassert>
    107 #include <utility>
    108 
    109 namespace llvm {
    110 
    111 struct CGSCCUpdateResult;
    112 class Module;
    113 
    114 // Allow debug logging in this inline function.
    115 #define DEBUG_TYPE "cgscc"
    116 
    117 /// Extern template declaration for the analysis set for this IR unit.
    118 extern template class AllAnalysesOn<LazyCallGraph::SCC>;
    119 
    120 extern template class AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
    121 
    122 /// The CGSCC analysis manager.
    123 ///
    124 /// See the documentation for the AnalysisManager template for detail
    125 /// documentation. This type serves as a convenient way to refer to this
    126 /// construct in the adaptors and proxies used to integrate this into the larger
    127 /// pass manager infrastructure.
    128 using CGSCCAnalysisManager =
    129     AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
    130 
    131 // Explicit specialization and instantiation declarations for the pass manager.
    132 // See the comments on the definition of the specialization for details on how
    133 // it differs from the primary template.
    134 template <>
    135 PreservedAnalyses
    136 PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
    137             CGSCCUpdateResult &>::run(LazyCallGraph::SCC &InitialC,
    138                                       CGSCCAnalysisManager &AM,
    139                                       LazyCallGraph &G, CGSCCUpdateResult &UR);
    140 extern template class PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager,
    141                                   LazyCallGraph &, CGSCCUpdateResult &>;
    142 
    143 /// The CGSCC pass manager.
    144 ///
    145 /// See the documentation for the PassManager template for details. It runs
    146 /// a sequence of SCC passes over each SCC that the manager is run over. This
    147 /// type serves as a convenient way to refer to this construct.
    148 using CGSCCPassManager =
    149     PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
    150                 CGSCCUpdateResult &>;
    151 
    152 /// An explicit specialization of the require analysis template pass.
    153 template <typename AnalysisT>
    154 struct RequireAnalysisPass<AnalysisT, LazyCallGraph::SCC, CGSCCAnalysisManager,
    155                            LazyCallGraph &, CGSCCUpdateResult &>
    156     : PassInfoMixin<RequireAnalysisPass<AnalysisT, LazyCallGraph::SCC,
    157                                         CGSCCAnalysisManager, LazyCallGraph &,
    158                                         CGSCCUpdateResult &>> {
    159   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
    160                         LazyCallGraph &CG, CGSCCUpdateResult &) {
    161     (void)AM.template getResult<AnalysisT>(C, CG);
    162     return PreservedAnalyses::all();
    163   }
    164 };
    165 
    166 /// A proxy from a \c CGSCCAnalysisManager to a \c Module.
    167 using CGSCCAnalysisManagerModuleProxy =
    168     InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
    169 
    170 /// We need a specialized result for the \c CGSCCAnalysisManagerModuleProxy so
    171 /// it can have access to the call graph in order to walk all the SCCs when
    172 /// invalidating things.
    173 template <> class CGSCCAnalysisManagerModuleProxy::Result {
    174 public:
    175   explicit Result(CGSCCAnalysisManager &InnerAM, LazyCallGraph &G)
    176       : InnerAM(&InnerAM), G(&G) {}
    177 
    178   /// Accessor for the analysis manager.
    179   CGSCCAnalysisManager &getManager() { return *InnerAM; }
    180 
    181   /// Handler for invalidation of the Module.
    182   ///
    183   /// If the proxy analysis itself is preserved, then we assume that the set of
    184   /// SCCs in the Module hasn't changed. Thus any pointers to SCCs in the
    185   /// CGSCCAnalysisManager are still valid, and we don't need to call \c clear
    186   /// on the CGSCCAnalysisManager.
    187   ///
    188   /// Regardless of whether this analysis is marked as preserved, all of the
    189   /// analyses in the \c CGSCCAnalysisManager are potentially invalidated based
    190   /// on the set of preserved analyses.
    191   bool invalidate(Module &M, const PreservedAnalyses &PA,
    192                   ModuleAnalysisManager::Invalidator &Inv);
    193 
    194 private:
    195   CGSCCAnalysisManager *InnerAM;
    196   LazyCallGraph *G;
    197 };
    198 
    199 /// Provide a specialized run method for the \c CGSCCAnalysisManagerModuleProxy
    200 /// so it can pass the lazy call graph to the result.
    201 template <>
    202 CGSCCAnalysisManagerModuleProxy::Result
    203 CGSCCAnalysisManagerModuleProxy::run(Module &M, ModuleAnalysisManager &AM);
    204 
    205 // Ensure the \c CGSCCAnalysisManagerModuleProxy is provided as an extern
    206 // template.
    207 extern template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
    208 
    209 extern template class OuterAnalysisManagerProxy<
    210     ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph &>;
    211 
    212 /// A proxy from a \c ModuleAnalysisManager to an \c SCC.
    213 using ModuleAnalysisManagerCGSCCProxy =
    214     OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC,
    215                               LazyCallGraph &>;
    216 
    217 /// Support structure for SCC passes to communicate updates the call graph back
    218 /// to the CGSCC pass manager infrsatructure.
    219 ///
    220 /// The CGSCC pass manager runs SCC passes which are allowed to update the call
    221 /// graph and SCC structures. This means the structure the pass manager works
    222 /// on is mutating underneath it. In order to support that, there needs to be
    223 /// careful communication about the precise nature and ramifications of these
    224 /// updates to the pass management infrastructure.
    225 ///
    226 /// All SCC passes will have to accept a reference to the management layer's
    227 /// update result struct and use it to reflect the results of any CG updates
    228 /// performed.
    229 ///
    230 /// Passes which do not change the call graph structure in any way can just
    231 /// ignore this argument to their run method.
    232 struct CGSCCUpdateResult {
    233   /// Worklist of the RefSCCs queued for processing.
    234   ///
    235   /// When a pass refines the graph and creates new RefSCCs or causes them to
    236   /// have a different shape or set of component SCCs it should add the RefSCCs
    237   /// to this worklist so that we visit them in the refined form.
    238   ///
    239   /// This worklist is in reverse post-order, as we pop off the back in order
    240   /// to observe RefSCCs in post-order. When adding RefSCCs, clients should add
    241   /// them in reverse post-order.
    242   SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> &RCWorklist;
    243 
    244   /// Worklist of the SCCs queued for processing.
    245   ///
    246   /// When a pass refines the graph and creates new SCCs or causes them to have
    247   /// a different shape or set of component functions it should add the SCCs to
    248   /// this worklist so that we visit them in the refined form.
    249   ///
    250   /// Note that if the SCCs are part of a RefSCC that is added to the \c
    251   /// RCWorklist, they don't need to be added here as visiting the RefSCC will
    252   /// be sufficient to re-visit the SCCs within it.
    253   ///
    254   /// This worklist is in reverse post-order, as we pop off the back in order
    255   /// to observe SCCs in post-order. When adding SCCs, clients should add them
    256   /// in reverse post-order.
    257   SmallPriorityWorklist<LazyCallGraph::SCC *, 1> &CWorklist;
    258 
    259   /// The set of invalidated RefSCCs which should be skipped if they are found
    260   /// in \c RCWorklist.
    261   ///
    262   /// This is used to quickly prune out RefSCCs when they get deleted and
    263   /// happen to already be on the worklist. We use this primarily to avoid
    264   /// scanning the list and removing entries from it.
    265   SmallPtrSetImpl<LazyCallGraph::RefSCC *> &InvalidatedRefSCCs;
    266 
    267   /// The set of invalidated SCCs which should be skipped if they are found
    268   /// in \c CWorklist.
    269   ///
    270   /// This is used to quickly prune out SCCs when they get deleted and happen
    271   /// to already be on the worklist. We use this primarily to avoid scanning
    272   /// the list and removing entries from it.
    273   SmallPtrSetImpl<LazyCallGraph::SCC *> &InvalidatedSCCs;
    274 
    275   /// If non-null, the updated current \c RefSCC being processed.
    276   ///
    277   /// This is set when a graph refinement takes place an the "current" point in
    278   /// the graph moves "down" or earlier in the post-order walk. This will often
    279   /// cause the "current" RefSCC to be a newly created RefSCC object and the
    280   /// old one to be added to the above worklist. When that happens, this
    281   /// pointer is non-null and can be used to continue processing the "top" of
    282   /// the post-order walk.
    283   LazyCallGraph::RefSCC *UpdatedRC;
    284 
    285   /// If non-null, the updated current \c SCC being processed.
    286   ///
    287   /// This is set when a graph refinement takes place an the "current" point in
    288   /// the graph moves "down" or earlier in the post-order walk. This will often
    289   /// cause the "current" SCC to be a newly created SCC object and the old one
    290   /// to be added to the above worklist. When that happens, this pointer is
    291   /// non-null and can be used to continue processing the "top" of the
    292   /// post-order walk.
    293   LazyCallGraph::SCC *UpdatedC;
    294 
    295   /// Preserved analyses across SCCs.
    296   ///
    297   /// We specifically want to allow CGSCC passes to mutate ancestor IR
    298   /// (changing both the CG structure and the function IR itself). However,
    299   /// this means we need to take special care to correctly mark what analyses
    300   /// are preserved *across* SCCs. We have to track this out-of-band here
    301   /// because within the main `PassManeger` infrastructure we need to mark
    302   /// everything within an SCC as preserved in order to avoid repeatedly
    303   /// invalidating the same analyses as we unnest pass managers and adaptors.
    304   /// So we track the cross-SCC version of the preserved analyses here from any
    305   /// code that does direct invalidation of SCC analyses, and then use it
    306   /// whenever we move forward in the post-order walk of SCCs before running
    307   /// passes over the new SCC.
    308   PreservedAnalyses CrossSCCPA;
    309 
    310   /// A hacky area where the inliner can retain history about inlining
    311   /// decisions that mutated the call graph's SCC structure in order to avoid
    312   /// infinite inlining. See the comments in the inliner's CG update logic.
    313   ///
    314   /// FIXME: Keeping this here seems like a big layering issue, we should look
    315   /// for a better technique.
    316   SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4>
    317       &InlinedInternalEdges;
    318 
    319   /// Weak VHs to keep track of indirect calls for the purposes of detecting
    320   /// devirtualization.
    321   ///
    322   /// This is a map to avoid having duplicate entries. If a Value is
    323   /// deallocated, its corresponding WeakTrackingVH will be nulled out. When
    324   /// checking if a Value is in the map or not, also check if the corresponding
    325   /// WeakTrackingVH is null to avoid issues with a new Value sharing the same
    326   /// address as a deallocated one.
    327   SmallMapVector<Value *, WeakTrackingVH, 16> IndirectVHs;
    328 };
    329 
    330 /// The core module pass which does a post-order walk of the SCCs and
    331 /// runs a CGSCC pass over each one.
    332 ///
    333 /// Designed to allow composition of a CGSCCPass(Manager) and
    334 /// a ModulePassManager. Note that this pass must be run with a module analysis
    335 /// manager as it uses the LazyCallGraph analysis. It will also run the
    336 /// \c CGSCCAnalysisManagerModuleProxy analysis prior to running the CGSCC
    337 /// pass over the module to enable a \c FunctionAnalysisManager to be used
    338 /// within this run safely.
    339 class ModuleToPostOrderCGSCCPassAdaptor
    340     : public PassInfoMixin<ModuleToPostOrderCGSCCPassAdaptor> {
    341 public:
    342   using PassConceptT =
    343       detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
    344                           LazyCallGraph &, CGSCCUpdateResult &>;
    345 
    346   explicit ModuleToPostOrderCGSCCPassAdaptor(std::unique_ptr<PassConceptT> Pass)
    347       : Pass(std::move(Pass)) {}
    348 
    349   ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
    350       : Pass(std::move(Arg.Pass)) {}
    351 
    352   friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
    353                    ModuleToPostOrderCGSCCPassAdaptor &RHS) {
    354     std::swap(LHS.Pass, RHS.Pass);
    355   }
    356 
    357   ModuleToPostOrderCGSCCPassAdaptor &
    358   operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
    359     swap(*this, RHS);
    360     return *this;
    361   }
    362 
    363   /// Runs the CGSCC pass across every SCC in the module.
    364   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
    365 
    366   static bool isRequired() { return true; }
    367 
    368 private:
    369   std::unique_ptr<PassConceptT> Pass;
    370 };
    371 
    372 /// A function to deduce a function pass type and wrap it in the
    373 /// templated adaptor.
    374 template <typename CGSCCPassT>
    375 ModuleToPostOrderCGSCCPassAdaptor
    376 createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
    377   using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
    378                                        PreservedAnalyses, CGSCCAnalysisManager,
    379                                        LazyCallGraph &, CGSCCUpdateResult &>;
    380   return ModuleToPostOrderCGSCCPassAdaptor(
    381       std::make_unique<PassModelT>(std::move(Pass)));
    382 }
    383 
    384 /// A proxy from a \c FunctionAnalysisManager to an \c SCC.
    385 ///
    386 /// When a module pass runs and triggers invalidation, both the CGSCC and
    387 /// Function analysis manager proxies on the module get an invalidation event.
    388 /// We don't want to fully duplicate responsibility for most of the
    389 /// invalidation logic. Instead, this layer is only responsible for SCC-local
    390 /// invalidation events. We work with the module's FunctionAnalysisManager to
    391 /// invalidate function analyses.
    392 class FunctionAnalysisManagerCGSCCProxy
    393     : public AnalysisInfoMixin<FunctionAnalysisManagerCGSCCProxy> {
    394 public:
    395   class Result {
    396   public:
    397     explicit Result() : FAM(nullptr) {}
    398     explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
    399 
    400     void updateFAM(FunctionAnalysisManager &FAM) { this->FAM = &FAM; }
    401     /// Accessor for the analysis manager.
    402     FunctionAnalysisManager &getManager() {
    403       assert(FAM);
    404       return *FAM;
    405     }
    406 
    407     bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
    408                     CGSCCAnalysisManager::Invalidator &Inv);
    409 
    410   private:
    411     FunctionAnalysisManager *FAM;
    412   };
    413 
    414   /// Computes the \c FunctionAnalysisManager and stores it in the result proxy.
    415   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &);
    416 
    417 private:
    418   friend AnalysisInfoMixin<FunctionAnalysisManagerCGSCCProxy>;
    419 
    420   static AnalysisKey Key;
    421 };
    422 
    423 extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
    424 
    425 /// A proxy from a \c CGSCCAnalysisManager to a \c Function.
    426 using CGSCCAnalysisManagerFunctionProxy =
    427     OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
    428 
    429 /// Helper to update the call graph after running a function pass.
    430 ///
    431 /// Function passes can only mutate the call graph in specific ways. This
    432 /// routine provides a helper that updates the call graph in those ways
    433 /// including returning whether any changes were made and populating a CG
    434 /// update result struct for the overall CGSCC walk.
    435 LazyCallGraph::SCC &updateCGAndAnalysisManagerForFunctionPass(
    436     LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
    437     CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
    438     FunctionAnalysisManager &FAM);
    439 
    440 /// Helper to update the call graph after running a CGSCC pass.
    441 ///
    442 /// CGSCC passes can only mutate the call graph in specific ways. This
    443 /// routine provides a helper that updates the call graph in those ways
    444 /// including returning whether any changes were made and populating a CG
    445 /// update result struct for the overall CGSCC walk.
    446 LazyCallGraph::SCC &updateCGAndAnalysisManagerForCGSCCPass(
    447     LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
    448     CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
    449     FunctionAnalysisManager &FAM);
    450 
    451 /// Adaptor that maps from a SCC to its functions.
    452 ///
    453 /// Designed to allow composition of a FunctionPass(Manager) and
    454 /// a CGSCCPassManager. Note that if this pass is constructed with a pointer
    455 /// to a \c CGSCCAnalysisManager it will run the
    456 /// \c FunctionAnalysisManagerCGSCCProxy analysis prior to running the function
    457 /// pass over the SCC to enable a \c FunctionAnalysisManager to be used
    458 /// within this run safely.
    459 class CGSCCToFunctionPassAdaptor
    460     : public PassInfoMixin<CGSCCToFunctionPassAdaptor> {
    461 public:
    462   using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
    463 
    464   explicit CGSCCToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass)
    465       : Pass(std::move(Pass)) {}
    466 
    467   CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
    468       : Pass(std::move(Arg.Pass)) {}
    469 
    470   friend void swap(CGSCCToFunctionPassAdaptor &LHS,
    471                    CGSCCToFunctionPassAdaptor &RHS) {
    472     std::swap(LHS.Pass, RHS.Pass);
    473   }
    474 
    475   CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
    476     swap(*this, RHS);
    477     return *this;
    478   }
    479 
    480   /// Runs the function pass across every function in the module.
    481   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
    482                         LazyCallGraph &CG, CGSCCUpdateResult &UR);
    483 
    484   static bool isRequired() { return true; }
    485 
    486 private:
    487   std::unique_ptr<PassConceptT> Pass;
    488 };
    489 
    490 /// A function to deduce a function pass type and wrap it in the
    491 /// templated adaptor.
    492 template <typename FunctionPassT>
    493 CGSCCToFunctionPassAdaptor
    494 createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
    495   using PassModelT =
    496       detail::PassModel<Function, FunctionPassT, PreservedAnalyses,
    497                         FunctionAnalysisManager>;
    498   return CGSCCToFunctionPassAdaptor(
    499       std::make_unique<PassModelT>(std::move(Pass)));
    500 }
    501 
    502 /// A helper that repeats an SCC pass each time an indirect call is refined to
    503 /// a direct call by that pass.
    504 ///
    505 /// While the CGSCC pass manager works to re-visit SCCs and RefSCCs as they
    506 /// change shape, we may also want to repeat an SCC pass if it simply refines
    507 /// an indirect call to a direct call, even if doing so does not alter the
    508 /// shape of the graph. Note that this only pertains to direct calls to
    509 /// functions where IPO across the SCC may be able to compute more precise
    510 /// results. For intrinsics, we assume scalar optimizations already can fully
    511 /// reason about them.
    512 ///
    513 /// This repetition has the potential to be very large however, as each one
    514 /// might refine a single call site. As a consequence, in practice we use an
    515 /// upper bound on the number of repetitions to limit things.
    516 class DevirtSCCRepeatedPass : public PassInfoMixin<DevirtSCCRepeatedPass> {
    517 public:
    518   using PassConceptT =
    519       detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
    520                           LazyCallGraph &, CGSCCUpdateResult &>;
    521 
    522   explicit DevirtSCCRepeatedPass(std::unique_ptr<PassConceptT> Pass,
    523                                  int MaxIterations)
    524       : Pass(std::move(Pass)), MaxIterations(MaxIterations) {}
    525 
    526   /// Runs the wrapped pass up to \c MaxIterations on the SCC, iterating
    527   /// whenever an indirect call is refined.
    528   PreservedAnalyses run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM,
    529                         LazyCallGraph &CG, CGSCCUpdateResult &UR);
    530 
    531 private:
    532   std::unique_ptr<PassConceptT> Pass;
    533   int MaxIterations;
    534 };
    535 
    536 /// A function to deduce a function pass type and wrap it in the
    537 /// templated adaptor.
    538 template <typename CGSCCPassT>
    539 DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT Pass,
    540                                                   int MaxIterations) {
    541   using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
    542                                        PreservedAnalyses, CGSCCAnalysisManager,
    543                                        LazyCallGraph &, CGSCCUpdateResult &>;
    544   return DevirtSCCRepeatedPass(std::make_unique<PassModelT>(std::move(Pass)),
    545                                MaxIterations);
    546 }
    547 
    548 // Clear out the debug logging macro.
    549 #undef DEBUG_TYPE
    550 
    551 } // end namespace llvm
    552 
    553 #endif // LLVM_ANALYSIS_CGSCCPASSMANAGER_H
    554