1259698Sdim//===- PassManager.h - Pass management infrastructure -----------*- C++ -*-===//
2259698Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6259698Sdim//
7259698Sdim//===----------------------------------------------------------------------===//
8259698Sdim/// \file
9259698Sdim///
10259698Sdim/// This header defines various interfaces for pass management in LLVM. There
11259698Sdim/// is no "pass" interface in LLVM per se. Instead, an instance of any class
12259698Sdim/// which supports a method to 'run' it over a unit of IR can be used as
13259698Sdim/// a pass. A pass manager is generally a tool to collect a sequence of passes
14259698Sdim/// which run over a particular IR construct, and run each of them in sequence
15259698Sdim/// over each such construct in the containing IR construct. As there is no
16259698Sdim/// containing IR construct for a Module, a manager for passes over modules
17259698Sdim/// forms the base case which runs its managed passes in sequence over the
18259698Sdim/// single module provided.
19259698Sdim///
20259698Sdim/// The core IR library provides managers for running passes over
21259698Sdim/// modules and functions.
22259698Sdim///
23259698Sdim/// * FunctionPassManager can run over a Module, runs each pass over
24259698Sdim///   a Function.
25259698Sdim/// * ModulePassManager must be directly run, runs each pass over the Module.
26259698Sdim///
27259698Sdim/// Note that the implementations of the pass managers use concept-based
28259698Sdim/// polymorphism as outlined in the "Value Semantics and Concept-based
29259698Sdim/// Polymorphism" talk (or its abbreviated sibling "Inheritance Is The Base
30259698Sdim/// Class of Evil") by Sean Parent:
31259698Sdim/// * http://github.com/sean-parent/sean-parent.github.com/wiki/Papers-and-Presentations
32259698Sdim/// * http://www.youtube.com/watch?v=_BpMYeUFXv8
33259698Sdim/// * http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil
34259698Sdim///
35259698Sdim//===----------------------------------------------------------------------===//
36259698Sdim
37280031Sdim#ifndef LLVM_IR_PASSMANAGER_H
38280031Sdim#define LLVM_IR_PASSMANAGER_H
39276479Sdim
40259698Sdim#include "llvm/ADT/DenseMap.h"
41276479Sdim#include "llvm/ADT/SmallPtrSet.h"
42321369Sdim#include "llvm/ADT/StringRef.h"
43314564Sdim#include "llvm/ADT/TinyPtrVector.h"
44259698Sdim#include "llvm/IR/Function.h"
45259698Sdim#include "llvm/IR/Module.h"
46344779Sdim#include "llvm/IR/PassInstrumentation.h"
47280031Sdim#include "llvm/IR/PassManagerInternal.h"
48360784Sdim#include "llvm/Pass.h"
49280031Sdim#include "llvm/Support/Debug.h"
50309124Sdim#include "llvm/Support/TypeName.h"
51288943Sdim#include "llvm/Support/raw_ostream.h"
52321369Sdim#include <algorithm>
53321369Sdim#include <cassert>
54321369Sdim#include <cstring>
55321369Sdim#include <iterator>
56259698Sdim#include <list>
57276479Sdim#include <memory>
58321369Sdim#include <tuple>
59321369Sdim#include <type_traits>
60321369Sdim#include <utility>
61259698Sdim#include <vector>
62259698Sdim
63259698Sdimnamespace llvm {
64259698Sdim
65314564Sdim/// A special type used by analysis passes to provide an address that
66314564Sdim/// identifies that particular analysis pass type.
67276479Sdim///
68314564Sdim/// Analysis passes should have a static data member of this type and derive
69314564Sdim/// from the \c AnalysisInfoMixin to get a static ID method used to identify
70314564Sdim/// the analysis in the pass management infrastructure.
71314564Sdimstruct alignas(8) AnalysisKey {};
72314564Sdim
73314564Sdim/// A special type used to provide an address that identifies a set of related
74314564Sdim/// analyses.  These sets are primarily used below to mark sets of analyses as
75314564Sdim/// preserved.
76276479Sdim///
77314564Sdim/// For example, a transformation can indicate that it preserves the CFG of a
78314564Sdim/// function by preserving the appropriate AnalysisSetKey.  An analysis that
79314564Sdim/// depends only on the CFG can then check if that AnalysisSetKey is preserved;
80314564Sdim/// if it is, the analysis knows that it itself is preserved.
81314564Sdimstruct alignas(8) AnalysisSetKey {};
82314564Sdim
83321369Sdim/// This templated class represents "all analyses that operate over \<a
84321369Sdim/// particular IR unit\>" (e.g. a Function or a Module) in instances of
85321369Sdim/// PreservedAnalysis.
86321369Sdim///
87321369Sdim/// This lets a transformation say e.g. "I preserved all function analyses".
88321369Sdim///
89321369Sdim/// Note that you must provide an explicit instantiation declaration and
90321369Sdim/// definition for this template in order to get the correct behavior on
91321369Sdim/// Windows. Otherwise, the address of SetKey will not be stable.
92321369Sdimtemplate <typename IRUnitT> class AllAnalysesOn {
93321369Sdimpublic:
94321369Sdim  static AnalysisSetKey *ID() { return &SetKey; }
95321369Sdim
96321369Sdimprivate:
97321369Sdim  static AnalysisSetKey SetKey;
98321369Sdim};
99321369Sdim
100321369Sdimtemplate <typename IRUnitT> AnalysisSetKey AllAnalysesOn<IRUnitT>::SetKey;
101321369Sdim
102321369Sdimextern template class AllAnalysesOn<Module>;
103321369Sdimextern template class AllAnalysesOn<Function>;
104321369Sdim
105321369Sdim/// Represents analyses that only rely on functions' control flow.
106321369Sdim///
107321369Sdim/// This can be used with \c PreservedAnalyses to mark the CFG as preserved and
108321369Sdim/// to query whether it has been preserved.
109321369Sdim///
110321369Sdim/// The CFG of a function is defined as the set of basic blocks and the edges
111321369Sdim/// between them. Changing the set of basic blocks in a function is enough to
112321369Sdim/// mutate the CFG. Mutating the condition of a branch or argument of an
113321369Sdim/// invoked function does not mutate the CFG, but changing the successor labels
114321369Sdim/// of those instructions does.
115321369Sdimclass CFGAnalyses {
116321369Sdimpublic:
117321369Sdim  static AnalysisSetKey *ID() { return &SetKey; }
118321369Sdim
119321369Sdimprivate:
120321369Sdim  static AnalysisSetKey SetKey;
121321369Sdim};
122321369Sdim
123314564Sdim/// A set of analyses that are preserved following a run of a transformation
124314564Sdim/// pass.
125314564Sdim///
126314564Sdim/// Transformation passes build and return these objects to communicate which
127314564Sdim/// analyses are still valid after the transformation. For most passes this is
128314564Sdim/// fairly simple: if they don't change anything all analyses are preserved,
129314564Sdim/// otherwise only a short list of analyses that have been explicitly updated
130314564Sdim/// are preserved.
131314564Sdim///
132314564Sdim/// This class also lets transformation passes mark abstract *sets* of analyses
133314564Sdim/// as preserved. A transformation that (say) does not alter the CFG can
134314564Sdim/// indicate such by marking a particular AnalysisSetKey as preserved, and
135314564Sdim/// then analyses can query whether that AnalysisSetKey is preserved.
136314564Sdim///
137314564Sdim/// Finally, this class can represent an "abandoned" analysis, which is
138314564Sdim/// not preserved even if it would be covered by some abstract set of analyses.
139314564Sdim///
140314564Sdim/// Given a `PreservedAnalyses` object, an analysis will typically want to
141314564Sdim/// figure out whether it is preserved. In the example below, MyAnalysisType is
142314564Sdim/// preserved if it's not abandoned, and (a) it's explicitly marked as
143314564Sdim/// preserved, (b), the set AllAnalysesOn<MyIRUnit> is preserved, or (c) both
144314564Sdim/// AnalysisSetA and AnalysisSetB are preserved.
145314564Sdim///
146314564Sdim/// ```
147314564Sdim///   auto PAC = PA.getChecker<MyAnalysisType>();
148314564Sdim///   if (PAC.preserved() || PAC.preservedSet<AllAnalysesOn<MyIRUnit>>() ||
149314564Sdim///       (PAC.preservedSet<AnalysisSetA>() &&
150314564Sdim///        PAC.preservedSet<AnalysisSetB>())) {
151314564Sdim///     // The analysis has been successfully preserved ...
152314564Sdim///   }
153314564Sdim/// ```
154276479Sdimclass PreservedAnalyses {
155276479Sdimpublic:
156341825Sdim  /// Convenience factory function for the empty preserved set.
157276479Sdim  static PreservedAnalyses none() { return PreservedAnalyses(); }
158276479Sdim
159341825Sdim  /// Construct a special preserved set that preserves all passes.
160276479Sdim  static PreservedAnalyses all() {
161276479Sdim    PreservedAnalyses PA;
162314564Sdim    PA.PreservedIDs.insert(&AllAnalysesKey);
163276479Sdim    return PA;
164276479Sdim  }
165276479Sdim
166341825Sdim  /// Construct a preserved analyses object with a single preserved set.
167321369Sdim  template <typename AnalysisSetT>
168321369Sdim  static PreservedAnalyses allInSet() {
169321369Sdim    PreservedAnalyses PA;
170321369Sdim    PA.preserveSet<AnalysisSetT>();
171321369Sdim    return PA;
172321369Sdim  }
173321369Sdim
174314564Sdim  /// Mark an analysis as preserved.
175314564Sdim  template <typename AnalysisT> void preserve() { preserve(AnalysisT::ID()); }
176280031Sdim
177341825Sdim  /// Given an analysis's ID, mark the analysis as preserved, adding it
178314564Sdim  /// to the set.
179314564Sdim  void preserve(AnalysisKey *ID) {
180314564Sdim    // Clear this ID from the explicit not-preserved set if present.
181314564Sdim    NotPreservedAnalysisIDs.erase(ID);
182314564Sdim
183314564Sdim    // If we're not already preserving all analyses (other than those in
184314564Sdim    // NotPreservedAnalysisIDs).
185276479Sdim    if (!areAllPreserved())
186314564Sdim      PreservedIDs.insert(ID);
187276479Sdim  }
188276479Sdim
189314564Sdim  /// Mark an analysis set as preserved.
190314564Sdim  template <typename AnalysisSetT> void preserveSet() {
191314564Sdim    preserveSet(AnalysisSetT::ID());
192314564Sdim  }
193314564Sdim
194314564Sdim  /// Mark an analysis set as preserved using its ID.
195314564Sdim  void preserveSet(AnalysisSetKey *ID) {
196314564Sdim    // If we're not already in the saturated 'all' state, add this set.
197314564Sdim    if (!areAllPreserved())
198314564Sdim      PreservedIDs.insert(ID);
199314564Sdim  }
200314564Sdim
201314564Sdim  /// Mark an analysis as abandoned.
202314564Sdim  ///
203314564Sdim  /// An abandoned analysis is not preserved, even if it is nominally covered
204314564Sdim  /// by some other set or was previously explicitly marked as preserved.
205314564Sdim  ///
206314564Sdim  /// Note that you can only abandon a specific analysis, not a *set* of
207314564Sdim  /// analyses.
208314564Sdim  template <typename AnalysisT> void abandon() { abandon(AnalysisT::ID()); }
209314564Sdim
210314564Sdim  /// Mark an analysis as abandoned using its ID.
211314564Sdim  ///
212314564Sdim  /// An abandoned analysis is not preserved, even if it is nominally covered
213314564Sdim  /// by some other set or was previously explicitly marked as preserved.
214314564Sdim  ///
215314564Sdim  /// Note that you can only abandon a specific analysis, not a *set* of
216314564Sdim  /// analyses.
217314564Sdim  void abandon(AnalysisKey *ID) {
218314564Sdim    PreservedIDs.erase(ID);
219314564Sdim    NotPreservedAnalysisIDs.insert(ID);
220314564Sdim  }
221314564Sdim
222341825Sdim  /// Intersect this set with another in place.
223276479Sdim  ///
224276479Sdim  /// This is a mutating operation on this preserved set, removing all
225276479Sdim  /// preserved passes which are not also preserved in the argument.
226276479Sdim  void intersect(const PreservedAnalyses &Arg) {
227276479Sdim    if (Arg.areAllPreserved())
228276479Sdim      return;
229276479Sdim    if (areAllPreserved()) {
230314564Sdim      *this = Arg;
231276479Sdim      return;
232276479Sdim    }
233314564Sdim    // The intersection requires the *union* of the explicitly not-preserved
234314564Sdim    // IDs and the *intersection* of the preserved IDs.
235314564Sdim    for (auto ID : Arg.NotPreservedAnalysisIDs) {
236314564Sdim      PreservedIDs.erase(ID);
237314564Sdim      NotPreservedAnalysisIDs.insert(ID);
238314564Sdim    }
239314564Sdim    for (auto ID : PreservedIDs)
240314564Sdim      if (!Arg.PreservedIDs.count(ID))
241314564Sdim        PreservedIDs.erase(ID);
242276479Sdim  }
243276479Sdim
244341825Sdim  /// Intersect this set with a temporary other set in place.
245276479Sdim  ///
246276479Sdim  /// This is a mutating operation on this preserved set, removing all
247276479Sdim  /// preserved passes which are not also preserved in the argument.
248276479Sdim  void intersect(PreservedAnalyses &&Arg) {
249276479Sdim    if (Arg.areAllPreserved())
250276479Sdim      return;
251276479Sdim    if (areAllPreserved()) {
252314564Sdim      *this = std::move(Arg);
253276479Sdim      return;
254276479Sdim    }
255314564Sdim    // The intersection requires the *union* of the explicitly not-preserved
256314564Sdim    // IDs and the *intersection* of the preserved IDs.
257314564Sdim    for (auto ID : Arg.NotPreservedAnalysisIDs) {
258314564Sdim      PreservedIDs.erase(ID);
259314564Sdim      NotPreservedAnalysisIDs.insert(ID);
260314564Sdim    }
261314564Sdim    for (auto ID : PreservedIDs)
262314564Sdim      if (!Arg.PreservedIDs.count(ID))
263314564Sdim        PreservedIDs.erase(ID);
264276479Sdim  }
265276479Sdim
266314564Sdim  /// A checker object that makes it easy to query for whether an analysis or
267314564Sdim  /// some set covering it is preserved.
268314564Sdim  class PreservedAnalysisChecker {
269314564Sdim    friend class PreservedAnalyses;
270276479Sdim
271314564Sdim    const PreservedAnalyses &PA;
272314564Sdim    AnalysisKey *const ID;
273314564Sdim    const bool IsAbandoned;
274314564Sdim
275314564Sdim    /// A PreservedAnalysisChecker is tied to a particular Analysis because
276314564Sdim    /// `preserved()` and `preservedSet()` both return false if the Analysis
277314564Sdim    /// was abandoned.
278314564Sdim    PreservedAnalysisChecker(const PreservedAnalyses &PA, AnalysisKey *ID)
279314564Sdim        : PA(PA), ID(ID), IsAbandoned(PA.NotPreservedAnalysisIDs.count(ID)) {}
280314564Sdim
281314564Sdim  public:
282314564Sdim    /// Returns true if the checker's analysis was not abandoned and either
283314564Sdim    ///  - the analysis is explicitly preserved or
284314564Sdim    ///  - all analyses are preserved.
285314564Sdim    bool preserved() {
286314564Sdim      return !IsAbandoned && (PA.PreservedIDs.count(&AllAnalysesKey) ||
287314564Sdim                              PA.PreservedIDs.count(ID));
288314564Sdim    }
289314564Sdim
290353358Sdim    /// Return true if the checker's analysis was not abandoned, i.e. it was not
291353358Sdim    /// explicitly invalidated. Even if the analysis is not explicitly
292353358Sdim    /// preserved, if the analysis is known stateless, then it is preserved.
293353358Sdim    bool preservedWhenStateless() {
294353358Sdim      return !IsAbandoned;
295353358Sdim    }
296353358Sdim
297314564Sdim    /// Returns true if the checker's analysis was not abandoned and either
298314564Sdim    ///  - \p AnalysisSetT is explicitly preserved or
299314564Sdim    ///  - all analyses are preserved.
300314564Sdim    template <typename AnalysisSetT> bool preservedSet() {
301314564Sdim      AnalysisSetKey *SetID = AnalysisSetT::ID();
302314564Sdim      return !IsAbandoned && (PA.PreservedIDs.count(&AllAnalysesKey) ||
303314564Sdim                              PA.PreservedIDs.count(SetID));
304314564Sdim    }
305314564Sdim  };
306314564Sdim
307314564Sdim  /// Build a checker for this `PreservedAnalyses` and the specified analysis
308314564Sdim  /// type.
309314564Sdim  ///
310314564Sdim  /// You can use the returned object to query whether an analysis was
311314564Sdim  /// preserved. See the example in the comment on `PreservedAnalysis`.
312314564Sdim  template <typename AnalysisT> PreservedAnalysisChecker getChecker() const {
313314564Sdim    return PreservedAnalysisChecker(*this, AnalysisT::ID());
314276479Sdim  }
315276479Sdim
316314564Sdim  /// Build a checker for this `PreservedAnalyses` and the specified analysis
317314564Sdim  /// ID.
318314564Sdim  ///
319314564Sdim  /// You can use the returned object to query whether an analysis was
320314564Sdim  /// preserved. See the example in the comment on `PreservedAnalysis`.
321314564Sdim  PreservedAnalysisChecker getChecker(AnalysisKey *ID) const {
322314564Sdim    return PreservedAnalysisChecker(*this, ID);
323309124Sdim  }
324309124Sdim
325314564Sdim  /// Test whether all analyses are preserved (and none are abandoned).
326280031Sdim  ///
327314564Sdim  /// This is used primarily to optimize for the common case of a transformation
328314564Sdim  /// which makes no changes to the IR.
329280031Sdim  bool areAllPreserved() const {
330314564Sdim    return NotPreservedAnalysisIDs.empty() &&
331314564Sdim           PreservedIDs.count(&AllAnalysesKey);
332280031Sdim  }
333280031Sdim
334314564Sdim  /// Directly test whether a set of analyses is preserved.
335314564Sdim  ///
336314564Sdim  /// This is only true when no analyses have been explicitly abandoned.
337314564Sdim  template <typename AnalysisSetT> bool allAnalysesInSetPreserved() const {
338314564Sdim    return allAnalysesInSetPreserved(AnalysisSetT::ID());
339314564Sdim  }
340314564Sdim
341314564Sdim  /// Directly test whether a set of analyses is preserved.
342314564Sdim  ///
343314564Sdim  /// This is only true when no analyses have been explicitly abandoned.
344314564Sdim  bool allAnalysesInSetPreserved(AnalysisSetKey *SetID) const {
345314564Sdim    return NotPreservedAnalysisIDs.empty() &&
346314564Sdim           (PreservedIDs.count(&AllAnalysesKey) || PreservedIDs.count(SetID));
347314564Sdim  }
348314564Sdim
349276479Sdimprivate:
350314564Sdim  /// A special key used to indicate all analyses.
351314564Sdim  static AnalysisSetKey AllAnalysesKey;
352276479Sdim
353314564Sdim  /// The IDs of analyses and analysis sets that are preserved.
354314564Sdim  SmallPtrSet<void *, 2> PreservedIDs;
355314564Sdim
356314564Sdim  /// The IDs of explicitly not-preserved analyses.
357314564Sdim  ///
358314564Sdim  /// If an analysis in this set is covered by a set in `PreservedIDs`, we
359314564Sdim  /// consider it not-preserved. That is, `NotPreservedAnalysisIDs` always
360314564Sdim  /// "wins" over analysis sets in `PreservedIDs`.
361314564Sdim  ///
362314564Sdim  /// Also, a given ID should never occur both here and in `PreservedIDs`.
363314564Sdim  SmallPtrSet<AnalysisKey *, 2> NotPreservedAnalysisIDs;
364276479Sdim};
365276479Sdim
366280031Sdim// Forward declare the analysis manager template.
367314564Sdimtemplate <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
368259698Sdim
369309124Sdim/// A CRTP mix-in to automatically provide informational APIs needed for
370309124Sdim/// passes.
371309124Sdim///
372314564Sdim/// This provides some boilerplate for types that are passes.
373309124Sdimtemplate <typename DerivedT> struct PassInfoMixin {
374314564Sdim  /// Gets the name of the pass we are mixed into.
375309124Sdim  static StringRef name() {
376314564Sdim    static_assert(std::is_base_of<PassInfoMixin, DerivedT>::value,
377314564Sdim                  "Must pass the derived type as the template argument!");
378309124Sdim    StringRef Name = getTypeName<DerivedT>();
379309124Sdim    if (Name.startswith("llvm::"))
380309124Sdim      Name = Name.drop_front(strlen("llvm::"));
381309124Sdim    return Name;
382309124Sdim  }
383309124Sdim};
384309124Sdim
385314564Sdim/// A CRTP mix-in that provides informational APIs needed for analysis passes.
386309124Sdim///
387314564Sdim/// This provides some boilerplate for types that are analysis passes. It
388314564Sdim/// automatically mixes in \c PassInfoMixin.
389309124Sdimtemplate <typename DerivedT>
390309124Sdimstruct AnalysisInfoMixin : PassInfoMixin<DerivedT> {
391314564Sdim  /// Returns an opaque, unique ID for this analysis type.
392309124Sdim  ///
393314564Sdim  /// This ID is a pointer type that is guaranteed to be 8-byte aligned and thus
394314564Sdim  /// suitable for use in sets, maps, and other data structures that use the low
395314564Sdim  /// bits of pointers.
396309124Sdim  ///
397314564Sdim  /// Note that this requires the derived type provide a static \c AnalysisKey
398314564Sdim  /// member called \c Key.
399314564Sdim  ///
400314564Sdim  /// FIXME: The only reason the mixin type itself can't declare the Key value
401314564Sdim  /// is that some compilers cannot correctly unique a templated static variable
402314564Sdim  /// so it has the same addresses in each instantiation. The only currently
403314564Sdim  /// known platform with this limitation is Windows DLL builds, specifically
404314564Sdim  /// building each part of LLVM as a DLL. If we ever remove that build
405314564Sdim  /// configuration, this mixin can provide the static key as well.
406314564Sdim  static AnalysisKey *ID() {
407314564Sdim    static_assert(std::is_base_of<AnalysisInfoMixin, DerivedT>::value,
408314564Sdim                  "Must pass the derived type as the template argument!");
409314564Sdim    return &DerivedT::Key;
410314564Sdim  }
411309124Sdim};
412309124Sdim
413344779Sdimnamespace detail {
414344779Sdim
415344779Sdim/// Actual unpacker of extra arguments in getAnalysisResult,
416344779Sdim/// passes only those tuple arguments that are mentioned in index_sequence.
417344779Sdimtemplate <typename PassT, typename IRUnitT, typename AnalysisManagerT,
418344779Sdim          typename... ArgTs, size_t... Ns>
419344779Sdimtypename PassT::Result
420344779SdimgetAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR,
421344779Sdim                             std::tuple<ArgTs...> Args,
422360784Sdim                             std::index_sequence<Ns...>) {
423344779Sdim  (void)Args;
424344779Sdim  return AM.template getResult<PassT>(IR, std::get<Ns>(Args)...);
425344779Sdim}
426344779Sdim
427344779Sdim/// Helper for *partial* unpacking of extra arguments in getAnalysisResult.
428344779Sdim///
429344779Sdim/// Arguments passed in tuple come from PassManager, so they might have extra
430344779Sdim/// arguments after those AnalysisManager's ExtraArgTs ones that we need to
431344779Sdim/// pass to getResult.
432344779Sdimtemplate <typename PassT, typename IRUnitT, typename... AnalysisArgTs,
433344779Sdim          typename... MainArgTs>
434344779Sdimtypename PassT::Result
435344779SdimgetAnalysisResult(AnalysisManager<IRUnitT, AnalysisArgTs...> &AM, IRUnitT &IR,
436344779Sdim                  std::tuple<MainArgTs...> Args) {
437344779Sdim  return (getAnalysisResultUnpackTuple<
438344779Sdim          PassT, IRUnitT>)(AM, IR, Args,
439360784Sdim                           std::index_sequence_for<AnalysisArgTs...>{});
440344779Sdim}
441344779Sdim
442344779Sdim} // namespace detail
443344779Sdim
444344779Sdim// Forward declare the pass instrumentation analysis explicitly queried in
445344779Sdim// generic PassManager code.
446344779Sdim// FIXME: figure out a way to move PassInstrumentationAnalysis into its own
447344779Sdim// header.
448344779Sdimclass PassInstrumentationAnalysis;
449344779Sdim
450341825Sdim/// Manages a sequence of passes over a particular unit of IR.
451314564Sdim///
452314564Sdim/// A pass manager contains a sequence of passes to run over a particular unit
453314564Sdim/// of IR (e.g. Functions, Modules). It is itself a valid pass over that unit of
454314564Sdim/// IR, and when run over some given IR will run each of its contained passes in
455314564Sdim/// sequence. Pass managers are the primary and most basic building block of a
456314564Sdim/// pass pipeline.
457314564Sdim///
458314564Sdim/// When you run a pass manager, you provide an \c AnalysisManager<IRUnitT>
459314564Sdim/// argument. The pass manager will propagate that analysis manager to each
460314564Sdim/// pass it runs, and will call the analysis manager's invalidation routine with
461314564Sdim/// the PreservedAnalyses of each pass it runs.
462314564Sdimtemplate <typename IRUnitT,
463314564Sdim          typename AnalysisManagerT = AnalysisManager<IRUnitT>,
464314564Sdim          typename... ExtraArgTs>
465314564Sdimclass PassManager : public PassInfoMixin<
466314564Sdim                        PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...>> {
467314564Sdimpublic:
468341825Sdim  /// Construct a pass manager.
469276479Sdim  ///
470314564Sdim  /// If \p DebugLogging is true, we'll log our progress to llvm::dbgs().
471314564Sdim  explicit PassManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
472314564Sdim
473314564Sdim  // FIXME: These are equivalent to the default move constructor/move
474314564Sdim  // assignment. However, using = default triggers linker errors due to the
475314564Sdim  // explicit instantiations below. Find away to use the default and remove the
476314564Sdim  // duplicated code here.
477280031Sdim  PassManager(PassManager &&Arg)
478280031Sdim      : Passes(std::move(Arg.Passes)),
479280031Sdim        DebugLogging(std::move(Arg.DebugLogging)) {}
480314564Sdim
481280031Sdim  PassManager &operator=(PassManager &&RHS) {
482280031Sdim    Passes = std::move(RHS.Passes);
483280031Sdim    DebugLogging = std::move(RHS.DebugLogging);
484276479Sdim    return *this;
485276479Sdim  }
486276479Sdim
487341825Sdim  /// Run all of the passes in this manager over the given unit of IR.
488314564Sdim  /// ExtraArgs are passed to each pass.
489314564Sdim  PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM,
490314564Sdim                        ExtraArgTs... ExtraArgs) {
491280031Sdim    PreservedAnalyses PA = PreservedAnalyses::all();
492276479Sdim
493344779Sdim    // Request PassInstrumentation from analysis manager, will use it to run
494344779Sdim    // instrumenting callbacks for the passes later.
495344779Sdim    // Here we use std::tuple wrapper over getResult which helps to extract
496344779Sdim    // AnalysisManager's arguments out of the whole ExtraArgs set.
497344779Sdim    PassInstrumentation PI =
498344779Sdim        detail::getAnalysisResult<PassInstrumentationAnalysis>(
499344779Sdim            AM, IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
500344779Sdim
501280031Sdim    if (DebugLogging)
502309124Sdim      dbgs() << "Starting " << getTypeName<IRUnitT>() << " pass manager run.\n";
503276479Sdim
504280031Sdim    for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
505344779Sdim      auto *P = Passes[Idx].get();
506280031Sdim      if (DebugLogging)
507344779Sdim        dbgs() << "Running pass: " << P->name() << " on " << IR.getName()
508344779Sdim               << "\n";
509276479Sdim
510344779Sdim      // Check the PassInstrumentation's BeforePass callbacks before running the
511344779Sdim      // pass, skip its execution completely if asked to (callback returns
512344779Sdim      // false).
513344779Sdim      if (!PI.runBeforePass<IRUnitT>(*P, IR))
514344779Sdim        continue;
515276479Sdim
516344779Sdim      PreservedAnalyses PassPA = P->run(IR, AM, ExtraArgs...);
517344779Sdim
518344779Sdim      // Call onto PassInstrumentation's AfterPass callbacks immediately after
519344779Sdim      // running the pass.
520344779Sdim      PI.runAfterPass<IRUnitT>(*P, IR);
521344779Sdim
522309124Sdim      // Update the analysis manager as each pass runs and potentially
523314564Sdim      // invalidates analyses.
524314564Sdim      AM.invalidate(IR, PassPA);
525276479Sdim
526314564Sdim      // Finally, intersect the preserved analyses to compute the aggregate
527314564Sdim      // preserved set for this pass manager.
528280031Sdim      PA.intersect(std::move(PassPA));
529276479Sdim
530280031Sdim      // FIXME: Historically, the pass managers all called the LLVM context's
531280031Sdim      // yield function here. We don't have a generic way to acquire the
532280031Sdim      // context and it isn't yet clear what the right pattern is for yielding
533280031Sdim      // in the new pass manager so it is currently omitted.
534280031Sdim      //IR.getContext().yield();
535280031Sdim    }
536276479Sdim
537327952Sdim    // Invalidation was handled after each pass in the above loop for the
538314564Sdim    // current unit of IR. Therefore, the remaining analysis results in the
539314564Sdim    // AnalysisManager are preserved. We mark this with a set so that we don't
540314564Sdim    // need to inspect each one individually.
541314564Sdim    PA.preserveSet<AllAnalysesOn<IRUnitT>>();
542314564Sdim
543280031Sdim    if (DebugLogging)
544309124Sdim      dbgs() << "Finished " << getTypeName<IRUnitT>() << " pass manager run.\n";
545276479Sdim
546280031Sdim    return PA;
547276479Sdim  }
548276479Sdim
549280031Sdim  template <typename PassT> void addPass(PassT Pass) {
550321369Sdim    using PassModelT =
551321369Sdim        detail::PassModel<IRUnitT, PassT, PreservedAnalyses, AnalysisManagerT,
552321369Sdim                          ExtraArgTs...>;
553321369Sdim
554280031Sdim    Passes.emplace_back(new PassModelT(std::move(Pass)));
555276479Sdim  }
556276479Sdim
557280031Sdimprivate:
558321369Sdim  using PassConceptT =
559321369Sdim      detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
560276479Sdim
561280031Sdim  std::vector<std::unique_ptr<PassConceptT>> Passes;
562276479Sdim
563341825Sdim  /// Flag indicating whether we should do debug logging.
564280031Sdim  bool DebugLogging;
565276479Sdim};
566276479Sdim
567309124Sdimextern template class PassManager<Module>;
568321369Sdim
569341825Sdim/// Convenience typedef for a pass manager over modules.
570321369Sdimusing ModulePassManager = PassManager<Module>;
571276479Sdim
572309124Sdimextern template class PassManager<Function>;
573321369Sdim
574341825Sdim/// Convenience typedef for a pass manager over functions.
575321369Sdimusing FunctionPassManager = PassManager<Function>;
576276479Sdim
577344779Sdim/// Pseudo-analysis pass that exposes the \c PassInstrumentation to pass
578344779Sdim/// managers. Goes before AnalysisManager definition to provide its
579344779Sdim/// internals (e.g PassInstrumentationAnalysis::ID) for use there if needed.
580344779Sdim/// FIXME: figure out a way to move PassInstrumentationAnalysis into its own
581344779Sdim/// header.
582344779Sdimclass PassInstrumentationAnalysis
583344779Sdim    : public AnalysisInfoMixin<PassInstrumentationAnalysis> {
584344779Sdim  friend AnalysisInfoMixin<PassInstrumentationAnalysis>;
585344779Sdim  static AnalysisKey Key;
586344779Sdim
587344779Sdim  PassInstrumentationCallbacks *Callbacks;
588344779Sdim
589344779Sdimpublic:
590344779Sdim  /// PassInstrumentationCallbacks object is shared, owned by something else,
591344779Sdim  /// not this analysis.
592344779Sdim  PassInstrumentationAnalysis(PassInstrumentationCallbacks *Callbacks = nullptr)
593344779Sdim      : Callbacks(Callbacks) {}
594344779Sdim
595344779Sdim  using Result = PassInstrumentation;
596344779Sdim
597344779Sdim  template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
598344779Sdim  Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
599344779Sdim    return PassInstrumentation(Callbacks);
600344779Sdim  }
601344779Sdim};
602344779Sdim
603341825Sdim/// A container for analyses that lazily runs them and caches their
604314564Sdim/// results.
605314564Sdim///
606314564Sdim/// This class can manage analyses for any IR unit where the address of the IR
607314564Sdim/// unit sufficies as its identity.
608314564Sdimtemplate <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager {
609314564Sdimpublic:
610314564Sdim  class Invalidator;
611259698Sdim
612314564Sdimprivate:
613314564Sdim  // Now that we've defined our invalidator, we can define the concept types.
614321369Sdim  using ResultConceptT =
615321369Sdim      detail::AnalysisResultConcept<IRUnitT, PreservedAnalyses, Invalidator>;
616321369Sdim  using PassConceptT =
617321369Sdim      detail::AnalysisPassConcept<IRUnitT, PreservedAnalyses, Invalidator,
618321369Sdim                                  ExtraArgTs...>;
619314564Sdim
620341825Sdim  /// List of analysis pass IDs and associated concept pointers.
621314564Sdim  ///
622314564Sdim  /// Requires iterators to be valid across appending new entries and arbitrary
623314564Sdim  /// erases. Provides the analysis ID to enable finding iterators to a given
624314564Sdim  /// entry in maps below, and provides the storage for the actual result
625314564Sdim  /// concept.
626321369Sdim  using AnalysisResultListT =
627321369Sdim      std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
628314564Sdim
629341825Sdim  /// Map type from IRUnitT pointer to our custom list type.
630321369Sdim  using AnalysisResultListMapT = DenseMap<IRUnitT *, AnalysisResultListT>;
631314564Sdim
632341825Sdim  /// Map type from a pair of analysis ID and IRUnitT pointer to an
633314564Sdim  /// iterator into a particular result list (which is where the actual analysis
634314564Sdim  /// result is stored).
635321369Sdim  using AnalysisResultMapT =
636321369Sdim      DenseMap<std::pair<AnalysisKey *, IRUnitT *>,
637321369Sdim               typename AnalysisResultListT::iterator>;
638314564Sdim
639314564Sdimpublic:
640314564Sdim  /// API to communicate dependencies between analyses during invalidation.
641314564Sdim  ///
642314564Sdim  /// When an analysis result embeds handles to other analysis results, it
643314564Sdim  /// needs to be invalidated both when its own information isn't preserved and
644314564Sdim  /// when any of its embedded analysis results end up invalidated. We pass an
645314564Sdim  /// \c Invalidator object as an argument to \c invalidate() in order to let
646314564Sdim  /// the analysis results themselves define the dependency graph on the fly.
647314564Sdim  /// This lets us avoid building building an explicit representation of the
648314564Sdim  /// dependencies between analysis results.
649314564Sdim  class Invalidator {
650314564Sdim  public:
651314564Sdim    /// Trigger the invalidation of some other analysis pass if not already
652314564Sdim    /// handled and return whether it was in fact invalidated.
653314564Sdim    ///
654314564Sdim    /// This is expected to be called from within a given analysis result's \c
655314564Sdim    /// invalidate method to trigger a depth-first walk of all inter-analysis
656314564Sdim    /// dependencies. The same \p IR unit and \p PA passed to that result's \c
657314564Sdim    /// invalidate method should in turn be provided to this routine.
658314564Sdim    ///
659314564Sdim    /// The first time this is called for a given analysis pass, it will call
660314564Sdim    /// the corresponding result's \c invalidate method.  Subsequent calls will
661314564Sdim    /// use a cache of the results of that initial call.  It is an error to form
662314564Sdim    /// cyclic dependencies between analysis results.
663314564Sdim    ///
664314564Sdim    /// This returns true if the given analysis's result is invalid. Any
665314564Sdim    /// dependecies on it will become invalid as a result.
666314564Sdim    template <typename PassT>
667314564Sdim    bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
668321369Sdim      using ResultModelT =
669321369Sdim          detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
670321369Sdim                                      PreservedAnalyses, Invalidator>;
671321369Sdim
672314564Sdim      return invalidateImpl<ResultModelT>(PassT::ID(), IR, PA);
673314564Sdim    }
674314564Sdim
675314564Sdim    /// A type-erased variant of the above invalidate method with the same core
676314564Sdim    /// API other than passing an analysis ID rather than an analysis type
677314564Sdim    /// parameter.
678314564Sdim    ///
679314564Sdim    /// This is sadly less efficient than the above routine, which leverages
680314564Sdim    /// the type parameter to avoid the type erasure overhead.
681314564Sdim    bool invalidate(AnalysisKey *ID, IRUnitT &IR, const PreservedAnalyses &PA) {
682314564Sdim      return invalidateImpl<>(ID, IR, PA);
683314564Sdim    }
684314564Sdim
685314564Sdim  private:
686314564Sdim    friend class AnalysisManager;
687314564Sdim
688314564Sdim    template <typename ResultT = ResultConceptT>
689314564Sdim    bool invalidateImpl(AnalysisKey *ID, IRUnitT &IR,
690314564Sdim                        const PreservedAnalyses &PA) {
691314564Sdim      // If we've already visited this pass, return true if it was invalidated
692314564Sdim      // and false otherwise.
693314564Sdim      auto IMapI = IsResultInvalidated.find(ID);
694314564Sdim      if (IMapI != IsResultInvalidated.end())
695314564Sdim        return IMapI->second;
696314564Sdim
697314564Sdim      // Otherwise look up the result object.
698314564Sdim      auto RI = Results.find({ID, &IR});
699314564Sdim      assert(RI != Results.end() &&
700314564Sdim             "Trying to invalidate a dependent result that isn't in the "
701314564Sdim             "manager's cache is always an error, likely due to a stale result "
702314564Sdim             "handle!");
703314564Sdim
704314564Sdim      auto &Result = static_cast<ResultT &>(*RI->second->second);
705314564Sdim
706314564Sdim      // Insert into the map whether the result should be invalidated and return
707314564Sdim      // that. Note that we cannot reuse IMapI and must do a fresh insert here,
708314564Sdim      // as calling invalidate could (recursively) insert things into the map,
709314564Sdim      // making any iterator or reference invalid.
710314564Sdim      bool Inserted;
711314564Sdim      std::tie(IMapI, Inserted) =
712314564Sdim          IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, *this)});
713314564Sdim      (void)Inserted;
714314564Sdim      assert(Inserted && "Should not have already inserted this ID, likely "
715314564Sdim                         "indicates a dependency cycle!");
716314564Sdim      return IMapI->second;
717314564Sdim    }
718314564Sdim
719314564Sdim    Invalidator(SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated,
720314564Sdim                const AnalysisResultMapT &Results)
721314564Sdim        : IsResultInvalidated(IsResultInvalidated), Results(Results) {}
722314564Sdim
723314564Sdim    SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated;
724314564Sdim    const AnalysisResultMapT &Results;
725314564Sdim  };
726314564Sdim
727341825Sdim  /// Construct an empty analysis manager.
728314564Sdim  ///
729314564Sdim  /// If \p DebugLogging is true, we'll log our progress to llvm::dbgs().
730314564Sdim  AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
731314564Sdim  AnalysisManager(AnalysisManager &&) = default;
732314564Sdim  AnalysisManager &operator=(AnalysisManager &&) = default;
733314564Sdim
734341825Sdim  /// Returns true if the analysis manager has an empty results cache.
735314564Sdim  bool empty() const {
736314564Sdim    assert(AnalysisResults.empty() == AnalysisResultLists.empty() &&
737314564Sdim           "The storage and index of analysis results disagree on how many "
738314564Sdim           "there are!");
739314564Sdim    return AnalysisResults.empty();
740276479Sdim  }
741276479Sdim
742341825Sdim  /// Clear any cached analysis results for a single unit of IR.
743314564Sdim  ///
744314564Sdim  /// This doesn't invalidate, but instead simply deletes, the relevant results.
745314564Sdim  /// It is useful when the IR is being removed and we want to clear out all the
746314564Sdim  /// memory pinned for it.
747327952Sdim  void clear(IRUnitT &IR, llvm::StringRef Name) {
748314564Sdim    if (DebugLogging)
749327952Sdim      dbgs() << "Clearing all analysis results for: " << Name << "\n";
750276479Sdim
751314564Sdim    auto ResultsListI = AnalysisResultLists.find(&IR);
752314564Sdim    if (ResultsListI == AnalysisResultLists.end())
753314564Sdim      return;
754314564Sdim    // Delete the map entries that point into the results list.
755314564Sdim    for (auto &IDAndResult : ResultsListI->second)
756314564Sdim      AnalysisResults.erase({IDAndResult.first, &IR});
757276479Sdim
758314564Sdim    // And actually destroy and erase the results associated with this IR.
759314564Sdim    AnalysisResultLists.erase(ResultsListI);
760314564Sdim  }
761276479Sdim
762341825Sdim  /// Clear all analysis results cached by this AnalysisManager.
763314564Sdim  ///
764314564Sdim  /// Like \c clear(IRUnitT&), this doesn't invalidate the results; it simply
765314564Sdim  /// deletes them.  This lets you clean up the AnalysisManager when the set of
766314564Sdim  /// IR units itself has potentially changed, and thus we can't even look up a
767314564Sdim  /// a result and invalidate/clear it directly.
768314564Sdim  void clear() {
769314564Sdim    AnalysisResults.clear();
770314564Sdim    AnalysisResultLists.clear();
771276479Sdim  }
772276479Sdim
773341825Sdim  /// Get the result of an analysis pass for a given IR unit.
774259698Sdim  ///
775314564Sdim  /// Runs the analysis if a cached result is not available.
776314564Sdim  template <typename PassT>
777314564Sdim  typename PassT::Result &getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs) {
778276479Sdim    assert(AnalysisPasses.count(PassT::ID()) &&
779259698Sdim           "This analysis pass was not registered prior to being queried");
780276479Sdim    ResultConceptT &ResultConcept =
781314564Sdim        getResultImpl(PassT::ID(), IR, ExtraArgs...);
782321369Sdim
783321369Sdim    using ResultModelT =
784321369Sdim        detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
785321369Sdim                                    PreservedAnalyses, Invalidator>;
786321369Sdim
787276479Sdim    return static_cast<ResultModelT &>(ResultConcept).Result;
788259698Sdim  }
789259698Sdim
790341825Sdim  /// Get the cached result of an analysis pass for a given IR unit.
791259698Sdim  ///
792276479Sdim  /// This method never runs the analysis.
793276479Sdim  ///
794276479Sdim  /// \returns null if there is no cached result.
795259698Sdim  template <typename PassT>
796280031Sdim  typename PassT::Result *getCachedResult(IRUnitT &IR) const {
797276479Sdim    assert(AnalysisPasses.count(PassT::ID()) &&
798259698Sdim           "This analysis pass was not registered prior to being queried");
799259698Sdim
800314564Sdim    ResultConceptT *ResultConcept = getCachedResultImpl(PassT::ID(), IR);
801276479Sdim    if (!ResultConcept)
802276479Sdim      return nullptr;
803276479Sdim
804321369Sdim    using ResultModelT =
805321369Sdim        detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
806321369Sdim                                    PreservedAnalyses, Invalidator>;
807321369Sdim
808276479Sdim    return &static_cast<ResultModelT *>(ResultConcept)->Result;
809259698Sdim  }
810259698Sdim
811341825Sdim  /// Register an analysis pass with the manager.
812259698Sdim  ///
813314564Sdim  /// The parameter is a callable whose result is an analysis pass. This allows
814314564Sdim  /// passing in a lambda to construct the analysis.
815309124Sdim  ///
816314564Sdim  /// The analysis type to register is the type returned by calling the \c
817314564Sdim  /// PassBuilder argument. If that type has already been registered, then the
818314564Sdim  /// argument will not be called and this function will return false.
819314564Sdim  /// Otherwise, we register the analysis returned by calling \c PassBuilder(),
820314564Sdim  /// and this function returns true.
821309124Sdim  ///
822314564Sdim  /// (Note: Although the return value of this function indicates whether or not
823314564Sdim  /// an analysis was previously registered, there intentionally isn't a way to
824314564Sdim  /// query this directly.  Instead, you should just register all the analyses
825314564Sdim  /// you might want and let this class run them lazily.  This idiom lets us
826314564Sdim  /// minimize the number of times we have to look up analyses in our
827314564Sdim  /// hashtable.)
828314564Sdim  template <typename PassBuilderT>
829314564Sdim  bool registerPass(PassBuilderT &&PassBuilder) {
830321369Sdim    using PassT = decltype(PassBuilder());
831321369Sdim    using PassModelT =
832321369Sdim        detail::AnalysisPassModel<IRUnitT, PassT, PreservedAnalyses,
833321369Sdim                                  Invalidator, ExtraArgTs...>;
834309124Sdim
835309124Sdim    auto &PassPtr = AnalysisPasses[PassT::ID()];
836309124Sdim    if (PassPtr)
837309124Sdim      // Already registered this pass type!
838309124Sdim      return false;
839309124Sdim
840309124Sdim    // Construct a new model around the instance returned by the builder.
841309124Sdim    PassPtr.reset(new PassModelT(PassBuilder()));
842309124Sdim    return true;
843259698Sdim  }
844259698Sdim
845341825Sdim  /// Invalidate a specific analysis pass for an IR module.
846259698Sdim  ///
847314564Sdim  /// Note that the analysis result can disregard invalidation, if it determines
848314564Sdim  /// it is in fact still valid.
849280031Sdim  template <typename PassT> void invalidate(IRUnitT &IR) {
850276479Sdim    assert(AnalysisPasses.count(PassT::ID()) &&
851276479Sdim           "This analysis pass was not registered prior to being invalidated");
852314564Sdim    invalidateImpl(PassT::ID(), IR);
853259698Sdim  }
854259698Sdim
855341825Sdim  /// Invalidate cached analyses for an IR unit.
856259698Sdim  ///
857276479Sdim  /// Walk through all of the analyses pertaining to this unit of IR and
858314564Sdim  /// invalidate them, unless they are preserved by the PreservedAnalyses set.
859314564Sdim  void invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
860314564Sdim    // We're done if all analyses on this IR unit are preserved.
861314564Sdim    if (PA.allAnalysesInSetPreserved<AllAnalysesOn<IRUnitT>>())
862314564Sdim      return;
863259698Sdim
864314564Sdim    if (DebugLogging)
865314564Sdim      dbgs() << "Invalidating all non-preserved analyses for: " << IR.getName()
866314564Sdim             << "\n";
867259698Sdim
868314564Sdim    // Track whether each analysis's result is invalidated in
869314564Sdim    // IsResultInvalidated.
870314564Sdim    SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
871314564Sdim    Invalidator Inv(IsResultInvalidated, AnalysisResults);
872314564Sdim    AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
873314564Sdim    for (auto &AnalysisResultPair : ResultsList) {
874314564Sdim      // This is basically the same thing as Invalidator::invalidate, but we
875314564Sdim      // can't call it here because we're operating on the type-erased result.
876314564Sdim      // Moreover if we instead called invalidate() directly, it would do an
877314564Sdim      // unnecessary look up in ResultsList.
878314564Sdim      AnalysisKey *ID = AnalysisResultPair.first;
879314564Sdim      auto &Result = *AnalysisResultPair.second;
880259698Sdim
881314564Sdim      auto IMapI = IsResultInvalidated.find(ID);
882314564Sdim      if (IMapI != IsResultInvalidated.end())
883314564Sdim        // This result was already handled via the Invalidator.
884314564Sdim        continue;
885259698Sdim
886314564Sdim      // Try to invalidate the result, giving it the Invalidator so it can
887314564Sdim      // recursively query for any dependencies it has and record the result.
888314564Sdim      // Note that we cannot reuse 'IMapI' here or pre-insert the ID, as
889314564Sdim      // Result.invalidate may insert things into the map, invalidating our
890314564Sdim      // iterator.
891314564Sdim      bool Inserted =
892314564Sdim          IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)})
893314564Sdim              .second;
894314564Sdim      (void)Inserted;
895314564Sdim      assert(Inserted && "Should never have already inserted this ID, likely "
896314564Sdim                         "indicates a cycle!");
897314564Sdim    }
898259698Sdim
899314564Sdim    // Now erase the results that were marked above as invalidated.
900314564Sdim    if (!IsResultInvalidated.empty()) {
901314564Sdim      for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
902314564Sdim        AnalysisKey *ID = I->first;
903314564Sdim        if (!IsResultInvalidated.lookup(ID)) {
904314564Sdim          ++I;
905314564Sdim          continue;
906314564Sdim        }
907259698Sdim
908314564Sdim        if (DebugLogging)
909314564Sdim          dbgs() << "Invalidating analysis: " << this->lookUpPass(ID).name()
910321369Sdim                 << " on " << IR.getName() << "\n";
911259698Sdim
912314564Sdim        I = ResultsList.erase(I);
913314564Sdim        AnalysisResults.erase({ID, &IR});
914314564Sdim      }
915314564Sdim    }
916280031Sdim
917314564Sdim    if (ResultsList.empty())
918314564Sdim      AnalysisResultLists.erase(&IR);
919276479Sdim  }
920259698Sdim
921314564Sdimprivate:
922341825Sdim  /// Look up a registered analysis pass.
923314564Sdim  PassConceptT &lookUpPass(AnalysisKey *ID) {
924314564Sdim    typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(ID);
925314564Sdim    assert(PI != AnalysisPasses.end() &&
926314564Sdim           "Analysis passes must be registered prior to being queried!");
927314564Sdim    return *PI->second;
928280031Sdim  }
929259698Sdim
930341825Sdim  /// Look up a registered analysis pass.
931314564Sdim  const PassConceptT &lookUpPass(AnalysisKey *ID) const {
932314564Sdim    typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(ID);
933314564Sdim    assert(PI != AnalysisPasses.end() &&
934314564Sdim           "Analysis passes must be registered prior to being queried!");
935314564Sdim    return *PI->second;
936280031Sdim  }
937259698Sdim
938341825Sdim  /// Get an analysis result, running the pass if necessary.
939314564Sdim  ResultConceptT &getResultImpl(AnalysisKey *ID, IRUnitT &IR,
940314564Sdim                                ExtraArgTs... ExtraArgs) {
941280031Sdim    typename AnalysisResultMapT::iterator RI;
942280031Sdim    bool Inserted;
943280031Sdim    std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
944314564Sdim        std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
945259698Sdim
946280031Sdim    // If we don't have a cached result for this function, look up the pass and
947280031Sdim    // run it to produce a result, which we then add to the cache.
948280031Sdim    if (Inserted) {
949314564Sdim      auto &P = this->lookUpPass(ID);
950280031Sdim      if (DebugLogging)
951321369Sdim        dbgs() << "Running analysis: " << P.name() << " on " << IR.getName()
952321369Sdim               << "\n";
953344779Sdim
954344779Sdim      PassInstrumentation PI;
955344779Sdim      if (ID != PassInstrumentationAnalysis::ID()) {
956344779Sdim        PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
957344779Sdim        PI.runBeforeAnalysis(P, IR);
958344779Sdim      }
959344779Sdim
960280031Sdim      AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
961314564Sdim      ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
962288943Sdim
963344779Sdim      PI.runAfterAnalysis(P, IR);
964344779Sdim
965288943Sdim      // P.run may have inserted elements into AnalysisResults and invalidated
966288943Sdim      // RI.
967314564Sdim      RI = AnalysisResults.find({ID, &IR});
968288943Sdim      assert(RI != AnalysisResults.end() && "we just inserted it!");
969288943Sdim
970280031Sdim      RI->second = std::prev(ResultList.end());
971280031Sdim    }
972259698Sdim
973280031Sdim    return *RI->second->second;
974280031Sdim  }
975259698Sdim
976341825Sdim  /// Get a cached analysis result or return null.
977314564Sdim  ResultConceptT *getCachedResultImpl(AnalysisKey *ID, IRUnitT &IR) const {
978280031Sdim    typename AnalysisResultMapT::const_iterator RI =
979314564Sdim        AnalysisResults.find({ID, &IR});
980280031Sdim    return RI == AnalysisResults.end() ? nullptr : &*RI->second->second;
981280031Sdim  }
982259698Sdim
983341825Sdim  /// Invalidate a function pass result.
984314564Sdim  void invalidateImpl(AnalysisKey *ID, IRUnitT &IR) {
985280031Sdim    typename AnalysisResultMapT::iterator RI =
986314564Sdim        AnalysisResults.find({ID, &IR});
987280031Sdim    if (RI == AnalysisResults.end())
988280031Sdim      return;
989276479Sdim
990280031Sdim    if (DebugLogging)
991314564Sdim      dbgs() << "Invalidating analysis: " << this->lookUpPass(ID).name()
992321369Sdim             << " on " << IR.getName() << "\n";
993280031Sdim    AnalysisResultLists[&IR].erase(RI->second);
994280031Sdim    AnalysisResults.erase(RI);
995259698Sdim  }
996259698Sdim
997341825Sdim  /// Map type from module analysis pass ID to pass concept pointer.
998321369Sdim  using AnalysisPassMapT =
999321369Sdim      DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
1000259698Sdim
1001341825Sdim  /// Collection of module analysis passes, indexed by ID.
1002314564Sdim  AnalysisPassMapT AnalysisPasses;
1003259698Sdim
1004341825Sdim  /// Map from function to a list of function analysis results.
1005259698Sdim  ///
1006259698Sdim  /// Provides linear time removal of all analysis results for a function and
1007259698Sdim  /// the ultimate storage for a particular cached analysis result.
1008280031Sdim  AnalysisResultListMapT AnalysisResultLists;
1009259698Sdim
1010341825Sdim  /// Map from an analysis ID and function to a particular cached
1011259698Sdim  /// analysis result.
1012280031Sdim  AnalysisResultMapT AnalysisResults;
1013280031Sdim
1014341825Sdim  /// Indicates whether we log to \c llvm::dbgs().
1015280031Sdim  bool DebugLogging;
1016276479Sdim};
1017259698Sdim
1018309124Sdimextern template class AnalysisManager<Module>;
1019321369Sdim
1020341825Sdim/// Convenience typedef for the Module analysis manager.
1021321369Sdimusing ModuleAnalysisManager = AnalysisManager<Module>;
1022280031Sdim
1023309124Sdimextern template class AnalysisManager<Function>;
1024321369Sdim
1025341825Sdim/// Convenience typedef for the Function analysis manager.
1026321369Sdimusing FunctionAnalysisManager = AnalysisManager<Function>;
1027280031Sdim
1028341825Sdim/// An analysis over an "outer" IR unit that provides access to an
1029314564Sdim/// analysis manager over an "inner" IR unit.  The inner unit must be contained
1030314564Sdim/// in the outer unit.
1031276479Sdim///
1032344779Sdim/// For example, InnerAnalysisManagerProxy<FunctionAnalysisManager, Module> is
1033314564Sdim/// an analysis over Modules (the "outer" unit) that provides access to a
1034314564Sdim/// Function analysis manager.  The FunctionAnalysisManager is the "inner"
1035314564Sdim/// manager being proxied, and Functions are the "inner" unit.  The inner/outer
1036314564Sdim/// relationship is valid because each Function is contained in one Module.
1037309124Sdim///
1038314564Sdim/// If you're (transitively) within a pass manager for an IR unit U that
1039314564Sdim/// contains IR unit V, you should never use an analysis manager over V, except
1040314564Sdim/// via one of these proxies.
1041314564Sdim///
1042314564Sdim/// Note that the proxy's result is a move-only RAII object.  The validity of
1043314564Sdim/// the analyses in the inner analysis manager is tied to its lifetime.
1044314564Sdimtemplate <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
1045309124Sdimclass InnerAnalysisManagerProxy
1046309124Sdim    : public AnalysisInfoMixin<
1047309124Sdim          InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
1048276479Sdimpublic:
1049309124Sdim  class Result {
1050309124Sdim  public:
1051314564Sdim    explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
1052321369Sdim
1053314564Sdim    Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)) {
1054309124Sdim      // We have to null out the analysis manager in the moved-from state
1055309124Sdim      // because we are taking ownership of the responsibilty to clear the
1056309124Sdim      // analysis state.
1057314564Sdim      Arg.InnerAM = nullptr;
1058309124Sdim    }
1059321369Sdim
1060309124Sdim    ~Result() {
1061314564Sdim      // InnerAM is cleared in a moved from state where there is nothing to do.
1062314564Sdim      if (!InnerAM)
1063309124Sdim        return;
1064276479Sdim
1065309124Sdim      // Clear out the analysis manager if we're being destroyed -- it means we
1066309124Sdim      // didn't even see an invalidate call when we got invalidated.
1067314564Sdim      InnerAM->clear();
1068309124Sdim    }
1069276479Sdim
1070321369Sdim    Result &operator=(Result &&RHS) {
1071321369Sdim      InnerAM = RHS.InnerAM;
1072321369Sdim      // We have to null out the analysis manager in the moved-from state
1073321369Sdim      // because we are taking ownership of the responsibilty to clear the
1074321369Sdim      // analysis state.
1075321369Sdim      RHS.InnerAM = nullptr;
1076321369Sdim      return *this;
1077321369Sdim    }
1078321369Sdim
1079341825Sdim    /// Accessor for the analysis manager.
1080314564Sdim    AnalysisManagerT &getManager() { return *InnerAM; }
1081280031Sdim
1082341825Sdim    /// Handler for invalidation of the outer IR unit, \c IRUnitT.
1083309124Sdim    ///
1084314564Sdim    /// If the proxy analysis itself is not preserved, we assume that the set of
1085314564Sdim    /// inner IR objects contained in IRUnit may have changed.  In this case,
1086314564Sdim    /// we have to call \c clear() on the inner analysis manager, as it may now
1087314564Sdim    /// have stale pointers to its inner IR objects.
1088309124Sdim    ///
1089314564Sdim    /// Regardless of whether the proxy analysis is marked as preserved, all of
1090314564Sdim    /// the analyses in the inner analysis manager are potentially invalidated
1091309124Sdim    /// based on the set of preserved analyses.
1092314564Sdim    bool invalidate(
1093314564Sdim        IRUnitT &IR, const PreservedAnalyses &PA,
1094314564Sdim        typename AnalysisManager<IRUnitT, ExtraArgTs...>::Invalidator &Inv);
1095309124Sdim
1096309124Sdim  private:
1097314564Sdim    AnalysisManagerT *InnerAM;
1098309124Sdim  };
1099309124Sdim
1100314564Sdim  explicit InnerAnalysisManagerProxy(AnalysisManagerT &InnerAM)
1101314564Sdim      : InnerAM(&InnerAM) {}
1102276479Sdim
1103341825Sdim  /// Run the analysis pass and create our proxy result object.
1104276479Sdim  ///
1105314564Sdim  /// This doesn't do any interesting work; it is primarily used to insert our
1106314564Sdim  /// proxy result object into the outer analysis cache so that we can proxy
1107314564Sdim  /// invalidation to the inner analysis manager.
1108314564Sdim  Result run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM,
1109314564Sdim             ExtraArgTs...) {
1110314564Sdim    return Result(*InnerAM);
1111314564Sdim  }
1112276479Sdim
1113276479Sdimprivate:
1114309124Sdim  friend AnalysisInfoMixin<
1115309124Sdim      InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
1116321369Sdim
1117314564Sdim  static AnalysisKey Key;
1118276479Sdim
1119314564Sdim  AnalysisManagerT *InnerAM;
1120259698Sdim};
1121259698Sdim
1122314564Sdimtemplate <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
1123314564SdimAnalysisKey
1124314564Sdim    InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
1125276479Sdim
1126309124Sdim/// Provide the \c FunctionAnalysisManager to \c Module proxy.
1127321369Sdimusing FunctionAnalysisManagerModuleProxy =
1128321369Sdim    InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
1129276479Sdim
1130314564Sdim/// Specialization of the invalidate method for the \c
1131314564Sdim/// FunctionAnalysisManagerModuleProxy's result.
1132314564Sdimtemplate <>
1133314564Sdimbool FunctionAnalysisManagerModuleProxy::Result::invalidate(
1134314564Sdim    Module &M, const PreservedAnalyses &PA,
1135314564Sdim    ModuleAnalysisManager::Invalidator &Inv);
1136314564Sdim
1137314564Sdim// Ensure the \c FunctionAnalysisManagerModuleProxy is provided as an extern
1138314564Sdim// template.
1139314564Sdimextern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
1140314564Sdim                                                Module>;
1141314564Sdim
1142341825Sdim/// An analysis over an "inner" IR unit that provides access to an
1143314564Sdim/// analysis manager over a "outer" IR unit.  The inner unit must be contained
1144314564Sdim/// in the outer unit.
1145276479Sdim///
1146314564Sdim/// For example OuterAnalysisManagerProxy<ModuleAnalysisManager, Function> is an
1147314564Sdim/// analysis over Functions (the "inner" unit) which provides access to a Module
1148314564Sdim/// analysis manager.  The ModuleAnalysisManager is the "outer" manager being
1149314564Sdim/// proxied, and Modules are the "outer" IR unit.  The inner/outer relationship
1150314564Sdim/// is valid because each Function is contained in one Module.
1151276479Sdim///
1152314564Sdim/// This proxy only exposes the const interface of the outer analysis manager,
1153314564Sdim/// to indicate that you cannot cause an outer analysis to run from within an
1154314564Sdim/// inner pass.  Instead, you must rely on the \c getCachedResult API.
1155314564Sdim///
1156314564Sdim/// This proxy doesn't manage invalidation in any way -- that is handled by the
1157314564Sdim/// recursive return path of each layer of the pass manager.  A consequence of
1158314564Sdim/// this is the outer analyses may be stale.  We invalidate the outer analyses
1159314564Sdim/// only when we're done running passes over the inner IR units.
1160314564Sdimtemplate <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
1161309124Sdimclass OuterAnalysisManagerProxy
1162309124Sdim    : public AnalysisInfoMixin<
1163314564Sdim          OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>> {
1164276479Sdimpublic:
1165341825Sdim  /// Result proxy object for \c OuterAnalysisManagerProxy.
1166276479Sdim  class Result {
1167276479Sdim  public:
1168360784Sdim    explicit Result(const AnalysisManagerT &OuterAM) : OuterAM(&OuterAM) {}
1169276479Sdim
1170360784Sdim    const AnalysisManagerT &getManager() const { return *OuterAM; }
1171276479Sdim
1172321369Sdim    /// When invalidation occurs, remove any registered invalidation events.
1173314564Sdim    bool invalidate(
1174321369Sdim        IRUnitT &IRUnit, const PreservedAnalyses &PA,
1175321369Sdim        typename AnalysisManager<IRUnitT, ExtraArgTs...>::Invalidator &Inv) {
1176321369Sdim      // Loop over the set of registered outer invalidation mappings and if any
1177321369Sdim      // of them map to an analysis that is now invalid, clear it out.
1178321369Sdim      SmallVector<AnalysisKey *, 4> DeadKeys;
1179321369Sdim      for (auto &KeyValuePair : OuterAnalysisInvalidationMap) {
1180321369Sdim        AnalysisKey *OuterID = KeyValuePair.first;
1181321369Sdim        auto &InnerIDs = KeyValuePair.second;
1182321369Sdim        InnerIDs.erase(llvm::remove_if(InnerIDs, [&](AnalysisKey *InnerID) {
1183321369Sdim          return Inv.invalidate(InnerID, IRUnit, PA); }),
1184321369Sdim                       InnerIDs.end());
1185321369Sdim        if (InnerIDs.empty())
1186321369Sdim          DeadKeys.push_back(OuterID);
1187321369Sdim      }
1188321369Sdim
1189321369Sdim      for (auto OuterID : DeadKeys)
1190321369Sdim        OuterAnalysisInvalidationMap.erase(OuterID);
1191321369Sdim
1192321369Sdim      // The proxy itself remains valid regardless of anything else.
1193314564Sdim      return false;
1194314564Sdim    }
1195276479Sdim
1196314564Sdim    /// Register a deferred invalidation event for when the outer analysis
1197314564Sdim    /// manager processes its invalidations.
1198314564Sdim    template <typename OuterAnalysisT, typename InvalidatedAnalysisT>
1199314564Sdim    void registerOuterAnalysisInvalidation() {
1200314564Sdim      AnalysisKey *OuterID = OuterAnalysisT::ID();
1201314564Sdim      AnalysisKey *InvalidatedID = InvalidatedAnalysisT::ID();
1202314564Sdim
1203314564Sdim      auto &InvalidatedIDList = OuterAnalysisInvalidationMap[OuterID];
1204314564Sdim      // Note, this is a linear scan. If we end up with large numbers of
1205314564Sdim      // analyses that all trigger invalidation on the same outer analysis,
1206314564Sdim      // this entire system should be changed to some other deterministic
1207314564Sdim      // data structure such as a `SetVector` of a pair of pointers.
1208314564Sdim      auto InvalidatedIt = std::find(InvalidatedIDList.begin(),
1209314564Sdim                                     InvalidatedIDList.end(), InvalidatedID);
1210314564Sdim      if (InvalidatedIt == InvalidatedIDList.end())
1211314564Sdim        InvalidatedIDList.push_back(InvalidatedID);
1212314564Sdim    }
1213314564Sdim
1214314564Sdim    /// Access the map from outer analyses to deferred invalidation requiring
1215314564Sdim    /// analyses.
1216314564Sdim    const SmallDenseMap<AnalysisKey *, TinyPtrVector<AnalysisKey *>, 2> &
1217314564Sdim    getOuterInvalidations() const {
1218314564Sdim      return OuterAnalysisInvalidationMap;
1219314564Sdim    }
1220314564Sdim
1221276479Sdim  private:
1222360784Sdim    const AnalysisManagerT *OuterAM;
1223314564Sdim
1224314564Sdim    /// A map from an outer analysis ID to the set of this IR-unit's analyses
1225314564Sdim    /// which need to be invalidated.
1226314564Sdim    SmallDenseMap<AnalysisKey *, TinyPtrVector<AnalysisKey *>, 2>
1227314564Sdim        OuterAnalysisInvalidationMap;
1228276479Sdim  };
1229276479Sdim
1230360784Sdim  OuterAnalysisManagerProxy(const AnalysisManagerT &OuterAM)
1231360784Sdim      : OuterAM(&OuterAM) {}
1232276479Sdim
1233341825Sdim  /// Run the analysis pass and create our proxy result object.
1234360784Sdim  /// Nothing to see here, it just forwards the \c OuterAM reference into the
1235276479Sdim  /// result.
1236314564Sdim  Result run(IRUnitT &, AnalysisManager<IRUnitT, ExtraArgTs...> &,
1237314564Sdim             ExtraArgTs...) {
1238360784Sdim    return Result(*OuterAM);
1239314564Sdim  }
1240276479Sdim
1241276479Sdimprivate:
1242309124Sdim  friend AnalysisInfoMixin<
1243314564Sdim      OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>>;
1244321369Sdim
1245314564Sdim  static AnalysisKey Key;
1246276479Sdim
1247360784Sdim  const AnalysisManagerT *OuterAM;
1248276479Sdim};
1249276479Sdim
1250314564Sdimtemplate <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
1251314564SdimAnalysisKey
1252314564Sdim    OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
1253309124Sdim
1254309124Sdimextern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
1255309124Sdim                                                Function>;
1256314564Sdim/// Provide the \c ModuleAnalysisManager to \c Function proxy.
1257321369Sdimusing ModuleAnalysisManagerFunctionProxy =
1258321369Sdim    OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
1259309124Sdim
1260341825Sdim/// Trivial adaptor that maps from a module to its functions.
1261276479Sdim///
1262276479Sdim/// Designed to allow composition of a FunctionPass(Manager) and
1263314564Sdim/// a ModulePassManager, by running the FunctionPass(Manager) over every
1264314564Sdim/// function in the module.
1265280031Sdim///
1266280031Sdim/// Function passes run within this adaptor can rely on having exclusive access
1267280031Sdim/// to the function they are run over. They should not read or modify any other
1268280031Sdim/// functions! Other threads or systems may be manipulating other functions in
1269280031Sdim/// the module, and so their state should never be relied on.
1270280031Sdim/// FIXME: Make the above true for all of LLVM's actual passes, some still
1271280031Sdim/// violate this principle.
1272280031Sdim///
1273280031Sdim/// Function passes can also read the module containing the function, but they
1274280031Sdim/// should not modify that module outside of the use lists of various globals.
1275280031Sdim/// For example, a function pass is not permitted to add functions to the
1276280031Sdim/// module.
1277280031Sdim/// FIXME: Make the above true for all of LLVM's actual passes, some still
1278280031Sdim/// violate this principle.
1279314564Sdim///
1280314564Sdim/// Note that although function passes can access module analyses, module
1281314564Sdim/// analyses are not invalidated while the function passes are running, so they
1282314564Sdim/// may be stale.  Function analyses will not be stale.
1283309124Sdimtemplate <typename FunctionPassT>
1284309124Sdimclass ModuleToFunctionPassAdaptor
1285309124Sdim    : public PassInfoMixin<ModuleToFunctionPassAdaptor<FunctionPassT>> {
1286276479Sdimpublic:
1287276479Sdim  explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
1288276479Sdim      : Pass(std::move(Pass)) {}
1289276479Sdim
1290341825Sdim  /// Runs the function pass across every function in the module.
1291309124Sdim  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
1292309124Sdim    FunctionAnalysisManager &FAM =
1293309124Sdim        AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
1294276479Sdim
1295344779Sdim    // Request PassInstrumentation from analysis manager, will use it to run
1296344779Sdim    // instrumenting callbacks for the passes later.
1297344779Sdim    PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
1298344779Sdim
1299276479Sdim    PreservedAnalyses PA = PreservedAnalyses::all();
1300288943Sdim    for (Function &F : M) {
1301288943Sdim      if (F.isDeclaration())
1302288943Sdim        continue;
1303276479Sdim
1304344779Sdim      // Check the PassInstrumentation's BeforePass callbacks before running the
1305344779Sdim      // pass, skip its execution completely if asked to (callback returns
1306344779Sdim      // false).
1307344779Sdim      if (!PI.runBeforePass<Function>(Pass, F))
1308344779Sdim        continue;
1309288943Sdim      PreservedAnalyses PassPA = Pass.run(F, FAM);
1310288943Sdim
1311344779Sdim      PI.runAfterPass(Pass, F);
1312344779Sdim
1313276479Sdim      // We know that the function pass couldn't have invalidated any other
1314276479Sdim      // function's analyses (that's the contract of a function pass), so
1315314564Sdim      // directly handle the function analysis manager's invalidation here.
1316314564Sdim      FAM.invalidate(F, PassPA);
1317276479Sdim
1318276479Sdim      // Then intersect the preserved set so that invalidation of module
1319276479Sdim      // analyses will eventually occur when the module pass completes.
1320276479Sdim      PA.intersect(std::move(PassPA));
1321276479Sdim    }
1322276479Sdim
1323314564Sdim    // The FunctionAnalysisManagerModuleProxy is preserved because (we assume)
1324314564Sdim    // the function passes we ran didn't add or remove any functions.
1325314564Sdim    //
1326314564Sdim    // We also preserve all analyses on Functions, because we did all the
1327314564Sdim    // invalidation we needed to do above.
1328314564Sdim    PA.preserveSet<AllAnalysesOn<Function>>();
1329276479Sdim    PA.preserve<FunctionAnalysisManagerModuleProxy>();
1330276479Sdim    return PA;
1331276479Sdim  }
1332276479Sdim
1333276479Sdimprivate:
1334276479Sdim  FunctionPassT Pass;
1335276479Sdim};
1336276479Sdim
1337341825Sdim/// A function to deduce a function pass type and wrap it in the
1338276479Sdim/// templated adaptor.
1339276479Sdimtemplate <typename FunctionPassT>
1340276479SdimModuleToFunctionPassAdaptor<FunctionPassT>
1341276479SdimcreateModuleToFunctionPassAdaptor(FunctionPassT Pass) {
1342288943Sdim  return ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
1343259698Sdim}
1344276479Sdim
1345341825Sdim/// A utility pass template to force an analysis result to be available.
1346280031Sdim///
1347314564Sdim/// If there are extra arguments at the pass's run level there may also be
1348314564Sdim/// extra arguments to the analysis manager's \c getResult routine. We can't
1349314564Sdim/// guess how to effectively map the arguments from one to the other, and so
1350314564Sdim/// this specialization just ignores them.
1351314564Sdim///
1352314564Sdim/// Specific patterns of run-method extra arguments and analysis manager extra
1353314564Sdim/// arguments will have to be defined as appropriate specializations.
1354314564Sdimtemplate <typename AnalysisT, typename IRUnitT,
1355314564Sdim          typename AnalysisManagerT = AnalysisManager<IRUnitT>,
1356314564Sdim          typename... ExtraArgTs>
1357314564Sdimstruct RequireAnalysisPass
1358314564Sdim    : PassInfoMixin<RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
1359314564Sdim                                        ExtraArgTs...>> {
1360341825Sdim  /// Run this pass over some unit of IR.
1361280031Sdim  ///
1362280031Sdim  /// This pass can be run over any unit of IR and use any analysis manager
1363280031Sdim  /// provided they satisfy the basic API requirements. When this pass is
1364280031Sdim  /// created, these methods can be instantiated to satisfy whatever the
1365280031Sdim  /// context requires.
1366314564Sdim  PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM,
1367314564Sdim                        ExtraArgTs &&... Args) {
1368314564Sdim    (void)AM.template getResult<AnalysisT>(Arg,
1369314564Sdim                                           std::forward<ExtraArgTs>(Args)...);
1370280031Sdim
1371280031Sdim    return PreservedAnalyses::all();
1372280031Sdim  }
1373280031Sdim};
1374280031Sdim
1375341825Sdim/// A no-op pass template which simply forces a specific analysis result
1376314564Sdim/// to be invalidated.
1377309124Sdimtemplate <typename AnalysisT>
1378309124Sdimstruct InvalidateAnalysisPass
1379309124Sdim    : PassInfoMixin<InvalidateAnalysisPass<AnalysisT>> {
1380341825Sdim  /// Run this pass over some unit of IR.
1381280031Sdim  ///
1382314564Sdim  /// This pass can be run over any unit of IR and use any analysis manager,
1383280031Sdim  /// provided they satisfy the basic API requirements. When this pass is
1384280031Sdim  /// created, these methods can be instantiated to satisfy whatever the
1385280031Sdim  /// context requires.
1386314564Sdim  template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
1387314564Sdim  PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&...) {
1388314564Sdim    auto PA = PreservedAnalyses::all();
1389314564Sdim    PA.abandon<AnalysisT>();
1390314564Sdim    return PA;
1391280031Sdim  }
1392280031Sdim};
1393280031Sdim
1394341825Sdim/// A utility pass that does nothing, but preserves no analyses.
1395280031Sdim///
1396314564Sdim/// Because this preserves no analyses, any analysis passes queried after this
1397314564Sdim/// pass runs will recompute fresh results.
1398309124Sdimstruct InvalidateAllAnalysesPass : PassInfoMixin<InvalidateAllAnalysesPass> {
1399341825Sdim  /// Run this pass over some unit of IR.
1400314564Sdim  template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
1401314564Sdim  PreservedAnalyses run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
1402280031Sdim    return PreservedAnalyses::none();
1403280031Sdim  }
1404280031Sdim};
1405280031Sdim
1406314564Sdim/// A utility pass template that simply runs another pass multiple times.
1407314564Sdim///
1408314564Sdim/// This can be useful when debugging or testing passes. It also serves as an
1409314564Sdim/// example of how to extend the pass manager in ways beyond composition.
1410314564Sdimtemplate <typename PassT>
1411314564Sdimclass RepeatedPass : public PassInfoMixin<RepeatedPass<PassT>> {
1412314564Sdimpublic:
1413314564Sdim  RepeatedPass(int Count, PassT P) : Count(Count), P(std::move(P)) {}
1414314564Sdim
1415314564Sdim  template <typename IRUnitT, typename AnalysisManagerT, typename... Ts>
1416344779Sdim  PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, Ts &&... Args) {
1417344779Sdim
1418344779Sdim    // Request PassInstrumentation from analysis manager, will use it to run
1419344779Sdim    // instrumenting callbacks for the passes later.
1420344779Sdim    // Here we use std::tuple wrapper over getResult which helps to extract
1421344779Sdim    // AnalysisManager's arguments out of the whole Args set.
1422344779Sdim    PassInstrumentation PI =
1423344779Sdim        detail::getAnalysisResult<PassInstrumentationAnalysis>(
1424344779Sdim            AM, IR, std::tuple<Ts...>(Args...));
1425344779Sdim
1426314564Sdim    auto PA = PreservedAnalyses::all();
1427344779Sdim    for (int i = 0; i < Count; ++i) {
1428344779Sdim      // Check the PassInstrumentation's BeforePass callbacks before running the
1429344779Sdim      // pass, skip its execution completely if asked to (callback returns
1430344779Sdim      // false).
1431344779Sdim      if (!PI.runBeforePass<IRUnitT>(P, IR))
1432344779Sdim        continue;
1433344779Sdim      PA.intersect(P.run(IR, AM, std::forward<Ts>(Args)...));
1434344779Sdim      PI.runAfterPass(P, IR);
1435344779Sdim    }
1436314564Sdim    return PA;
1437314564Sdim  }
1438314564Sdim
1439314564Sdimprivate:
1440314564Sdim  int Count;
1441314564Sdim  PassT P;
1442314564Sdim};
1443314564Sdim
1444314564Sdimtemplate <typename PassT>
1445314564SdimRepeatedPass<PassT> createRepeatedPass(int Count, PassT P) {
1446314564Sdim  return RepeatedPass<PassT>(Count, std::move(P));
1447276479Sdim}
1448276479Sdim
1449321369Sdim} // end namespace llvm
1450314564Sdim
1451321369Sdim#endif // LLVM_IR_PASSMANAGER_H
1452