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

Fedor Sergeev via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 20 07:58:13 PDT 2018


Thanks for taking care of this.
It appeared to be unrelated to the llvm::Any, just inaccurate handling 
of StringRefs.

regards,
   Fedor.

On 09/20/2018 08:18 AM, Eric Christopher wrote:
> Reverted thusly:
>
> echristo at athyra ~/s/llvm> git svn dcommit
> Committing to https://llvm.org/svn/llvm-project/llvm/trunk ...
> Dinclude/llvm/IR/PassInstrumentation.h
> Dlib/IR/PassInstrumentation.cpp
> Minclude/llvm/Analysis/CGSCCPassManager.h
> Minclude/llvm/IR/PassManager.h
> Minclude/llvm/Passes/PassBuilder.h
> Minclude/llvm/Transforms/Scalar/LoopPassManager.h
> Mlib/Analysis/CGSCCPassManager.cpp
> Mlib/FuzzMutate/IRMutator.cpp
> Mlib/IR/CMakeLists.txt
> Mlib/Passes/PassRegistry.def
> Mlib/Transforms/Scalar/LoopPassManager.cpp
> Mtest/Other/loop-pm-invalidation.ll
> Mtest/Other/new-pass-manager.ll
> Mtest/Other/new-pm-defaults.ll
> Mtest/Other/new-pm-lto-defaults.ll
> Mtest/Other/new-pm-thinlto-defaults.ll
> Mtest/Transforms/Inline/cgscc-incremental-invalidate.ll
> Mtest/Transforms/LoopRotate/pr35210.ll
> Munittests/Analysis/CGSCCPassManagerTest.cpp
> Munittests/IR/PassBuilderCallbacksTest.cpp
> Munittests/IR/PassManagerTest.cpp
> Munittests/Transforms/Scalar/LoopPassManagerTest.cpp
> Committed r342616
>
> On Wed, Sep 19, 2018 at 10:08 PM Eric Christopher <echristo at gmail.com 
> <mailto:echristo at gmail.com>> wrote:
>
>     So it looks like this is causing issues in the asan buildbot:
>
>     http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/23878/steps/check-llvm%20asan/logs/stdio
>
>     (hack wasn't quite enough I'm guessing :)
>
>     I'm going to go ahead and revert and will reply with the reverted
>     revision. Sorry for the inconvenience!
>
>     Thanks!
>
>     -eric
>
>     On Wed, Sep 19, 2018 at 3:44 PM Fedor Sergeev via llvm-commits
>     <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>>
>     wrote:
>
>         Author: fedor.sergeev
>         Date: Wed Sep 19 15:42:57 2018
>         New Revision: 342597
>
>         URL: http://llvm.org/viewvc/llvm-project?rev=342597&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.
>
>         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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h (original)
>         +++ llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h Wed
>         Sep 19 15:42:57 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=342597&view=auto
>         ==============================================================================
>         --- llvm/trunk/include/llvm/IR/PassInstrumentation.h (added)
>         +++ llvm/trunk/include/llvm/IR/PassInstrumentation.h Wed Sep
>         19 15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/include/llvm/IR/PassManager.h (original)
>         +++ llvm/trunk/include/llvm/IR/PassManager.h Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/include/llvm/Passes/PassBuilder.h (original)
>         +++ llvm/trunk/include/llvm/Passes/PassBuilder.h Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         ---
>         llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h
>         (original)
>         +++
>         llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h
>         Wed Sep 19 15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/lib/Analysis/CGSCCPassManager.cpp (original)
>         +++ llvm/trunk/lib/Analysis/CGSCCPassManager.cpp Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/lib/FuzzMutate/IRMutator.cpp (original)
>         +++ llvm/trunk/lib/FuzzMutate/IRMutator.cpp Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/lib/IR/CMakeLists.txt (original)
>         +++ llvm/trunk/lib/IR/CMakeLists.txt Wed Sep 19 15:42:57 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=342597&view=auto
>         ==============================================================================
>         --- llvm/trunk/lib/IR/PassInstrumentation.cpp (added)
>         +++ llvm/trunk/lib/IR/PassInstrumentation.cpp Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/lib/Passes/PassRegistry.def (original)
>         +++ llvm/trunk/lib/Passes/PassRegistry.def Wed Sep 19 15:42:57
>         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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/lib/Transforms/Scalar/LoopPassManager.cpp
>         (original)
>         +++ llvm/trunk/lib/Transforms/Scalar/LoopPassManager.cpp Wed
>         Sep 19 15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/test/Other/loop-pm-invalidation.ll (original)
>         +++ llvm/trunk/test/Other/loop-pm-invalidation.ll Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/test/Other/new-pass-manager.ll (original)
>         +++ llvm/trunk/test/Other/new-pass-manager.ll Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/test/Other/new-pm-defaults.ll (original)
>         +++ llvm/trunk/test/Other/new-pm-defaults.ll Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/test/Other/new-pm-lto-defaults.ll (original)
>         +++ llvm/trunk/test/Other/new-pm-lto-defaults.ll Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/test/Other/new-pm-thinlto-defaults.ll (original)
>         +++ llvm/trunk/test/Other/new-pm-thinlto-defaults.ll Wed Sep
>         19 15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         ---
>         llvm/trunk/test/Transforms/Inline/cgscc-incremental-invalidate.ll
>         (original)
>         +++
>         llvm/trunk/test/Transforms/Inline/cgscc-incremental-invalidate.ll
>         Wed Sep 19 15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/test/Transforms/LoopRotate/pr35210.ll (original)
>         +++ llvm/trunk/test/Transforms/LoopRotate/pr35210.ll Wed Sep
>         19 15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp
>         (original)
>         +++ llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp Wed
>         Sep 19 15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/unittests/IR/PassBuilderCallbacksTest.cpp
>         (original)
>         +++ llvm/trunk/unittests/IR/PassBuilderCallbacksTest.cpp Wed
>         Sep 19 15:42:57 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> StringRef getName(const IRUnitT
>         &IR) {
>         +  return IR.getName();
>         +}
>         +
>         +template <> StringRef getName(const StringRef &name) { return
>         name; }
>         +
>         +template <> StringRef getName(const llvm::Any &WrappedIR) {
>         +  if (any_isa<const Module *>(WrappedIR))
>         +    return any_cast<const Module *>(WrappedIR)->getName();
>         +  if (any_isa<const Function *>(WrappedIR))
>         +    return any_cast<const Function *>(WrappedIR)->getName();
>         +  if (any_isa<const Loop *>(WrappedIR))
>         +    return any_cast<const Loop *>(WrappedIR)->getName();
>         +  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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         --- llvm/trunk/unittests/IR/PassManagerTest.cpp (original)
>         +++ llvm/trunk/unittests/IR/PassManagerTest.cpp Wed Sep 19
>         15:42:57 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=342597&r1=342596&r2=342597&view=diff
>         ==============================================================================
>         ---
>         llvm/trunk/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
>         (original)
>         +++
>         llvm/trunk/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
>         Wed Sep 19 15:42:57 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 <mailto:llvm-commits at lists.llvm.org>
>         http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180920/15a2f9e9/attachment-0001.html>


More information about the llvm-commits mailing list