<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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</blockquote></div></div>