[llvm] r342664 - [New PM] Introducing PassInstrumentation framework

Fedor Sergeev via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 21 11:35:29 PDT 2018


Galina,

The failure does not look like something I can possibly fix:

C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\lib\Passes\PassBuilder.cpp 
: fatal error C1128: number of sections exceeded object file format 
limit: compile with /bigobj

I have no slightest clue what does it mean and how my changes could ever 
cause it.
regards,
   Fedor.

On 09/21/2018 09:11 PM, Galina Kistanova wrote:
 > Hello Fedor,
 >
 > This commit broke build step on one of our builders:
 > 
http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/12632
 > . . .
 > FAILED: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.obj
 > . . .
 >
 > Please have a look?
 > The builder was already red and did not send notifications on this.
 >
 > Thanks
 >
 > Galina
 >
 > On Thu, Sep 20, 2018 at 10:10 AM Fedor Sergeev via llvm-commits 
<llvm-commits at lists.llvm.org> wrote:
 >
 >     Author: fedor.sergeev
 >     Date: Thu Sep 20 10:08:45 2018
 >     New Revision: 342664
 >
 >     URL: http://llvm.org/viewvc/llvm-project?rev=342664&view=rev
 >     Log:
 >     [New PM] Introducing PassInstrumentation framework
 >
 >     Pass Execution Instrumentation interface enables customizable 
instrumentation
 >     of pass execution, as per "RFC: Pass Execution Instrumentation 
interface"
 >     posted 06/07/2018 on llvm-dev@
 >
 >     The intent is to provide a common machinery to implement all
 >     the pass-execution-debugging features like print-before/after,
 >     opt-bisect, time-passes etc.
 >
 >     Here we get a basic implementation consisting of:
 >     * PassInstrumentationCallbacks class that handles registration of 
callbacks
 >       and access to them.
 >
 >     * PassInstrumentation class that handles instrumentation-point 
interfaces
 >       that call into PassInstrumentationCallbacks.
 >
 >     * Callbacks accept StringRef which is just a name of the Pass 
right now.
 >       There were some ideas to pass an opaque wrapper for the pointer 
to pass instance,
 >       however it appears that pointer does not actually identify the 
instance
 >       (adaptors and managers might have the same address with the 
pass they govern).
 >       Hence it was decided to go simple for now and then later decide 
on what the proper
 >       mental model of identifying a "pass in a phase of pipeline" is.
 >
 >     * Callbacks accept llvm::Any serving as a wrapper for const 
IRUnit*, to remove direct dependencies
 >       on different IRUnits (e.g. Analyses).
 >
 >     * PassInstrumentationAnalysis analysis is explicitly requested 
from PassManager through
 >       usual AnalysisManager::getResult. All pass managers were 
updated to run that
 >       to get PassInstrumentation object for instrumentation calls.
 >
 >     * Using tuples/index_sequence getAnalysisResult helper to extract 
generic AnalysisManager's extra
 >       args out of a generic PassManager's extra args. This is the 
only way I was able to explicitly
 >       run getResult for PassInstrumentationAnalysis out of a generic 
code like PassManager::run or
 >       RepeatedPass::run.
 >       TODO: Upon lengthy discussions we agreed to accept this as an 
initial implementation
 >       and then get rid of getAnalysisResult by improving RepeatedPass 
implementation.
 >
 >     * PassBuilder takes PassInstrumentationCallbacks object to pass 
it further into
 >       PassInstrumentationAnalysis. Callbacks registration should be 
performed directly
 >       through PassInstrumentationCallbacks.
 >
 >     * new-pm tests updated to account for PassInstrumentationAnalysis 
being run
 >
 >     * Added PassInstrumentation tests to PassBuilderCallbacks unit tests.
 >       Other unit tests updated with registration of the now-required 
PassInstrumentationAnalysis.
 >
 >       Made getName helper to return std::string (instead of StringRef 
initially) to fix
 >       asan builtbot failures on CGSCC tests.
 >
 >     Reviewers: chandlerc, philip.pfaffe
 >     Differential Revision: https://reviews.llvm.org/D47858
 >
 >     Added:
 >         llvm/trunk/include/llvm/IR/PassInstrumentation.h
 >         llvm/trunk/lib/IR/PassInstrumentation.cpp
 >     Modified:
 >         llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h
 >         llvm/trunk/include/llvm/IR/PassManager.h
 >         llvm/trunk/include/llvm/Passes/PassBuilder.h
 > llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h
 >         llvm/trunk/lib/Analysis/CGSCCPassManager.cpp
 >         llvm/trunk/lib/FuzzMutate/IRMutator.cpp
 >         llvm/trunk/lib/IR/CMakeLists.txt
 >         llvm/trunk/lib/Passes/PassRegistry.def
 >         llvm/trunk/lib/Transforms/Scalar/LoopPassManager.cpp
 >         llvm/trunk/test/Other/loop-pm-invalidation.ll
 >         llvm/trunk/test/Other/new-pass-manager.ll
 >         llvm/trunk/test/Other/new-pm-defaults.ll
 >         llvm/trunk/test/Other/new-pm-lto-defaults.ll
 >         llvm/trunk/test/Other/new-pm-thinlto-defaults.ll
 > llvm/trunk/test/Transforms/Inline/cgscc-incremental-invalidate.ll
 >         llvm/trunk/test/Transforms/LoopRotate/pr35210.ll
 >         llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp
 >         llvm/trunk/unittests/IR/PassBuilderCallbacksTest.cpp
 >         llvm/trunk/unittests/IR/PassManagerTest.cpp
 > llvm/trunk/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
 >
 >     Modified: llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h (original)
 >     +++ llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h Thu Sep 
20 10:08:45 2018
 >     @@ -364,6 +364,10 @@ public:
 >                                  InvalidSCCSet, nullptr,   nullptr,
 >                                  InlinedInternalEdges};
 >
 >     +    // Request PassInstrumentation from analysis manager, will 
use it to run
 >     +    // instrumenting callbacks for the passes later.
 >     +    PassInstrumentation PI = 
