//===- PassManager.h - Pass management infrastructure -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This header defines various interfaces for pass management in LLVM. There
/// is no "pass" interface in LLVM per se. Instead, an instance of any class
/// which supports a method to 'run' it over a unit of IR can be used as
/// a pass. A pass manager is generally a tool to collect a sequence of passes
/// which run over a particular IR construct, and run each of them in sequence
/// over each such construct in the containing IR construct. As there is no
/// containing IR construct for a Module, a manager for passes over modules
/// forms the base case which runs its managed passes in sequence over the
/// single module provided.
///
/// The core IR library provides managers for running passes over
/// modules and functions.
///
/// * FunctionPassManager can run over a Module, runs each pass over
///   a Function.
/// * ModulePassManager must be directly run, runs each pass over the Module.
///
/// Note that the implementations of the pass managers use concept-based
/// polymorphism as outlined in the "Value Semantics and Concept-based
/// Polymorphism" talk (or its abbreviated sibling "Inheritance Is The Base
/// Class of Evil") by Sean Parent:
/// * http://github.com/sean-parent/sean-parent.github.com/wiki/Papers-and-Presentations
/// * http://www.youtube.com/watch?v=_BpMYeUFXv8
/// * http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_PASSMANAGER_H
#define LLVM_IR_PASSMANAGER_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManagerInternal.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/type_traits.h"
#include <list>
#include <memory>
#include <vector>

namespace llvm {

class Module;
class Function;

/// \brief An abstract set of preserved analyses following a transformation pass
/// run.
///
/// When a transformation pass is run, it can return a set of analyses whose
/// results were preserved by that transformation. The default set is "none",
/// and preserving analyses must be done explicitly.
///
/// There is also an explicit all state which can be used (for example) when
/// the IR is not mutated at all.
class PreservedAnalyses {
public:
  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  PreservedAnalyses() {}
  PreservedAnalyses(const PreservedAnalyses &Arg)
      : PreservedPassIDs(Arg.PreservedPassIDs) {}
  PreservedAnalyses(PreservedAnalyses &&Arg)
      : PreservedPassIDs(std::move(Arg.PreservedPassIDs)) {}
  friend void swap(PreservedAnalyses &LHS, PreservedAnalyses &RHS) {
    using std::swap;
    swap(LHS.PreservedPassIDs, RHS.PreservedPassIDs);
  }
  PreservedAnalyses &operator=(PreservedAnalyses RHS) {
    swap(*this, RHS);
    return *this;
  }

  /// \brief Convenience factory function for the empty preserved set.
  static PreservedAnalyses none() { return PreservedAnalyses(); }

  /// \brief Construct a special preserved set that preserves all passes.
  static PreservedAnalyses all() {
    PreservedAnalyses PA;
    PA.PreservedPassIDs.insert((void *)AllPassesID);
    return PA;
  }

  /// \brief Mark a particular pass as preserved, adding it to the set.
  template <typename PassT> void preserve() { preserve(PassT::ID()); }

  /// \brief Mark an abstract PassID as preserved, adding it to the set.
  void preserve(void *PassID) {
    if (!areAllPreserved())
      PreservedPassIDs.insert(PassID);
  }

  /// \brief Intersect this set with another in place.
  ///
  /// This is a mutating operation on this preserved set, removing all
  /// preserved passes which are not also preserved in the argument.
  void intersect(const PreservedAnalyses &Arg) {
    if (Arg.areAllPreserved())
      return;
    if (areAllPreserved()) {
      PreservedPassIDs = Arg.PreservedPassIDs;
      return;
    }
    for (void *P : PreservedPassIDs)
      if (!Arg.PreservedPassIDs.count(P))
        PreservedPassIDs.erase(P);
  }

  /// \brief Intersect this set with a temporary other set in place.
  ///
  /// This is a mutating operation on this preserved set, removing all
  /// preserved passes which are not also preserved in the argument.
  void intersect(PreservedAnalyses &&Arg) {
    if (Arg.areAllPreserved())
      return;
    if (areAllPreserved()) {
      PreservedPassIDs = std::move(Arg.PreservedPassIDs);
      return;
    }
    for (void *P : PreservedPassIDs)
      if (!Arg.PreservedPassIDs.count(P))
        PreservedPassIDs.erase(P);
  }

  /// \brief Query whether a pass is marked as preserved by this set.
  template <typename PassT> bool preserved() const {
    return preserved(PassT::ID());
  }

