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