AM.getResult<PassInstrumentationAnalysis>(M);
 >     +
 >          PreservedAnalyses PA = PreservedAnalyses::all();
 >          CG.buildRefSCCs();
 >          for (auto RCI = CG.postorder_ref_scc_begin(),
 >     @@ -428,8 +432,17 @@ public:
 >
 >                  UR.UpdatedRC = nullptr;
 >                  UR.UpdatedC = nullptr;
 >     +
 >     +            // Check the PassInstrumentation's BeforePass 
callbacks before
 >     +            // running the pass, skip its execution completely 
if asked to
 >     +            // (callback returns false).
 >     +            if (!PI.runBeforePass<LazyCallGraph::SCC>(Pass, *C))
 >     +              continue;
 >     +
 >                  PreservedAnalyses PassPA = Pass.run(*C, CGAM, CG, UR);
 >
 >     + PI.runAfterPass<LazyCallGraph::SCC>(Pass, *C);
 >     +
 >                  // Update the SCC and RefSCC if necessary.
 >                  C = UR.UpdatedC ? UR.UpdatedC : C;
 >                  RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
 >     @@ -615,12 +628,20 @@ public:
 >            if (CG.lookupSCC(*N) != CurrentC)
 >              continue;
 >
 >     -      PreservedAnalyses PassPA = Pass.run(N->getFunction(), FAM);
 >     +      Function &F = N->getFunction();
 >     +
 >     +      PassInstrumentation PI = 
FAM.getResult<PassInstrumentationAnalysis>(F);
 >     +      if (!PI.runBeforePass<Function>(Pass, F))
 >     +        continue;
 >     +
 >     +      PreservedAnalyses PassPA = Pass.run(F, FAM);
 >     +
 >     +      PI.runAfterPass<Function>(Pass, F);
 >
 >            // 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.
 >     -      FAM.invalidate(N->getFunction(), PassPA);
 >     +      FAM.invalidate(F, PassPA);
 >
 >            // Then intersect the preserved set so that invalidation 
of module
 >            // analyses will eventually occur when the module pass 
completes.
 >     @@ -690,6 +711,8 @@ public:
 >        PreservedAnalyses run(LazyCallGraph::SCC &InitialC, 
CGSCCAnalysisManager &AM,
 >                              LazyCallGraph &CG, CGSCCUpdateResult &UR) {
 >          PreservedAnalyses PA = PreservedAnalyses::all();
 >     +    PassInstrumentation PI =
 >     + AM.getResult<PassInstrumentationAnalysis>(InitialC, CG);
 >
 >          // The SCC may be refined while we are running passes over 
it, so set up
 >          // a pointer that we can update.
 >     @@ -733,8 +756,14 @@ public:
 >          auto CallCounts = ScanSCC(*C, CallHandles);
 >
 >          for (int Iteration = 0;; ++Iteration) {
 >     +
 >     +      if (!PI.runBeforePass<LazyCallGraph::SCC>(Pass, *C))
 >     +        continue;
 >     +
 >            PreservedAnalyses PassPA = Pass.run(*C, AM, CG, UR);
 >
 >     +      PI.runAfterPass<LazyCallGraph::SCC>(Pass, *C);
 >     +
 >            // If the SCC structure has changed, bail immediately and 
let the outer
 >            // CGSCC layer handle any iteration to reflect the refined 
structure.
 >            if (UR.UpdatedC && UR.UpdatedC != C) {
 >
 >     Added: llvm/trunk/include/llvm/IR/PassInstrumentation.h
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassInstrumentation.h?rev=342664&view=auto
 > 
==============================================================================
 >     --- llvm/trunk/include/llvm/IR/PassInstrumentation.h (added)
 >     +++ llvm/trunk/include/llvm/IR/PassInstrumentation.h Thu Sep 20 
10:08:45 2018
 >     @@ -0,0 +1,150 @@
 >     +//===- llvm/IR/PassInstrumentation.h ----------------------*- 
C++ -*-===//
 >     +//
 >     +//                     The LLVM Compiler Infrastructure
 >     +//
 >     +// This file is distributed under the University of Illinois 
Open Source
 >     +// License. See LICENSE.TXT for details.
 >     +//
 > 
+//===----------------------------------------------------------------------===//
 >     +/// \file
 >     +///
 >     +/// This file defines the Pass Instrumentation classes that provide
 >     +/// instrumentation points into the pass execution by PassManager.
 >     +///
 >     +/// There are two main classes:
 >     +///   - PassInstrumentation provides a set of instrumentation 
points for
 >     +///     pass managers to call on.
 >     +///
 >     +///   - PassInstrumentationCallbacks registers callbacks and 
provides access
 >     +///     to them for PassInstrumentation.
 >     +///
 >     +/// PassInstrumentation object is being used as a result of
 >     +/// PassInstrumentationAnalysis (so it is intended to be easily 
copyable).
 >     +///
 >     +/// Intended scheme of use for Pass Instrumentation is as follows:
 >     +///    - register instrumentation callbacks in 
PassInstrumentationCallbacks
 >     +///      instance. PassBuilder provides helper for that.
 >     +///
 >     +///    - register PassInstrumentationAnalysis with all the 
PassManagers.
 >     +///      PassBuilder handles that automatically when registering 
analyses.
 >     +///
 >     +///    - Pass Manager requests PassInstrumentationAnalysis from 
analysis manager
 >     +///      and gets PassInstrumentation as its result.
 >     +///
 >     +///    - Pass Manager invokes PassInstrumentation entry points 
appropriately,
 >     +///      passing StringRef identification ("name") of the pass 
currently being
 >     +///      executed and IRUnit it works on. There can be different 
schemes of
 >     +///      providing names in future, currently it is just a 
name() of the pass.
 >     +///
 >     +///    - PassInstrumentation wraps address of IRUnit into 
llvm::Any and passes
 >     +///      control to all the registered callbacks. Note that we 
specifically wrap
 >     +///      'const IRUnitT*' so as to avoid any accidental changes 
to IR in
 >     +///      instrumenting callbacks.
 >     +///
 >     +///    - Some instrumentation points (BeforePass) allow to 
control execution
 >     +///      of a pass. For those callbacks returning false means 
pass will not be
 >     +///      executed.
 >     +///
 >     +/// TODO: currently there is no way for a pass to opt-out of 
execution control
 >     +/// (e.g. become unskippable). PassManager is the only entity 
that determines
 >     +/// how pass instrumentation affects pass execution.
 >     +///
 > 
+//===----------------------------------------------------------------------===//
 >     +
 >     +#ifndef LLVM_IR_PASSINSTRUMENTATION_H
 >     +#define LLVM_IR_PASSINSTRUMENTATION_H
 >     +
 >     +#include "llvm/ADT/Any.h"
 >     +#include "llvm/ADT/FunctionExtras.h"
 >     +#include "llvm/ADT/SmallVector.h"
 >     +#include "llvm/Support/TypeName.h"
 >     +#include <type_traits>
 >     +
 >     +namespace llvm {
 >     +
 >     +class PreservedAnalyses;
 >     +
 >     +/// This class manages callbacks registration, as well as 
provides a way for
 >     +/// PassInstrumentation to pass control to the registered callbacks.
 >     +class PassInstrumentationCallbacks {
 >     +public:
 >     +  // Before/After Pass callbacks accept IRUnits, so they need to 
take them
 >     +  // as pointers, wrapped with llvm::Any
 >     +  using BeforePassFunc = bool(StringRef, Any);
 >     +  using AfterPassFunc = void(StringRef, Any);
 >     +  using BeforeAnalysisFunc = void(StringRef, Any);
 >     +  using AfterAnalysisFunc = void(StringRef, Any);
 >     +
 >     +public:
 >     +  PassInstrumentationCallbacks() {}
 >     +
 >     +  /// Copying PassInstrumentationCallbacks is not intended.
 >     +  PassInstrumentationCallbacks(const 
PassInstrumentationCallbacks &) = delete;
 >     +  void operator=(const PassInstrumentationCallbacks &) = delete;
 >     +
 >     +  template <typename CallableT> void 
registerBeforePassCallback(CallableT C) {
 >     +    BeforePassCallbacks.emplace_back(std::move(C));
 >     +  }
 >     +
 >     +  template <typename CallableT> void 
registerAfterPassCallback(CallableT C) {
 >     +    AfterPassCallbacks.emplace_back(std::move(C));
 >     +  }
 >     +
 >     +private:
 >     +  friend class PassInstrumentation;
 >     +
 >     + SmallVector<llvm::unique_function<BeforePassFunc>, 4> 
BeforePassCallbacks;
 >     + SmallVector<llvm::unique_function<AfterPassFunc>, 4> 
AfterPassCallbacks;
 >     +};
 >     +
 >     +/// This class provides instrumentation entry points for the 
Pass Manager,
 >     +/// doing calls to callbacks registered in 
PassInstrumentationCallbacks.
 >     +class PassInstrumentation {
 >     +  PassInstrumentationCallbacks *Callbacks;
 >     +
 >     +public:
 >     +  /// Callbacks object is not owned by PassInstrumentation, its 
life-time
 >     +  /// should at least match the life-time of corresponding
 >     +  /// PassInstrumentationAnalysis (which usually is till the end 
of current
 >     +  /// compilation).
 >     +  PassInstrumentation(PassInstrumentationCallbacks *CB = nullptr)
 >     +      : Callbacks(CB) {}
 >     +
 >     +  /// BeforePass instrumentation point - takes \p Pass instance 
to be executed
 >     +  /// and constant reference to IR it operates on. \Returns true 
if pass is
 >     +  /// allowed to be executed.
 >     +  template <typename IRUnitT, typename PassT>
 >     +  bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
 >     +    if (!Callbacks)
 >     +      return true;
 >     +
 >     +    bool ShouldRun = true;
 >     +    for (auto &C : Callbacks->BeforePassCallbacks)
 >     +      ShouldRun &= C(Pass.name(), llvm::Any(&IR));
 >     +    return ShouldRun;
 >     +  }
 >     +
 >     +  /// AfterPass instrumentation point - takes \p Pass instance 
that has
 >     +  /// just been executed and constant reference to IR it 
operates on.
 >     +  template <typename IRUnitT, typename PassT>
 >     +  void runAfterPass(const PassT &Pass, const IRUnitT &IR) const {
 >     +    if (Callbacks)
 >     +      for (auto &C : Callbacks->AfterPassCallbacks)
 >     +        C(Pass.name(), llvm::Any(&IR));
 >     +  }
 >     +
 >     +  /// Handle invalidation from the pass manager when 
PassInstrumentation
 >     +  /// is used as the result of PassInstrumentationAnalysis.
 >     +  ///
 >     +  /// On attempt to invalidate just return false. There is 
nothing to become
 >     +  /// invalid here.
 >     +  template <typename IRUnitT, typename... ExtraArgsT>
 >     +  bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &,
 >     +                  ExtraArgsT...) {
 >     +    return false;
 >     +  }
 >     +};
 >     +
 >     +} // namespace llvm
 >     +
 >     +#endif
 >
 >     Modified: llvm/trunk/include/llvm/IR/PassManager.h
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/include/llvm/IR/PassManager.h (original)
 >     +++ llvm/trunk/include/llvm/IR/PassManager.h Thu Sep 20 10:08:45 2018
 >     @@ -44,6 +44,7 @@
 >      #include "llvm/ADT/TinyPtrVector.h"
 >      #include "llvm/IR/Function.h"
 >      #include "llvm/IR/Module.h"
 >     +#include "llvm/IR/PassInstrumentation.h"
 >      #include "llvm/IR/PassManagerInternal.h"
 >      #include "llvm/Support/Debug.h"
 >      #include "llvm/Support/TypeName.h"
 >     @@ -402,6 +403,43 @@ struct AnalysisInfoMixin : PassInfoMixin
 >        }
 >      };
 >
 >     +namespace detail {
 >     +
 >     +/// Actual unpacker of extra arguments in getAnalysisResult,
 >     +/// passes only those tuple arguments that are mentioned in 
index_sequence.
 >     +template <typename PassT, typename IRUnitT, typename 
AnalysisManagerT,
 >     +          typename... ArgTs, size_t... Ns>
 >     +typename PassT::Result
 >     +getAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR,
 >     +                             std::tuple<ArgTs...> Args,
 >     + llvm::index_sequence<Ns...>) {
 >     +  (void)Args;
 >     +  return AM.template getResult<PassT>(IR, std::get<Ns>(Args)...);
 >     +}
 >     +
 >     +/// Helper for *partial* unpacking of extra arguments in 