  /// \brief Query whether an abstract pass ID is marked as preserved by this
  /// set.
  bool preserved(void *PassID) const {
    return PreservedPassIDs.count((void *)AllPassesID) ||
           PreservedPassIDs.count(PassID);
  }

  /// \brief Test whether all passes are preserved.
  ///
  /// This is used primarily to optimize for the case of no changes which will
  /// common in many scenarios.
  bool areAllPreserved() const {
    return PreservedPassIDs.count((void *)AllPassesID);
  }

private:
  // Note that this must not be -1 or -2 as those are already used by the
  // SmallPtrSet.
  static const uintptr_t AllPassesID = (intptr_t)(-3);

  SmallPtrSet<void *, 2> PreservedPassIDs;
};

// Forward declare the analysis manager template.
template <typename IRUnitT> class AnalysisManager;

/// \brief Manages a sequence of passes over units of IR.
///
/// A pass manager contains a sequence of passes to run over units of IR. It is
/// itself a valid pass over that unit of IR, and when over some given IR will
/// run each pass in sequence. This is the primary and most basic building
/// block of a pass pipeline.
///
/// If it is run with an \c AnalysisManager<IRUnitT> argument, it will propagate
/// that analysis manager to each pass it runs, as well as calling the analysis
/// manager's invalidation routine with the PreservedAnalyses of each pass it
/// runs.
template <typename IRUnitT> class PassManager {
public:
  /// \brief Construct a pass manager.
  ///
  /// It can be passed a flag to get debug logging as the passes are run.
  PassManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  PassManager(PassManager &&Arg)
      : Passes(std::move(Arg.Passes)),
        DebugLogging(std::move(Arg.DebugLogging)) {}
  PassManager &operator=(PassManager &&RHS) {
    Passes = std::move(RHS.Passes);
    DebugLogging = std::move(RHS.DebugLogging);
    return *this;
  }

  /// \brief Run all of the passes in this manager over the IR.
  PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM = nullptr) {
    PreservedAnalyses PA = PreservedAnalyses::all();

    if (DebugLogging)
      dbgs() << "Starting pass manager run.\n";

    for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
      if (DebugLogging)
        dbgs() << "Running pass: " << Passes[Idx]->name() << " on "
               << IR.getName() << "\n";

      PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);

      // If we have an active analysis manager at this level we want to ensure
      // we update it as each pass runs and potentially invalidates analyses.
      // We also update the preserved set of analyses based on what analyses we
      // have already handled the invalidation for here and don't need to
      // invalidate when finished.
      if (AM)
        PassPA = AM->invalidate(IR, std::move(PassPA));

      // Finally, we intersect the final preserved analyses to compute the
      // aggregate preserved set for this pass manager.
      PA.intersect(std::move(PassPA));

      // FIXME: Historically, the pass managers all called the LLVM context's
      // yield function here. We don't have a generic way to acquire the
      // context and it isn't yet clear what the right pattern is for yielding
      // in the new pass manager so it is currently omitted.
      //IR.getContext().yield();
    }

    if (DebugLogging)
      dbgs() << "Finished pass manager run.\n";

    return PA;
  }

  template <typename PassT> void addPass(PassT Pass) {
    typedef detail::PassModel<IRUnitT, PassT> PassModelT;
    Passes.emplace_back(new PassModelT(std::move(Pass)));
  }

  static StringRef name() { return "PassManager"; }

private:
  typedef detail::PassConcept<IRUnitT> PassConceptT;

  PassManager(const PassManager &) = delete;
  PassManager &operator=(const PassManager &) = delete;

  std::vector<std::unique_ptr<PassConceptT>> Passes;

  /// \brief Flag indicating whether we should do debug logging.
  bool DebugLogging;
};

/// \brief Convenience typedef for a pass manager over modules.
typedef PassManager<Module> ModulePassManager;

/// \brief Convenience typedef for a pass manager over functions.
typedef PassManager<Function> FunctionPassManager;

namespace detail {

/// \brief A CRTP base used to implement analysis managers.
///
/// This class template serves as the boiler plate of an analysis manager. Any
/// analysis manager can be implemented on top of this base class. Any
/// implementation will be required to provide specific hooks:
///
/// - getResultImpl
/// - getCachedResultImpl
/// - invalidateImpl
///
/// The details of the call pattern are within.
///
/// Note that there is also a generic analysis manager template which implements
/// the above required functions along with common datastructures used for
/// managing analyses. This base class is factored so that if you need to
/// customize the handling of a specific IR unit, you can do so without
/// replicating *all* of the boilerplate.
template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
  DerivedT *derived_this() { return static_cast<DerivedT *>(this); }
  const DerivedT *derived_this() const {
    return static_cast<const DerivedT *>(this);
  }

