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