getAnalysisResult.
 >     +///
 >     +/// Arguments passed in tuple come from PassManager, so they 
might have extra
 >     +/// arguments after those AnalysisManager's ExtraArgTs ones that 
we need to
 >     +/// pass to getResult.
 >     +template <typename PassT, typename IRUnitT, typename... 
AnalysisArgTs,
 >     +          typename... MainArgTs>
 >     +typename PassT::Result
 >     +getAnalysisResult(AnalysisManager<IRUnitT, AnalysisArgTs...> 
&AM, IRUnitT &IR,
 >     +                  std::tuple<MainArgTs...> Args) {
 >     +  return (getAnalysisResultUnpackTuple<
 >     +          PassT, IRUnitT>)(AM, IR, Args,
 >     + llvm::index_sequence_for<AnalysisArgTs...>{});
 >     +}
 >     +
 >     +} // namespace detail
 >     +
 >     +// Forward declare the pass instrumentation analysis explicitly 
queried in
 >     +// generic PassManager code.
 >     +// FIXME: figure out a way to move PassInstrumentationAnalysis 
into its own
 >     +// header.
 >     +class PassInstrumentationAnalysis;
 >     +
 >      /// Manages a sequence of passes over a particular unit of IR.
 >      ///
 >      /// A pass manager contains a sequence of passes to run over a 