  AnalysisManagerBase(const AnalysisManagerBase &) = delete;
  AnalysisManagerBase &
  operator=(const AnalysisManagerBase &) = delete;

protected:
  typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
  typedef detail::AnalysisPassConcept<IRUnitT> PassConceptT;

  // FIXME: Provide template aliases for the models when we're using C++11 in
  // a mode supporting them.

  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  AnalysisManagerBase() {}
  AnalysisManagerBase(AnalysisManagerBase &&Arg)
      : AnalysisPasses(std::move(Arg.AnalysisPasses)) {}
  AnalysisManagerBase &operator=(AnalysisManagerBase &&RHS) {
    AnalysisPasses = std::move(RHS.AnalysisPasses);
    return *this;
  }

public:
  /// \brief Get the result of an analysis pass for this module.
  ///
  /// If there is not a valid cached result in the manager already, this will
  /// re-run the analysis to produce a valid result.
  template <typename PassT> typename PassT::Result &getResult(IRUnitT &IR) {
    assert(AnalysisPasses.count(PassT::ID()) &&
           "This analysis pass was not registered prior to being queried");

    ResultConceptT &ResultConcept =
        derived_this()->getResultImpl(PassT::ID(), IR);
    typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
        ResultModelT;
    return static_cast<ResultModelT &>(ResultConcept).Result;
  }

  /// \brief Get the cached result of an analysis pass for this module.
  ///
  /// This method never runs the analysis.
  ///
  /// \returns null if there is no cached result.
  template <typename PassT>
  typename PassT::Result *getCachedResult(IRUnitT &IR) const {
    assert(AnalysisPasses.count(PassT::ID()) &&
           "This analysis pass was not registered prior to being queried");

    ResultConceptT *ResultConcept =
        derived_this()->getCachedResultImpl(PassT::ID(), IR);
    if (!ResultConcept)
      return nullptr;

    typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
        ResultModelT;
    return &static_cast<ResultModelT *>(ResultConcept)->Result;
  }

  /// \brief Register an analysis pass with the manager.
  ///
  /// This provides an initialized and set-up analysis pass to the analysis
  /// manager. Whomever is setting up analysis passes must use this to populate
  /// the manager with all of the analysis passes available.
  template <typename PassT> void registerPass(PassT Pass) {
    assert(!AnalysisPasses.count(PassT::ID()) &&
           "Registered the same analysis pass twice!");
    typedef detail::AnalysisPassModel<IRUnitT, PassT> PassModelT;
    AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
  }

  /// \brief Invalidate a specific analysis pass for an IR module.
  ///
  /// Note that the analysis result can disregard invalidation.
  template <typename PassT> void invalidate(IRUnitT &IR) {
    assert(AnalysisPasses.count(PassT::ID()) &&
           "This analysis pass was not registered prior to being invalidated");
    derived_this()->invalidateImpl(PassT::ID(), IR);
  }

  /// \brief Invalidate analyses cached for an IR unit.
  ///
  /// Walk through all of the analyses pertaining to this unit of IR and
  /// invalidate them unless they are preserved by the PreservedAnalyses set.
  /// We accept the PreservedAnalyses set by value and update it with each
  /// analyis pass which has been successfully invalidated and thus can be
  /// preserved going forward. The updated set is returned.
  PreservedAnalyses invalidate(IRUnitT &IR, PreservedAnalyses PA) {
    return derived_this()->invalidateImpl(IR, std::move(PA));
  }

protected:
  /// \brief Lookup a registered analysis pass.
  PassConceptT &lookupPass(void *PassID) {
    typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(PassID);
    assert(PI != AnalysisPasses.end() &&
           "Analysis passes must be registered prior to being queried!");
    return *PI->second;
  }

  /// \brief Lookup a registered analysis pass.
  const PassConceptT &lookupPass(void *PassID) const {
    typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(PassID);
    assert(PI != AnalysisPasses.end() &&
           "Analysis passes must be registered prior to being queried!");
    return *PI->second;
  }

private:
  /// \brief Map type from module analysis pass ID to pass concept pointer.
  typedef DenseMap<void *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;

