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