particular unit
 >     @@ -445,15 +483,34 @@ public:
 >                              ExtraArgTs... ExtraArgs) {
 >          PreservedAnalyses PA = PreservedAnalyses::all();
 >
 >     +    // Request PassInstrumentation from analysis manager, will 
use it to run
 >     +    // instrumenting callbacks for the passes later.
 >     +    // Here we use std::tuple wrapper over getResult which helps 
to extract
 >     +    // AnalysisManager's arguments out of the whole ExtraArgs set.
 >     +    PassInstrumentation PI =
 >     + detail::getAnalysisResult<PassInstrumentationAnalysis>(
 >     +            AM, IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
 >     +
 >          if (DebugLogging)
 >            dbgs() << "Starting " << getTypeName<IRUnitT>() << " pass 
manager run.\n";
 >
 >          for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; 
++Idx) {
 >     +      auto *P = Passes[Idx].get();
 >            if (DebugLogging)
 >     -        dbgs() << "Running pass: " << Passes[Idx]->name() << " on "
 >     -               << IR.getName() << "\n";
 >     +        dbgs() << "Running pass: " << P->name() << " on " << 
IR.getName()
 >     +               << "\n";
 >     +
 >     +      // Check the PassInstrumentation's BeforePass callbacks 
before running the
 >     +      // pass, skip its execution completely if asked to 
(callback returns
 >     +      // false).
 >     +      if (!PI.runBeforePass<IRUnitT>(*P, IR))
 >     +        continue;
 >
 >     -      PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM, 
ExtraArgs...);
 >     +      PreservedAnalyses PassPA = P->run(IR, AM, ExtraArgs...);
 >     +
 >     +      // Call onto PassInstrumentation's AfterPass callbacks 
immediately after
 >     +      // running the pass.
 >     +      PI.runAfterPass<IRUnitT>(*P, IR);
 >
 >            // Update the analysis manager as each pass runs and 
potentially
 >            // invalidates analyses.
 >     @@ -510,6 +567,32 @@ extern template class PassManager<Functi
 >      /// Convenience typedef for a pass manager over functions.
 >      using FunctionPassManager = PassManager<Function>;
 >
 >     +/// Pseudo-analysis pass that exposes the \c PassInstrumentation 
to pass
 >     +/// managers. Goes before AnalysisManager definition to provide its
 >     +/// internals (e.g PassInstrumentationAnalysis::ID) for use 
there if needed.
 >     +/// FIXME: figure out a way to move PassInstrumentationAnalysis 
into its own
 >     +/// header.
 >     +class PassInstrumentationAnalysis
 >     +    : public AnalysisInfoMixin<PassInstrumentationAnalysis> {
 >     +  friend AnalysisInfoMixin<PassInstrumentationAnalysis>;
 >     +  static AnalysisKey Key;
 >     +
 >     +  PassInstrumentationCallbacks *Callbacks;
 >     +
 >     +public:
 >     +  /// PassInstrumentationCallbacks object is shared, owned by 
something else,
 >     +  /// not this analysis.
 >     +  PassInstrumentationAnalysis(PassInstrumentationCallbacks 
*Callbacks = nullptr)
 >     +      : Callbacks(Callbacks) {}
 >     +
 >     +  using Result = PassInstrumentation;
 >     +
 >     +  template <typename IRUnitT, typename AnalysisManagerT, 
typename... ExtraArgTs>
 >     +  Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
 >     +    return PassInstrumentation(Callbacks);
 >     +  }
 >     +};
 >     +
 >      /// A container for analyses that lazily runs them and caches their
 >      /// results.
 >      ///
 >     @@ -1192,13 +1275,24 @@ public:
 >          FunctionAnalysisManager &FAM =
 > AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
 >
 >     +    // Request PassInstrumentation from analysis manager, will 
use it to run
 >     +    // instrumenting callbacks for the passes later.
 >     +    PassInstrumentation PI = 
AM.getResult<PassInstrumentationAnalysis>(M);
 >     +
 >          PreservedAnalyses PA = PreservedAnalyses::all();
 >          for (Function &F : M) {
 >            if (F.isDeclaration())
 >              continue;
 >
 >     +      // Check the PassInstrumentation's BeforePass callbacks 
before running the
 >     +      // pass, skip its execution completely if asked to 
(callback returns
 >     +      // false).
 >     +      if (!PI.runBeforePass<Function>(Pass, F))
 >     +        continue;
 >            PreservedAnalyses PassPA = Pass.run(F, FAM);
 >
 >     +      PI.runAfterPass(Pass, F);
 >     +
 >            // 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.
 >     @@ -1302,10 +1396,26 @@ public:
 >        RepeatedPass(int Count, PassT P) : Count(Count), 
P(std::move(P)) {}
 >
 >        template <typename IRUnitT, typename AnalysisManagerT, 
typename... Ts>
 >     -  PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, Ts 
&&... Args) {
 >     +  PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, Ts 
&&... Args) {
 >     +
 >     +    // Request PassInstrumentation from analysis manager, will 
use it to run
 >     +    // instrumenting callbacks for the passes later.
 >     +    // Here we use std::tuple wrapper over getResult which helps 
to extract
 >     +    // AnalysisManager's arguments out of the whole Args set.
 >     +    PassInstrumentation PI =
 >     + detail::getAnalysisResult<PassInstrumentationAnalysis>(
 >     +            AM, IR, std::tuple<Ts...>(Args...));
 >     +
 >          auto PA = PreservedAnalyses::all();
 >     -    for (int i = 0; i < Count; ++i)
 >     -      PA.intersect(P.run(Arg, AM, std::forward<Ts>(Args)...));
 >     +    for (int i = 0; i < Count; ++i) {
 >     +      // Check the PassInstrumentation's BeforePass callbacks 
before running the
 >     +      // pass, skip its execution completely if asked to 
(callback returns
 >     +      // false).
 >     +      if (!PI.runBeforePass<IRUnitT>(P, IR))
 >     +        continue;
 >     +      PA.intersect(P.run(IR, AM, std::forward<Ts>(Args)...));
 >     +      PI.runAfterPass(P, IR);
 >     +    }
 >          return PA;
 >        }
 >
 >
 >     Modified: llvm/trunk/include/llvm/Passes/PassBuilder.h
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Passes/PassBuilder.h?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/include/llvm/Passes/PassBuilder.h (original)
 >     +++ llvm/trunk/include/llvm/Passes/PassBuilder.h Thu Sep 20 
10:08:45 2018
 >     @@ -58,6 +58,7 @@ struct PGOOptions {
 >      class PassBuilder {
 >        TargetMachine *TM;
 >        Optional<PGOOptions> PGOOpt;
 >     +  PassInstrumentationCallbacks *PIC;
 >
 >      public:
 >        /// A struct to capture parsed pass pipeline names.
 >     @@ -172,8 +173,9 @@ public:
 >        };
 >
 >        explicit PassBuilder(TargetMachine *TM = nullptr,
 >     -                       Optional<PGOOptions> PGOOpt = None)
 >     -      : TM(TM), PGOOpt(PGOOpt) {}
 >     +                       Optional<PGOOptions> PGOOpt = None,
 >     +                       PassInstrumentationCallbacks *PIC = nullptr)
 >     +      : TM(TM), PGOOpt(PGOOpt), PIC(PIC) {}
 >
 >        /// Cross register the analysis managers through their proxies.
 >        ///
 >
 >     Modified: llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h 
(original)
 >     +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h 
Thu Sep 20 10:08:45 2018
 >     @@ -276,7 +276,15 @@ public:
 >          // pass pipeline to put loops into their canonical form. 
Note that we can
 >          // directly build up function analyses after this as the 
function pass
 >          // manager handles all the invalidation at that layer.
 >     -    PreservedAnalyses PA = LoopCanonicalizationFPM.run(F, AM);
 >     +    PassInstrumentation PI = 
AM.getResult<PassInstrumentationAnalysis>(F);
 >     +
 >     +    PreservedAnalyses PA = PreservedAnalyses::all();
 >     +    // Check the PassInstrumentation's BeforePass callbacks 
before running the
 >     +    // canonicalization pipeline.
 >     +    if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) {
 >     +      PA = LoopCanonicalizationFPM.run(F, AM);
 >     + PI.runAfterPass<Function>(LoopCanonicalizationFPM, F);
 >     +    }
 >
 >          // Get the loop structure for this function
 >          LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
 >     @@ -337,8 +345,15 @@ public:
 >            assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
 >                   "Loops must remain in LCSSA form!");
 >      #endif
 >     -
 >     +      // Check the PassInstrumentation's BeforePass callbacks 
before running the
 >     +      // pass, skip its execution completely if asked to 
(callback returns
 >     +      // false).
 >     +      if (!PI.runBeforePass<Loop>(Pass, *L))
 >     +        continue;
 >            PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater);
 >     +
 >     +      PI.runAfterPass<Loop>(Pass, *L);
 >     +
 >            // FIXME: We should verify the set of analyses relevant to 
Loop passes
 >            // are preserved.
 >
 >
 >     Modified: llvm/trunk/lib/Analysis/CGSCCPassManager.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CGSCCPassManager.cpp?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/lib/Analysis/CGSCCPassManager.cpp (original)
 >     +++ llvm/trunk/lib/Analysis/CGSCCPassManager.cpp Thu Sep 20 
10:08:45 2018
 >     @@ -54,6 +54,11 @@ PassManager<LazyCallGraph::SCC, CGSCCAna
 >                  CGSCCUpdateResult &>::run(LazyCallGraph::SCC &InitialC,
 >                                            CGSCCAnalysisManager &AM,
 >                                            LazyCallGraph &G, 
CGSCCUpdateResult &UR) {
 >     +  // Request PassInstrumentation from analysis manager, will use 
it to run
 >     +  // instrumenting callbacks for the passes later.
 >     +  PassInstrumentation PI =
 >     + AM.getResult<PassInstrumentationAnalysis>(InitialC, G);
 >     +
 >        PreservedAnalyses PA = PreservedAnalyses::all();
 >
 >        if (DebugLogging)
 >     @@ -67,8 +72,15 @@ PassManager<LazyCallGraph::SCC, CGSCCAna
 >          if (DebugLogging)
 >            dbgs() << "Running pass: " << Pass->name() << " on " << *C 
<< "\n";
 >
 >     +    // Check the PassInstrumentation's BeforePass callbacks 
before running the
 >     +    // pass, skip its execution completely if asked to (callback 
returns false).
 >     +    if (!PI.runBeforePass(*Pass, *C))
 >     +      continue;
 >     +
 >          PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR);
 >
 >     +    PI.runAfterPass(*Pass, *C);
 >     +
 >          // Update the SCC if necessary.
 >          C = UR.UpdatedC ? UR.UpdatedC : C;
 >
 >
 >     Modified: llvm/trunk/lib/FuzzMutate/IRMutator.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/FuzzMutate/IRMutator.cpp?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/lib/FuzzMutate/IRMutator.cpp (original)
 >     +++ llvm/trunk/lib/FuzzMutate/IRMutator.cpp Thu Sep 20 10:08:45 2018
 >     @@ -73,6 +73,7 @@ static void eliminateDeadCode(Function &
 >        FPM.addPass(DCEPass());
 >        FunctionAnalysisManager FAM;
 >        FAM.registerPass([&] { return TargetLibraryAnalysis(); });
 >     +  FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >        FPM.run(F, FAM);
 >      }
 >
 >
 >     Modified: llvm/trunk/lib/IR/CMakeLists.txt
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/CMakeLists.txt?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/lib/IR/CMakeLists.txt (original)
 >     +++ llvm/trunk/lib/IR/CMakeLists.txt Thu Sep 20 10:08:45 2018
 >     @@ -42,6 +42,7 @@ add_llvm_library(LLVMCore
 >        Operator.cpp
 >        OptBisect.cpp
 >        Pass.cpp
 >     +  PassInstrumentation.cpp
 >        PassManager.cpp
 >        PassRegistry.cpp
 >        PassTimingInfo.cpp
 >
 >     Added: llvm/trunk/lib/IR/PassInstrumentation.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/PassInstrumentation.cpp?rev=342664&view=auto
 > 
==============================================================================
 >     --- llvm/trunk/lib/IR/PassInstrumentation.cpp (added)
 >     +++ llvm/trunk/lib/IR/PassInstrumentation.cpp Thu Sep 20 10:08:45 
2018
 >     @@ -0,0 +1,22 @@
 >     +//===- PassInstrumentation.cpp - Pass Instrumentation interface 
-*- C++ -*-===//
 >     +//
 >     +//                     The LLVM Compiler Infrastructure
 >     +//
 >     +// This file is distributed under the University of Illinois 
Open Source
 >     +// License. See LICENSE.TXT for details.
 >     +//
 > 
+//===----------------------------------------------------------------------===//
 >     +/// \file
 >     +///
 >     +/// This file provides the implementation of PassInstrumentation 
class.
 >     +///
 > 
+//===----------------------------------------------------------------------===//
 >     +
 >     +#include "llvm/IR/PassInstrumentation.h"
 >     +#include "llvm/IR/PassManager.h"
 >     +
 >     +namespace llvm {
 >     +
 >     +AnalysisKey PassInstrumentationAnalysis::Key;
 >     +
 >     +} // namespace llvm
 >
 >     Modified: llvm/trunk/lib/Passes/PassRegistry.def
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/lib/Passes/PassRegistry.def (original)
 >     +++ llvm/trunk/lib/Passes/PassRegistry.def Thu Sep 20 10:08:45 2018
 >     @@ -26,6 +26,7 @@ MODULE_ANALYSIS("no-op-module", NoOpModu
 >      MODULE_ANALYSIS("profile-summary", ProfileSummaryAnalysis())
 >      MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
 >      MODULE_ANALYSIS("verify", VerifierAnalysis())
 >     +MODULE_ANALYSIS("pass-instrumentation", 
PassInstrumentationAnalysis(PIC))
 >
 >      #ifndef MODULE_ALIAS_ANALYSIS
 >      #define MODULE_ALIAS_ANALYSIS(NAME, 
CREATE_PASS)                               \
 >     @@ -84,6 +85,7 @@ MODULE_PASS("verify", VerifierPass())
 >      #endif
 >      CGSCC_ANALYSIS("no-op-cgscc", NoOpCGSCCAnalysis())
 >      CGSCC_ANALYSIS("fam-proxy", FunctionAnalysisManagerCGSCCProxy())
 >     +CGSCC_ANALYSIS("pass-instrumentation", 
PassInstrumentationAnalysis(PIC))
 >      #undef CGSCC_ANALYSIS
 >
 >      #ifndef CGSCC_PASS
 >     @@ -121,6 +123,7 @@ FUNCTION_ANALYSIS("targetlibinfo", Targe
 >      FUNCTION_ANALYSIS("targetir",
 >                        TM ? TM->getTargetIRAnalysis() : 
TargetIRAnalysis())
 >      FUNCTION_ANALYSIS("verify", VerifierAnalysis())
 >     +FUNCTION_ANALYSIS("pass-instrumentation", 
PassInstrumentationAnalysis(PIC))
 >
 >      #ifndef FUNCTION_ALIAS_ANALYSIS
 >      #define FUNCTION_ALIAS_ANALYSIS(NAME, 
CREATE_PASS)                             \
 >     @@ -226,6 +229,7 @@ FUNCTION_PASS("view-cfg-only", CFGOnlyVi
 >      LOOP_ANALYSIS("no-op-loop", NoOpLoopAnalysis())
 >      LOOP_ANALYSIS("access-info", LoopAccessAnalysis())
 >      LOOP_ANALYSIS("ivusers", IVUsersAnalysis())
 >     +LOOP_ANALYSIS("pass-instrumentation", 
PassInstrumentationAnalysis(PIC))
 >      #undef LOOP_ANALYSIS
 >
 >      #ifndef LOOP_PASS
 >
 >     Modified: llvm/trunk/lib/Transforms/Scalar/LoopPassManager.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopPassManager.cpp?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/lib/Transforms/Scalar/LoopPassManager.cpp (original)
 >     +++ llvm/trunk/lib/Transforms/Scalar/LoopPassManager.cpp Thu Sep 
20 10:08:45 2018
 >     @@ -30,12 +30,22 @@ PassManager<Loop, LoopAnalysisManager, L
 >        if (DebugLogging)
 >          dbgs() << "Starting Loop pass manager run.\n";
 >
 >     +  // Request PassInstrumentation from analysis manager, will use 
it to run
 >     +  // instrumenting callbacks for the passes later.
 >     +  PassInstrumentation PI = 
AM.getResult<PassInstrumentationAnalysis>(L, AR);
 >        for (auto &Pass : Passes) {
 >          if (DebugLogging)
 >            dbgs() << "Running pass: " << Pass->name() << " on " << L;
 >
 >     +    // Check the PassInstrumentation's BeforePass callbacks 
before running the
 >     +    // pass, skip its execution completely if asked to (callback 
returns false).
 >     +    if (!PI.runBeforePass<Loop>(*Pass, L))
 >     +      continue;
 >     +
 >          PreservedAnalyses PassPA = Pass->run(L, AM, AR, U);
 >
 >     +    PI.runAfterPass<Loop>(*Pass, L);
 >     +
 >          // If the loop was deleted, abort the run and return to the 
outer walk.
 >          if (U.skipCurrentLoop()) {
 >            PA.intersect(std::move(PassPA));
 >
 >     Modified: llvm/trunk/test/Other/loop-pm-invalidation.ll
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/loop-pm-invalidation.ll?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/test/Other/loop-pm-invalidation.ll (original)
 >     +++ llvm/trunk/test/Other/loop-pm-invalidation.ll Thu Sep 20 
10:08:45 2018
 >     @@ -73,6 +73,7 @@ define void @one_loop(i1* %ptr) {
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Running pass: 
InvalidateAnalysisPass<{{.*}}LoopAnalysis
 >     @@ -90,6 +91,7 @@ define void @one_loop(i1* %ptr) {
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run.
 >     @@ -108,6 +110,7 @@ define void @one_loop(i1* %ptr) {
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Running pass: 
InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
 >     @@ -123,6 +126,7 @@ define void @one_loop(i1* %ptr) {
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run.
 >     @@ -153,9 +157,11 @@ define void @nested_loops(i1* %ptr) {
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Running pass: 
InvalidateAnalysisPass<{{.*}}LoopAnalysis
 >     @@ -174,9 +180,11 @@ define void @nested_loops(i1* %ptr) {
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run.
 >     @@ -195,9 +203,11 @@ define void @nested_loops(i1* %ptr) {
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Running pass: 
InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
 >     @@ -214,9 +224,11 @@ define void @nested_loops(i1* %ptr) {
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run.
 >     @@ -254,6 +266,7 @@ define void @dead_loop() {
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Running pass: 
InvalidateAnalysisPass<{{.*}}LoopAnalysis
 >     @@ -271,6 +284,7 @@ define void @dead_loop() {
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run.
 >     @@ -289,6 +303,7 @@ define void @dead_loop() {
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Running pass: 
InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
 >     @@ -304,6 +319,7 @@ define void @dead_loop() {
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
 >     +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
 >      ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run.
 >     @@ -322,6 +338,7 @@ define void @dead_loop() {
 >      ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: 
TargetIRAnalysis
 >      ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Loop
 >      ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Starting {{.*}}Loop pass 
manager run.
 >     +; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: 
PassInstrumentationAnalysis
 >      ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: NoOpLoopPass
 >      ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: LoopDeletionPass
 >      ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Clearing all analysis 
results for:
 >
 >     Modified: llvm/trunk/test/Other/new-pass-manager.ll
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/test/Other/new-pass-manager.ll (original)
 >     +++ llvm/trunk/test/Other/new-pass-manager.ll Thu Sep 20 10:08:45 
2018
 >     @@ -24,6 +24,7 @@
 >      ; CHECK-CGSCC-PASS-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
 >      ; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
 >      ; CHECK-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
 >     +; CHECK-CGSCC-PASS-NEXT: Running analysis: 
PassInstrumentationAnalysis
 >      ; CHECK-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
 >      ; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
 >      ; CHECK-CGSCC-PASS-NEXT: Finished CGSCC pass manager run
 >     @@ -38,6 +39,7 @@
 >      ; CHECK-FUNCTION-PASS: Starting llvm::Module pass manager run
 >      ; CHECK-FUNCTION-PASS-NEXT: Running pass: 
ModuleToFunctionPassAdaptor
 >      ; CHECK-FUNCTION-PASS-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}>
 >     +; CHECK-FUNCTION-PASS-NEXT: Running analysis: 
PassInstrumentationAnalysis
 >      ; CHECK-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
 >      ; CHECK-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
 >      ; CHECK-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
 >     @@ -408,6 +410,7 @@
 >      ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
 >      ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: 
LazyCallGraphAnalysis
 >      ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: 
TargetLibraryAnalysis
 >     +; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: 
PassInstrumentationAnalysis
 >      ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
 >      ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: RepeatedPass
 >      ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
 >     @@ -428,6 +431,7 @@
 >      ; CHECK-REPEAT-FUNCTION-PASS: Starting llvm::Module pass manager run
 >      ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: 
ModuleToFunctionPassAdaptor
 >      ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}>
 >     +; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: 
PassInstrumentationAnalysis
 >      ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass 
manager run
 >      ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: RepeatedPass
 >      ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass 
manager run
 >     @@ -448,6 +452,7 @@
 >      ; CHECK-REPEAT-LOOP-PASS: Starting llvm::Module pass manager run
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: 
ModuleToFunctionPassAdaptor
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}>
 >     +; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: 
PassInstrumentationAnalysis
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass 
manager run
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: 
FunctionToLoopPassAdaptor
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass 
manager run
 >     @@ -464,6 +469,7 @@
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: TargetIRAnalysis
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}>
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting Loop pass manager run
 >     +; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: 
PassInstrumentationAnalysis
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: RepeatedPass
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting Loop pass manager run
 >      ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass
 >
 >     Modified: llvm/trunk/test/Other/new-pm-defaults.ll
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-defaults.ll?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/test/Other/new-pm-defaults.ll (original)
 >     +++ llvm/trunk/test/Other/new-pm-defaults.ll Thu Sep 20 10:08:45 2018
 >     @@ -67,7 +67,8 @@
 >      ; RUN:     | FileCheck %s --check-prefix=CHECK-O 
--check-prefix=CHECK-O3 \
 >      ; RUN:     --check-prefix=CHECK-EP-PIPELINE-START
 >
 >     -; CHECK-O: Starting llvm::Module pass manager run.
 >     +; CHECK-O: Running analysis: PassInstrumentationAnalysis
 >     +; CHECK-O-NEXT: Starting llvm::Module pass manager run.
 >      ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}>
 >      ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
 >      ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass
 >     @@ -78,6 +79,7 @@
 >      ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
 >      ; CHECK-O-NEXT: Running pass: 
ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
 >      ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 >     +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-O-NEXT: Starting llvm::Function pass manager run.
 >      ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 >      ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
 >     @@ -110,6 +112,7 @@
 >      ; CHECK-O-NEXT: Running pass: 
ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}>
 >      ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 >      ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
 >     +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-O-NEXT: Starting CGSCC pass manager run.
 >      ; CHECK-O-NEXT: Running pass: InlinerPass
 >      ; CHECK-O-NEXT: Running analysis: 
OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
 >     @@ -149,6 +152,7 @@
 >      ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 >      ; CHECK-O-NEXT: Starting Loop pass manager run.
 >     +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass
 >      ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass
 >      ; CHECK-O-NEXT: Running pass: LoopRotatePass
 >
 >     Modified: llvm/trunk/test/Other/new-pm-lto-defaults.ll
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-lto-defaults.ll?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/test/Other/new-pm-lto-defaults.ll (original)
 >     +++ llvm/trunk/test/Other/new-pm-lto-defaults.ll Thu Sep 20 
10:08:45 2018
 >     @@ -23,7 +23,8 @@
 >      ; RUN:     | FileCheck %s --check-prefix=CHECK-O 
--check-prefix=CHECK-O2 \
 >      ; RUN:     --check-prefix=CHECK-O3 --check-prefix=CHECK-EP-Peephole
 >
 >     -; CHECK-O: Starting llvm::Module pass manager run.
 >     +; CHECK-O: Running analysis: PassInstrumentationAnalysis
 >     +; CHECK-O-NEXT: Starting llvm::Module pass manager run.
 >      ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module
 >      ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
 >      ; CHECK-O-NEXT: Running pass: GlobalDCEPass
 >     @@ -32,6 +33,7 @@
 >      ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
 >      ; CHECK-O2-NEXT: Running pass: 
ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
 >      ; CHECK-O2-NEXT: Running analysis: 
InnerAnalysisManagerProxy<{{.*}}Module
 >     +; CHECK-O2-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-O2-NEXT: Starting llvm::Function pass manager run.
 >      ; CHECK-O2-NEXT: Running pass: CallSiteSplittingPass on foo
 >      ; CHECK-O2-NEXT: Running analysis: TargetLibraryAnalysis on foo
 >
 >     Modified: llvm/trunk/test/Other/new-pm-thinlto-defaults.ll
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-thinlto-defaults.ll?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/test/Other/new-pm-thinlto-defaults.ll (original)
 >     +++ llvm/trunk/test/Other/new-pm-thinlto-defaults.ll Thu Sep 20 
10:08:45 2018
 >     @@ -47,7 +47,8 @@
 >      ; RUN:     -passes='thinlto<O2>' -S  %s 2>&1 \
 >      ; RUN:     | FileCheck %s 
--check-prefixes=CHECK-O,CHECK-O2,CHECK-POSTLINK-O,CHECK-POSTLINK-O2
 >      ;
 >     -; CHECK-O: Starting llvm::Module pass manager run.
 >     +; CHECK-O: Running analysis: PassInstrumentationAnalysis
 >     +; CHECK-O-NEXT: Starting llvm::Module pass manager run.
 >      ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}>
 >      ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
 >      ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass
 >     @@ -64,6 +65,7 @@
 >      ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
 >      ; CHECK-O-NEXT: Running pass: 
ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
 >      ; CHECK-PRELINK-O-NODIS-NEXT: Running analysis: 
InnerAnalysisManagerProxy
 >     +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-O-NEXT: Starting llvm::Function pass manager run.
 >      ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 >      ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
 >     @@ -95,6 +97,7 @@
 >      ; CHECK-O-NEXT: Running pass: 
ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}>
 >      ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 >      ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
 >     +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-O-NEXT: Starting CGSCC pass manager run.
 >      ; CHECK-O-NEXT: Running pass: InlinerPass
 >      ; CHECK-O-NEXT: Running analysis: 
OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
 >     @@ -133,6 +136,7 @@
 >      ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis
 >      ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 >      ; CHECK-O-NEXT: Starting Loop pass manager run.
 >     +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 >      ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass
 >      ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass
 >      ; CHECK-O-NEXT: Running pass: LoopRotatePass
 >
 >     Modified: 
llvm/trunk/test/Transforms/Inline/cgscc-incremental-invalidate.ll
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/cgscc-incremental-invalidate.ll?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- 
llvm/trunk/test/Transforms/Inline/cgscc-incremental-invalidate.ll (original)
 >     +++ 
llvm/trunk/test/Transforms/Inline/cgscc-incremental-invalidate.ll Thu 
Sep 20 10:08:45 2018
 >     @@ -33,7 +33,8 @@
 >      ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_g
 >      ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_g
 >      ; CHECK-NEXT: Finished llvm::Function pass manager run.
 >     -; CHECK-NEXT: Starting llvm::Function pass manager run.
 >     +; CHECK-NOT: Invalidating analysis:
 >     +; CHECK: Starting llvm::Function pass manager run.
 >      ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_h
 >      ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_h
 >      ; CHECK-NEXT: Finished llvm::Function pass manager run.
 >
 >     Modified: llvm/trunk/test/Transforms/LoopRotate/pr35210.ll
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopRotate/pr35210.ll?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/test/Transforms/LoopRotate/pr35210.ll (original)
 >     +++ llvm/trunk/test/Transforms/LoopRotate/pr35210.ll Thu Sep 20 
10:08:45 2018
 >     @@ -21,6 +21,7 @@
 >      ; CHECK-NEXT: Running analysis: TargetIRAnalysis on f
 >      ; CHECK-NEXT: Running analysis: InnerAnalysisManagerProxy{{.*}} on f
 >      ; CHECK-NEXT: Starting Loop pass manager run.
 >     +; CHECK-NEXT: Running analysis: PassInstrumentationAnalysis on bb
 >      ; CHECK-NEXT: Running pass: LoopRotatePass on Loop at depth 1 
containing: %bb<header><exiting>,%bb4<latch>
 >      ; CHECK-NEXT: Folding loop latch bb4 into bb
 >      ; CHECK-NEXT: Invalidating all non-preserved analyses for: bb
 >
 >     Modified: llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp (original)
 >     +++ llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp Thu 
Sep 20 10:08:45 2018
 >     @@ -231,6 +231,13 @@ public:
 >          MAM.registerPass([&] { return TargetLibraryAnalysis(); });
 >          MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
 >          MAM.registerPass([&] { return 
FunctionAnalysisManagerModuleProxy(FAM); });
 >     +
 >     +    // Register required pass instrumentation analysis.
 >     +    MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >     +    CGAM.registerPass([&] { return 
PassInstrumentationAnalysis(); });
 >     +    FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >     +
 >     +    // Cross-register proxies.
 >          MAM.registerPass([&] { return 
CGSCCAnalysisManagerModuleProxy(CGAM); });
 >          CGAM.registerPass([&] { return 
FunctionAnalysisManagerCGSCCProxy(); });
 >          CGAM.registerPass([&] { return 
ModuleAnalysisManagerCGSCCProxy(MAM); });
 >
 >     Modified: llvm/trunk/unittests/IR/PassBuilderCallbacksTest.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PassBuilderCallbacksTest.cpp?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/unittests/IR/PassBuilderCallbacksTest.cpp (original)
 >     +++ llvm/trunk/unittests/IR/PassBuilderCallbacksTest.cpp Thu Sep 
20 10:08:45 2018
 >     @@ -7,14 +7,18 @@
 >      //
 > 
//===----------------------------------------------------------------------===//
 >
 >     +#include <functional>
 >      #include <gmock/gmock.h>
 >      #include <gtest/gtest.h>
 >     +#include <llvm/ADT/Any.h>
 >      #include <llvm/Analysis/CGSCCPassManager.h>
 >      #include <llvm/Analysis/LoopAnalysisManager.h>
 >      #include <llvm/AsmParser/Parser.h>
 >      #include <llvm/IR/LLVMContext.h>
 >     +#include <llvm/IR/PassInstrumentation.h>
 >      #include <llvm/IR/PassManager.h>
 >      #include <llvm/Passes/PassBuilder.h>
 >     +#include <llvm/Support/Regex.h>
 >      #include <llvm/Support/SourceMgr.h>
 >      #include <llvm/Transforms/Scalar/LoopPassManager.h>
 >
 >     @@ -32,7 +36,10 @@ static std::ostream &operator<<(std::ost
 >      }
 >
 >      namespace {
 >     +using testing::AnyNumber;
 >     +using testing::AtLeast;
 >      using testing::DoDefault;
 >     +using testing::Not;
 >      using testing::Return;
 >      using testing::Expectation;
 >      using testing::Invoke;
 >     @@ -87,6 +94,7 @@ public:
 >        typename Analysis::Result getResult() {
 >          return typename Analysis::Result(static_cast<DerivedT 
&>(*this));
 >        }
 >     +  static StringRef getName() { return 
llvm::getTypeName<DerivedT>(); }
 >
 >      protected:
 >        // FIXME: MSVC seems unable to handle a lambda argument to 
Invoke from within
 >     @@ -143,6 +151,8 @@ public:
 >          }
 >        };
 >
 >     +  static StringRef getName() { return 
llvm::getTypeName<DerivedT>(); }
 >     +
 >        Pass getPass() { return Pass(static_cast<DerivedT &>(*this)); }
 >
 >      protected:
 >     @@ -258,6 +268,81 @@ static std::unique_ptr<Module> parseIR(L
 >        return parseAssemblyString(IR, Err, C);
 >      }
 >
 >     +/// Helper for HasName matcher that returns getName both for 
IRUnit and
 >     +/// for IRUnit pointer wrapper into llvm::Any (wrapped by 
PassInstrumentation).
 >     +template <typename IRUnitT> std::string getName(const IRUnitT &IR) {
 >     +  return IR.getName();
 >     +}
 >     +
 >     +template <> std::string getName(const StringRef &name) { return 
name; }
 >     +
 >     +template <> std::string getName(const llvm::Any &WrappedIR) {
 >     +  if (any_isa<const Module *>(WrappedIR))
 >     +    return any_cast<const Module *>(WrappedIR)->getName().str();
 >     +  if (any_isa<const Function *>(WrappedIR))
 >     +    return any_cast<const Function *>(WrappedIR)->getName().str();
 >     +  if (any_isa<const Loop *>(WrappedIR))
 >     +    return any_cast<const Loop *>(WrappedIR)->getName().str();
 >     +  if (any_isa<const LazyCallGraph::SCC *>(WrappedIR))
 >     +    return any_cast<const LazyCallGraph::SCC 
*>(WrappedIR)->getName();
 >     +  return "<UNKNOWN>";
 >     +}
 >     +/// Define a custom matcher for objects which support a 
'getName' method.
 >     +///
 >     +/// LLVM often has IR objects or analysis objects which expose a 
name
 >     +/// and in tests it is convenient to match these by name for 
readability.
 >     +/// Usually, this name is either a StringRef or a plain 
std::string. This
 >     +/// matcher supports any type exposing a getName() method of 
this form whose
 >     +/// return value is compatible with an std::ostream. For 
StringRef, this uses
 >     +/// the shift operator defined above.
 >     +///
 >     +/// It should be used as:
 >     +///
 >     +///   HasName("my_function")
 >     +///
 >     +/// No namespace or other qualification is required.
 >     +MATCHER_P(HasName, Name, "") {
 >     +  *result_listener << "has name '" << getName(arg) << "'";
 >     +  return Name == getName(arg);
 >     +}
 >     +
 >     +MATCHER_P(HasNameRegex, Name, "") {
 >     +  *result_listener << "has name '" << getName(arg) << "'";
 >     +  llvm::Regex r(Name);
 >     +  return r.match(getName(arg));
 >     +}
 >     +
 >     +struct MockPassInstrumentationCallbacks {
 >     +  PassInstrumentationCallbacks Callbacks;
 >     +
 >     +  MockPassInstrumentationCallbacks() {
 >     +    ON_CALL(*this, runBeforePass(_, _)).WillByDefault(Return(true));
 >     +  }
 >     +  MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any));
 >     +  MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any));
 >     +
 >     +  void registerPassInstrumentation() {
 >     +    Callbacks.registerBeforePassCallback([this](StringRef P, 
llvm::Any IR) {
 >     +      return this->runBeforePass(P, IR);
 >     +    });
 >     +    Callbacks.registerAfterPassCallback(
 >     +        [this](StringRef P, llvm::Any IR) { 
this->runAfterPass(P, IR); });
 >     +  }
 >     +
 >     +  void ignoreNonMockPassInstrumentation(StringRef IRName) {
 >     +    // Generic EXPECT_CALLs are needed to match instrumentation 
on unimportant
 >     +    // parts of a pipeline that we do not care about (e.g. 
various passes added
 >     +    // by default by PassBuilder - Verifier pass etc).
 >     +    // Make sure to avoid ignoring Mock passes/analysis, we 
definitely want
 >     +    // to check these explicitly.
 >     +    EXPECT_CALL(*this,
 >     +                runBeforePass(Not(HasNameRegex("Mock")), 
HasName(IRName)))
 >     +        .Times(AnyNumber());
 >     +    EXPECT_CALL(*this, runAfterPass(Not(HasNameRegex("Mock")), 
HasName(IRName)))
 >     +        .Times(AnyNumber());
 >     +  }
 >     +};
 >     +
 >      template <typename PassManagerT> class PassBuilderCallbacksTest;
 >
 >      /// This test fixture is shared between all the actual tests 
below and
 >     @@ -280,6 +365,8 @@ protected:
 >        LLVMContext Context;
 >        std::unique_ptr<Module> M;
 >
 >     +  MockPassInstrumentationCallbacks CallbacksHandle;
 >     +
 >        PassBuilder PB;
 >        ModulePassManager PM;
 >        LoopAnalysisManager LAM;
 >     @@ -312,6 +399,7 @@ protected:
 >                        "exit:\n"
 >                        "  ret void\n"
 >                        "}\n")),
 >     +        CallbacksHandle(), PB(nullptr, None, 
&CallbacksHandle.Callbacks),
 >              PM(true), LAM(true), FAM(true), CGAM(true), AM(true) {
 >
 >          /// Register a callback for analysis registration.
 >     @@ -356,25 +444,6 @@ protected:
 >        }
 >      };
 >
 >     -/// Define a custom matcher for objects which support a 