  /// \brief Collection of module analysis passes, indexed by ID.
  AnalysisPassMapT AnalysisPasses;
};

} // End namespace detail

/// \brief A generic analysis pass manager with lazy running and caching of
/// results.
///
/// This analysis manager can be used for any IR unit where the address of the
/// IR unit sufficies as its identity. It manages the cache for a unit of IR via
/// the address of each unit of IR cached.
template <typename IRUnitT>
class AnalysisManager
    : public detail::AnalysisManagerBase<AnalysisManager<IRUnitT>, IRUnitT> {
  friend class detail::AnalysisManagerBase<AnalysisManager<IRUnitT>, IRUnitT>;
  typedef detail::AnalysisManagerBase<AnalysisManager<IRUnitT>, IRUnitT> BaseT;
  typedef typename BaseT::ResultConceptT ResultConceptT;
  typedef typename BaseT::PassConceptT PassConceptT;

public:
  // Most public APIs are inherited from the CRTP base class.

  /// \brief Construct an empty analysis manager.
  ///
  /// A flag can be passed to indicate that the manager should perform debug
  /// logging.
  AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}

  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  AnalysisManager(AnalysisManager &&Arg)
      : BaseT(std::move(static_cast<BaseT &>(Arg))),
        AnalysisResults(std::move(Arg.AnalysisResults)),
        DebugLogging(std::move(Arg.DebugLogging)) {}
  AnalysisManager &operator=(AnalysisManager &&RHS) {
    BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
    AnalysisResults = std::move(RHS.AnalysisResults);
    DebugLogging = std::move(RHS.DebugLogging);
    return *this;
  }

  /// \brief Returns true if the analysis manager has an empty results cache.
  bool empty() const {
    assert(AnalysisResults.empty() == AnalysisResultLists.empty() &&
           "The storage and index of analysis results disagree on how many "
           "there are!");
    return AnalysisResults.empty();
  }

  /// \brief Clear the analysis result cache.
  ///
  /// This routine allows cleaning up when the set of IR units itself has
  /// potentially changed, and thus we can't even look up a a result and
  /// invalidate it directly. Notably, this does *not* call invalidate functions
  /// as there is nothing to be done for them.
  void clear() {
    AnalysisResults.clear();
    AnalysisResultLists.clear();
  }