'getName' method.
 >     -///
 >     -/// LLVM often has IR objects or analysis objects which expose a 
name
 >     -/// and in tests it is convenient to match these by name for 
readability.
 >     -/// Usually, this name is either a StringRef or a plain 
std::string. This
 >     -/// matcher supports any type exposing a getName() method of 
this form whose
 >     -/// return value is compatible with an std::ostream. For 
StringRef, this uses
 >     -/// the shift operator defined above.
 >     -///
 >     -/// It should be used as:
 >     -///
 >     -///   HasName("my_function")
 >     -///
 >     -/// No namespace or other qualification is required.
 >     -MATCHER_P(HasName, Name, "") {
 >     -  *result_listener << "has name '" << arg.getName() << "'";
 >     -  return Name == arg.getName();
 >     -}
 >     -
 >      using ModuleCallbacksTest = 
PassBuilderCallbacksTest<ModulePassManager>;
 >      using CGSCCCallbacksTest = 
PassBuilderCallbacksTest<CGSCCPassManager>;
 >      using FunctionCallbacksTest = 
PassBuilderCallbacksTest<FunctionPassManager>;
 >     @@ -391,6 +460,57 @@ TEST_F(ModuleCallbacksTest, Passes) {
 >        StringRef PipelineText = "test-transform";
 >        ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >            << "Pipeline was: " << PipelineText;
 >     +
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >     +TEST_F(ModuleCallbacksTest, InstrumentedPasses) {
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _));
 >     +  EXPECT_CALL(PassHandle, run(HasName("<string>"), _))
 >     +      .WillOnce(Invoke(getAnalysisResult));
 >     +
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation not specifically mentioned below 
can be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     +
 >     +  // PassInstrumentation calls should happen in-sequence, in the 
same order
 >     +  // as passes/analyses are scheduled.
 >     +  ::testing::Sequence PISequence;
 >     +  EXPECT_CALL(CallbacksHandle, 
runBeforePass(HasNameRegex("MockPassHandle"),
 >     + HasName("<string>")))
 >     +      .InSequence(PISequence);
 >     +  EXPECT_CALL(CallbacksHandle,
 >     +              runAfterPass(HasNameRegex("MockPassHandle"), 
HasName("<string>")))
 >     +      .InSequence(PISequence);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >     +TEST_F(ModuleCallbacksTest, InstrumentedSkippedPasses) {
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation run here can safely be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     +
 >     +  // Skip the pass by returning false.
 >     +  EXPECT_CALL(CallbacksHandle, 
runBeforePass(HasNameRegex("MockPassHandle"),
 >     + HasName("<string>")))
 >     +      .WillOnce(Return(false));
 >     +
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)).Times(0);
 >     +  EXPECT_CALL(PassHandle, run(HasName("<string>"), _)).Times(0);
 >     +
 >     +  // As the pass is skipped there is no afterPass as well.
 >     +  EXPECT_CALL(CallbacksHandle, 
runAfterPass(HasNameRegex("MockPassHandle"), _))
 >     +      .Times(0);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +
 >        PM.run(*M, AM);
 >      }
 >
 >     @@ -405,6 +525,56 @@ TEST_F(FunctionCallbacksTest, Passes) {
 >        PM.run(*M, AM);
 >      }
 >
 >     +TEST_F(FunctionCallbacksTest, InstrumentedPasses) {
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation not specifically mentioned below 
can be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     +  CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
 >     +
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _));
 >     +  EXPECT_CALL(PassHandle, run(HasName("foo"), _))
 >     +      .WillOnce(Invoke(getAnalysisResult));
 >     +
 >     +  // PassInstrumentation calls should happen in-sequence, in the 