private:
  AnalysisManager(const AnalysisManager &) = delete;
  AnalysisManager &operator=(const AnalysisManager &) = delete;

  /// \brief Get an analysis result, running the pass if necessary.
  ResultConceptT &getResultImpl(void *PassID, IRUnitT &IR) {
    typename AnalysisResultMapT::iterator RI;
    bool Inserted;
    std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
        std::make_pair(PassID, &IR), typename AnalysisResultListT::iterator()));

    // If we don't have a cached result for this function, look up the pass and
    // run it to produce a result, which we then add to the cache.
    if (Inserted) {
      auto &P = this->lookupPass(PassID);
      if (DebugLogging)
        dbgs() << "Running analysis: " << P.name() << "\n";
      AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
      ResultList.emplace_back(PassID, P.run(IR, this));

      // P.run may have inserted elements into AnalysisResults and invalidated
      // RI.
      RI = AnalysisResults.find(std::make_pair(PassID, &IR));
      assert(RI != AnalysisResults.end() && "we just inserted it!");

      RI->second = std::prev(ResultList.end());
    }

    return *RI->second->second;
  }

  /// \brief Get a cached analysis result or return null.
  ResultConceptT *getCachedResultImpl(void *PassID, IRUnitT &IR) const {
    typename AnalysisResultMapT::const_iterator RI =
        AnalysisResults.find(std::make_pair(PassID, &IR));
    return RI == AnalysisResults.end() ? nullptr : &*RI->second->second;
  }

  /// \brief Invalidate a function pass result.
  void invalidateImpl(void *PassID, IRUnitT &IR) {
    typename AnalysisResultMapT::iterator RI =
        AnalysisResults.find(std::make_pair(PassID, &IR));
    if (RI == AnalysisResults.end())
      return;

    if (DebugLogging)
      dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
             << "\n";
    AnalysisResultLists[&IR].erase(RI->second);
    AnalysisResults.erase(RI);
  }

  /// \brief Invalidate the results for a function..
  PreservedAnalyses invalidateImpl(IRUnitT &IR, PreservedAnalyses PA) {
    // Short circuit for a common case of all analyses being preserved.
    if (PA.areAllPreserved())
      return PA;

    if (DebugLogging)
      dbgs() << "Invalidating all non-preserved analyses for: "
             << IR.getName() << "\n";

    // Clear all the invalidated results associated specifically with this
    // function.
    SmallVector<void *, 8> InvalidatedPassIDs;
    AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
    for (typename AnalysisResultListT::iterator I = ResultsList.begin(),
                                                E = ResultsList.end();
         I != E;) {
      void *PassID = I->first;

      // Pass the invalidation down to the pass itself to see if it thinks it is
      // necessary. The analysis pass can return false if no action on the part
      // of the analysis manager is required for this invalidation event.
      if (I->second->invalidate(IR, PA)) {
        if (DebugLogging)
          dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
                 << "\n";

        InvalidatedPassIDs.push_back(I->first);
        I = ResultsList.erase(I);
      } else {
        ++I;
      }

      // After handling each pass, we mark it as preserved. Once we've
      // invalidated any stale results, the rest of the system is allowed to
      // start preserving this analysis again.
      PA.preserve(PassID);
    }
    while (!InvalidatedPassIDs.empty())
      AnalysisResults.erase(
          std::make_pair(InvalidatedPassIDs.pop_back_val(), &IR));
    if (ResultsList.empty())
      AnalysisResultLists.erase(&IR);

    return PA;
  }

  /// \brief List of function analysis pass IDs and associated concept pointers.
  ///
  /// Requires iterators to be valid across appending new entries and arbitrary
  /// erases. Provides both the pass ID and concept pointer such that it is
  /// half of a bijection and provides storage for the actual result concept.
  typedef std::list<std::pair<
      void *, std::unique_ptr<detail::AnalysisResultConcept<IRUnitT>>>>
      AnalysisResultListT;

  /// \brief Map type from function pointer to our custom list type.
  typedef DenseMap<IRUnitT *, AnalysisResultListT> AnalysisResultListMapT;

  /// \brief Map from function to a list of function analysis results.
  ///
  /// Provides linear time removal of all analysis results for a function and
  /// the ultimate storage for a particular cached analysis result.
  AnalysisResultListMapT AnalysisResultLists;

  /// \brief Map type from a pair of analysis ID and function pointer to an
  /// iterator into a particular result list.
  typedef DenseMap<std::pair<void *, IRUnitT *>,
                   typename AnalysisResultListT::iterator> AnalysisResultMapT;

  /// \brief Map from an analysis ID and function to a particular cached
  /// analysis result.
  AnalysisResultMapT AnalysisResults;

  /// \brief A flag indicating whether debug logging is enabled.
  bool DebugLogging;
};

/// \brief Convenience typedef for the Module analysis manager.
typedef AnalysisManager<Module> ModuleAnalysisManager;

/// \brief Convenience typedef for the Function analysis manager.
typedef AnalysisManager<Function> FunctionAnalysisManager;

/// \brief A module analysis which acts as a proxy for a function analysis
/// manager.
///
/// This primarily proxies invalidation information from the module analysis
/// manager and module pass manager to a function analysis manager. You should
/// never use a function analysis manager from within (transitively) a module
/// pass manager unless your parent module pass has received a proxy result
/// object for it.
class FunctionAnalysisManagerModuleProxy {
public:
  class Result;

  static void *ID() { return (void *)&PassID; }

  static StringRef name() { return "FunctionAnalysisManagerModuleProxy"; }

  explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
      : FAM(&FAM) {}
  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  FunctionAnalysisManagerModuleProxy(
      const FunctionAnalysisManagerModuleProxy &Arg)
      : FAM(Arg.FAM) {}
  FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)
      : FAM(std::move(Arg.FAM)) {}
  FunctionAnalysisManagerModuleProxy &
  operator=(FunctionAnalysisManagerModuleProxy RHS) {
    std::swap(FAM, RHS.FAM);
    return *this;
  }

  /// \brief Run the analysis pass and create our proxy result object.
  ///
  /// This doesn't do any interesting work, it is primarily used to insert our
  /// proxy result object into the module analysis cache so that we can proxy
  /// invalidation to the function analysis manager.
  ///
  /// In debug builds, it will also assert that the analysis manager is empty
  /// as no queries should arrive at the function analysis manager prior to
  /// this analysis being requested.
  Result run(Module &M);