same order
 >     +  // as passes/analyses are scheduled.
 >     +  ::testing::Sequence PISequence;
 >     +  EXPECT_CALL(CallbacksHandle,
 >     + runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")))
 >     +      .InSequence(PISequence);
 >     +  EXPECT_CALL(CallbacksHandle,
 >     +              runAfterPass(HasNameRegex("MockPassHandle"), 
HasName("foo")))
 >     +      .InSequence(PISequence);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >     +TEST_F(FunctionCallbacksTest, InstrumentedSkippedPasses) {
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation run here can safely be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     +  CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
 >     +
 >     +  // Skip the pass by returning false.
 >     +  EXPECT_CALL(CallbacksHandle,
 >     + runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")))
 >     +      .WillOnce(Return(false));
 >     +
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)).Times(0);
 >     +  EXPECT_CALL(PassHandle, run(HasName("foo"), _)).Times(0);
 >     +
 >     +  // As the pass is skipped there is no afterPass as well.
 >     +  EXPECT_CALL(CallbacksHandle, 
runAfterPass(HasNameRegex("MockPassHandle"), _))
 >     +      .Times(0);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >      TEST_F(LoopCallbacksTest, Passes) {
 >        EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _));
 >        EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _))
 >     @@ -416,6 +586,58 @@ TEST_F(LoopCallbacksTest, Passes) {
 >        PM.run(*M, AM);
 >      }
 >
 >     +TEST_F(LoopCallbacksTest, InstrumentedPasses) {
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation not specifically mentioned below 
can be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     +  CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("loop");
 >     +
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _));
 >     +  EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _))
 >     +      .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult)));
 >     +
 >     +  // PassInstrumentation calls should happen in-sequence, in the 
same order
 >     +  // as passes/analyses are scheduled.
 >     +  ::testing::Sequence PISequence;
 >     +  EXPECT_CALL(CallbacksHandle,
 >     + runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
 >     +      .InSequence(PISequence);
 >     +  EXPECT_CALL(CallbacksHandle,
 >     +              runAfterPass(HasNameRegex("MockPassHandle"), 
HasName("loop")))
 >     +      .InSequence(PISequence);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >     +TEST_F(LoopCallbacksTest, InstrumentedSkippedPasses) {
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation run here can safely be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     +  CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("loop");
 >     +
 >     +  // Skip the pass by returning false.
 >     +  EXPECT_CALL(CallbacksHandle,
 >     + runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
 >     +      .WillOnce(Return(false));
 >     +
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)).Times(0);
 >     +  EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)).Times(0);
 >     +
 >     +  // As the pass is skipped there is no afterPass as well.
 >     +  EXPECT_CALL(CallbacksHandle, 
runAfterPass(HasNameRegex("MockPassHandle"), _))
 >     +      .Times(0);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >      TEST_F(CGSCCCallbacksTest, Passes) {
 >        EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _));
 >        EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _))
 >     @@ -423,6 +645,57 @@ TEST_F(CGSCCCallbacksTest, Passes) {
 >
 >        StringRef PipelineText = "test-transform";
 >        ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >     +TEST_F(CGSCCCallbacksTest, InstrumentedPasses) {
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation not specifically mentioned below 
can be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)");
 >     +
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _));
 >     +  EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _))
 >     +      .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult)));
 >     +
 >     +  // PassInstrumentation calls should happen in-sequence, in the 
same order
 >     +  // as passes/analyses are scheduled.
 >     +  ::testing::Sequence PISequence;
 >     +  EXPECT_CALL(CallbacksHandle,
 >     + runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
 >     +      .InSequence(PISequence);
 >     +  EXPECT_CALL(CallbacksHandle,
 >     +              runAfterPass(HasNameRegex("MockPassHandle"), 
HasName("(foo)")))
 >     +      .InSequence(PISequence);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >     +      << "Pipeline was: " << PipelineText;
 >     +  PM.run(*M, AM);
 >     +}
 >     +
 >     +TEST_F(CGSCCCallbacksTest, InstrumentedSkippedPasses) {
 >     +  CallbacksHandle.registerPassInstrumentation();
 >     +  // Non-mock instrumentation run here can safely be ignored.
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
 >     + CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)");
 >     +
 >     +  // Skip the pass by returning false.
 >     +  EXPECT_CALL(CallbacksHandle,
 >     + runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
 >     +      .WillOnce(Return(false));
 >     +
 >     +  // neither Analysis nor Pass are called.
 >     +  EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)).Times(0);
 >     +  EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)).Times(0);
 >     +
 >     +  // As the pass is skipped there is no afterPass as well.
 >     +  EXPECT_CALL(CallbacksHandle, 
runAfterPass(HasNameRegex("MockPassHandle"), _))
 >     +      .Times(0);
 >     +
 >     +  StringRef PipelineText = "test-transform";
 >     +  ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
 >            << "Pipeline was: " << PipelineText;
 >        PM.run(*M, AM);
 >      }
 >
 >     Modified: llvm/trunk/unittests/IR/PassManagerTest.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PassManagerTest.cpp?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- llvm/trunk/unittests/IR/PassManagerTest.cpp (original)
 >     +++ llvm/trunk/unittests/IR/PassManagerTest.cpp Thu Sep 20 
10:08:45 2018
 >     @@ -406,6 +406,9 @@ TEST_F(PassManagerTest, Basic) {
 >        MAM.registerPass([&] { return 
FunctionAnalysisManagerModuleProxy(FAM); });
 >        FAM.registerPass([&] { return 
ModuleAnalysisManagerFunctionProxy(MAM); });
 >
 >     +  MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >     +  FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >     +
 >        ModulePassManager MPM;
 >
 >        // Count the runs over a Function.
 >     @@ -556,6 +559,8 @@ struct CustomizedPass : PassInfoMixin<Cu
 >      TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
 >        CustomizedAnalysisManager AM;
 >        AM.registerPass([&] { return CustomizedAnalysis(); });
 >     +  PassInstrumentationCallbacks PIC;
 >     +  AM.registerPass([&] { return 
PassInstrumentationAnalysis(&PIC); });
 >
 >        CustomizedPassManager PM;
 >
 >     @@ -688,6 +693,10 @@ TEST_F(PassManagerTest, IndirectAnalysis
 >        MAM.registerPass([&] { return 
FunctionAnalysisManagerModuleProxy(FAM); });
 >        FAM.registerPass([&] { return 
ModuleAnalysisManagerFunctionProxy(MAM); });
 >
 >     +  PassInstrumentationCallbacks PIC;
 >     +  MAM.registerPass([&] { return 
PassInstrumentationAnalysis(&PIC); });
 >     +  FAM.registerPass([&] { return 
PassInstrumentationAnalysis(&PIC); });
 >     +
 >        int InstrCount = 0, FunctionCount = 0;
 >        ModulePassManager MPM(/*DebugLogging*/ true);
 >        FunctionPassManager FPM(/*DebugLogging*/ true);
 >
 >     Modified: 
llvm/trunk/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
 >     URL: 
http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Scalar/LoopPassManagerTest.cpp?rev=342664&r1=342663&r2=342664&view=diff
 > 
==============================================================================
 >     --- 
llvm/trunk/unittests/Transforms/Scalar/LoopPassManagerTest.cpp (original)
 >     +++ 
llvm/trunk/unittests/Transforms/Scalar/LoopPassManagerTest.cpp Thu Sep 
20 10:08:45 2018
 >     @@ -308,6 +308,11 @@ public:
 >          FAM.registerPass([&] { return TargetLibraryAnalysis(); });
 >          FAM.registerPass([&] { return TargetIRAnalysis(); });
 >
 >     +    // Register required pass instrumentation analysis.
 >     +    LAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >     +    FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >     +    MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 >     +
 >          // Cross-register proxies.
 >          LAM.registerPass([&] { return 
FunctionAnalysisManagerLoopProxy(FAM); });
 >          FAM.registerPass([&] { return 
LoopAnalysisManagerFunctionProxy(LAM); });
 >
 >
 >     _______________________________________________
 >     llvm-commits mailing list
 >     llvm-commits at lists.llvm.org
 >     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
 >




More information about the llvm-commits mailing list