private:
  static char PassID;

  FunctionAnalysisManager *FAM;
};

/// \brief The result proxy object for the
/// \c FunctionAnalysisManagerModuleProxy.
///
/// See its documentation for more information.
class FunctionAnalysisManagerModuleProxy::Result {
public:
  explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  Result(const Result &Arg) : FAM(Arg.FAM) {}
  Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
  Result &operator=(Result RHS) {
    std::swap(FAM, RHS.FAM);
    return *this;
  }
  ~Result();

  /// \brief Accessor for the \c FunctionAnalysisManager.
  FunctionAnalysisManager &getManager() { return *FAM; }

  /// \brief Handler for invalidation of the module.
  ///
  /// If this analysis itself is preserved, then we assume that the set of \c
  /// Function objects in the \c Module hasn't changed and thus we don't need
  /// to invalidate *all* cached data associated with a \c Function* in the \c
  /// FunctionAnalysisManager.
  ///
  /// Regardless of whether this analysis is marked as preserved, all of the
  /// analyses in the \c FunctionAnalysisManager are potentially invalidated
  /// based on the set of preserved analyses.
  bool invalidate(Module &M, const PreservedAnalyses &PA);

private:
  FunctionAnalysisManager *FAM;
};

/// \brief A function analysis which acts as a proxy for a module analysis
/// manager.
///
/// This primarily provides an accessor to a parent module analysis manager to
/// function passes. Only the const interface of the module analysis manager is
/// provided to indicate that once inside of a function analysis pass you
/// cannot request a module analysis to actually run. Instead, the user must
/// rely on the \c getCachedResult API.
///
/// This proxy *doesn't* manage the invalidation in any way. That is handled by
/// the recursive return path of each layer of the pass manager and the
/// returned PreservedAnalysis set.
class ModuleAnalysisManagerFunctionProxy {
public:
  /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
  class Result {
  public:
    explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
    // We have to explicitly define all the special member functions because
    // MSVC refuses to generate them.
    Result(const Result &Arg) : MAM(Arg.MAM) {}
    Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
    Result &operator=(Result RHS) {
      std::swap(MAM, RHS.MAM);
      return *this;
    }

    const ModuleAnalysisManager &getManager() const { return *MAM; }

    /// \brief Handle invalidation by ignoring it, this pass is immutable.
    bool invalidate(Function &) { return false; }

  private:
    const ModuleAnalysisManager *MAM;
  };

  static void *ID() { return (void *)&PassID; }

  static StringRef name() { return "ModuleAnalysisManagerFunctionProxy"; }

  ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
      : MAM(&MAM) {}
  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  ModuleAnalysisManagerFunctionProxy(
      const ModuleAnalysisManagerFunctionProxy &Arg)
      : MAM(Arg.MAM) {}
  ModuleAnalysisManagerFunctionProxy(ModuleAnalysisManagerFunctionProxy &&Arg)
      : MAM(std::move(Arg.MAM)) {}
  ModuleAnalysisManagerFunctionProxy &
  operator=(ModuleAnalysisManagerFunctionProxy RHS) {
    std::swap(MAM, RHS.MAM);
    return *this;
  }

  /// \brief Run the analysis pass and create our proxy result object.
  /// Nothing to see here, it just forwards the \c MAM reference into the
  /// result.
  Result run(Function &) { return Result(*MAM); }

private:
  static char PassID;

  const ModuleAnalysisManager *MAM;
};

/// \brief Trivial adaptor that maps from a module to its functions.
///
/// Designed to allow composition of a FunctionPass(Manager) and
/// a ModulePassManager. Note that if this pass is constructed with a pointer
/// to a \c ModuleAnalysisManager it will run the
/// \c FunctionAnalysisManagerModuleProxy analysis prior to running the function
/// pass over the module to enable a \c FunctionAnalysisManager to be used
/// within this run safely.
///
/// Function passes run within this adaptor can rely on having exclusive access
/// to the function they are run over. They should not read or modify any other
/// functions! Other threads or systems may be manipulating other functions in
/// the module, and so their state should never be relied on.
/// FIXME: Make the above true for all of LLVM's actual passes, some still
/// violate this principle.
///
/// Function passes can also read the module containing the function, but they
/// should not modify that module outside of the use lists of various globals.
/// For example, a function pass is not permitted to add functions to the
/// module.
/// FIXME: Make the above true for all of LLVM's actual passes, some still
/// violate this principle.
template <typename FunctionPassT> class ModuleToFunctionPassAdaptor {
public:
  explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
      : Pass(std::move(Pass)) {}
  // We have to explicitly define all the special member functions because MSVC
  // refuses to generate them.
  ModuleToFunctionPassAdaptor(const ModuleToFunctionPassAdaptor &Arg)
      : Pass(Arg.Pass) {}
  ModuleToFunctionPassAdaptor(ModuleToFunctionPassAdaptor &&Arg)
      : Pass(std::move(Arg.Pass)) {}
  friend void swap(ModuleToFunctionPassAdaptor &LHS,
                   ModuleToFunctionPassAdaptor &RHS) {
    using std::swap;
    swap(LHS.Pass, RHS.Pass);
  }
  ModuleToFunctionPassAdaptor &operator=(ModuleToFunctionPassAdaptor RHS) {
    swap(*this, RHS);
    return *this;
  }

  /// \brief Runs the function pass across every function in the module.
  PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) {
    FunctionAnalysisManager *FAM = nullptr;
    if (AM)
      // Setup the function analysis manager from its proxy.
      FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();

    PreservedAnalyses PA = PreservedAnalyses::all();
    for (Function &F : M) {
      if (F.isDeclaration())
        continue;

      PreservedAnalyses PassPA = Pass.run(F, FAM);

      // We know that the function pass couldn't have invalidated any other
      // function's analyses (that's the contract of a function pass), so
      // directly handle the function analysis manager's invalidation here and
      // update our preserved set to reflect that these have already been
      // handled.
      if (FAM)
        PassPA = FAM->invalidate(F, std::move(PassPA));

      // Then intersect the preserved set so that invalidation of module
      // analyses will eventually occur when the module pass completes.
      PA.intersect(std::move(PassPA));
    }

    // By definition we preserve the proxy. This precludes *any* invalidation
    // of function analyses by the proxy, but that's OK because we've taken
    // care to invalidate analyses in the function analysis manager
    // incrementally above.
    PA.preserve<FunctionAnalysisManagerModuleProxy>();
    return PA;
  }

  static StringRef name() { return "ModuleToFunctionPassAdaptor"; }

private:
  FunctionPassT Pass;
};

/// \brief A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename FunctionPassT>
ModuleToFunctionPassAdaptor<FunctionPassT>
createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
  return ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
}

/// \brief A template utility pass to force an analysis result to be available.
///
/// This is a no-op pass which simply forces a specific analysis pass's result
/// to be available when it is run.
template <typename AnalysisT> struct RequireAnalysisPass {
  /// \brief Run this pass over some unit of IR.
  ///
  /// This pass can be run over any unit of IR and use any analysis manager
  /// provided they satisfy the basic API requirements. When this pass is
  /// created, these methods can be instantiated to satisfy whatever the
  /// context requires.
  template <typename IRUnitT>
  PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
    if (AM)
      (void)AM->template getResult<AnalysisT>(Arg);

    return PreservedAnalyses::all();
  }

  static StringRef name() { return "RequireAnalysisPass"; }
};

/// \brief A template utility pass to force an analysis result to be
/// invalidated.
///
/// This is a no-op pass which simply forces a specific analysis result to be
/// invalidated when it is run.
template <typename AnalysisT> struct InvalidateAnalysisPass {
  /// \brief Run this pass over some unit of IR.
  ///
  /// This pass can be run over any unit of IR and use any analysis manager
  /// provided they satisfy the basic API requirements. When this pass is
  /// created, these methods can be instantiated to satisfy whatever the
  /// context requires.
  template <typename IRUnitT>
  PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
    if (AM)
      // We have to directly invalidate the analysis result as we can't
      // enumerate all other analyses and use the preserved set to control it.
      (void)AM->template invalidate<AnalysisT>(Arg);

    return PreservedAnalyses::all();
  }

  static StringRef name() { return "InvalidateAnalysisPass"; }
};

/// \brief A utility pass that does nothing but preserves no analyses.
///
/// As a consequence fo not preserving any analyses, this pass will force all
/// analysis passes to be re-run to produce fresh results if any are needed.
struct InvalidateAllAnalysesPass {
  /// \brief Run this pass over some unit of IR.
  template <typename IRUnitT> PreservedAnalyses run(IRUnitT &Arg) {
    return PreservedAnalyses::none();
  }

  static StringRef name() { return "InvalidateAllAnalysesPass"; }
};

}

#endif
