diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1148,7 +1148,7 @@ PTO.Coroutines = LangOpts.Coroutines; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI; + StandardInstrumentations SI(CodeGenOpts.DebugPassManager); SI.registerCallbacks(PIC); PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC); diff --git a/llvm/include/llvm/Analysis/CGSCCPassManager.h b/llvm/include/llvm/Analysis/CGSCCPassManager.h --- a/llvm/include/llvm/Analysis/CGSCCPassManager.h +++ b/llvm/include/llvm/Analysis/CGSCCPassManager.h @@ -327,7 +327,8 @@ /// within this run safely. template class ModuleToPostOrderCGSCCPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin< + ModuleToPostOrderCGSCCPassAdaptor> { public: explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) : Pass(std::move(Pass)) {} @@ -444,7 +445,7 @@ /// within this run safely. template class CGSCCToFunctionPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h --- a/llvm/include/llvm/IR/PassInstrumentation.h +++ b/llvm/include/llvm/IR/PassInstrumentation.h @@ -75,7 +75,7 @@ // already invalidated IRUnit is unsafe. There are ways to handle invalidated IRUnits // in a safe way, and we might pursue that as soon as there is a useful instrumentation // that needs it. - using BeforePassFunc = bool(StringRef, Any); + using BeforePassFunc = bool(StringRef, bool, Any); using AfterPassFunc = void(StringRef, Any); using AfterPassInvalidatedFunc = void(StringRef); using BeforeAnalysisFunc = void(StringRef, Any); @@ -147,7 +147,7 @@ bool ShouldRun = true; for (auto &C : Callbacks->BeforePassCallbacks) - ShouldRun &= C(Pass.name(), llvm::Any(&IR)); + ShouldRun &= C(Pass.name(), Pass.isRequired(), llvm::Any(&IR)); return ShouldRun; } diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -370,6 +370,7 @@ /// passes. /// /// This provides some boilerplate for types that are passes. +/// Use this for optional (usually optimization) passes. template struct PassInfoMixin { /// Gets the name of the pass we are mixed into. static StringRef name() { @@ -380,6 +381,20 @@ Name = Name.drop_front(strlen("llvm::")); return Name; } + + /// This pass is not required to produce a valid executable. + /// Use RequiredPassInfoMixin for required passes. + static bool isRequired() { return false; } +}; + +/// A CRTP mix-in to automatically provide informational APIs needed for +/// passes. +/// +/// Use this for passes required to produce a valid executable. +template +struct RequiredPassInfoMixin : PassInfoMixin { + /// This pass is required to produce a valid executable. + static bool isRequired() { return true; } }; /// A CRTP mix-in that provides informational APIs needed for analysis passes. @@ -462,7 +477,7 @@ template , typename... ExtraArgTs> -class PassManager : public PassInfoMixin< +class PassManager : public RequiredPassInfoMixin< PassManager> { public: /// Construct a pass manager. @@ -1207,7 +1222,7 @@ /// may be stale. Function analyses will not be stale. template class ModuleToFunctionPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} diff --git a/llvm/include/llvm/IR/PassManagerInternal.h b/llvm/include/llvm/IR/PassManagerInternal.h --- a/llvm/include/llvm/IR/PassManagerInternal.h +++ b/llvm/include/llvm/IR/PassManagerInternal.h @@ -48,6 +48,11 @@ /// Polymorphic method to access the name of a pass. virtual StringRef name() const = 0; + + /// Whether or not this pass is required to create executable code. + /// + /// Used for optnone and opt-bisect. + virtual bool isRequired() const = 0; }; /// A template wrapper used to implement the polymorphic API. @@ -81,6 +86,8 @@ StringRef name() const override { return PassT::name(); } + bool isRequired() const override { return PassT::isRequired(); } + PassT Pass; }; diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -16,6 +16,7 @@ #define LLVM_PASSES_STANDARDINSTRUMENTATIONS_H #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PassTimingInfo.h" @@ -53,14 +54,27 @@ bool StoreModuleDesc = false; }; +class OptNoneInstrumentation { +public: + OptNoneInstrumentation(bool DebugPM) : DebugPM(DebugPM) {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); + +private: + bool skip(StringRef PassID, bool PassIsRequired, Any IR); + + bool DebugPM; +}; + /// This class provides an interface to register all the standard pass /// instrumentations and manages their state (if any). class StandardInstrumentations { PrintIRInstrumentation PrintIR; TimePassesHandler TimePasses; + OptNoneInstrumentation OptNone; public: - StandardInstrumentations() = default; + StandardInstrumentations(bool DebugPM) + : PrintIR(), TimePasses(), OptNone(DebugPM) {} void registerCallbacks(PassInstrumentationCallbacks &PIC); diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h --- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h +++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -229,7 +229,7 @@ /// LoopAnalysisManager to be used within this run safely. template class FunctionToLoopPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit FunctionToLoopPassAdaptor(LoopPassT Pass, bool UseMemorySSA = false, bool DebugLogging = false) diff --git a/llvm/lib/IR/PassTimingInfo.cpp b/llvm/lib/IR/PassTimingInfo.cpp --- a/llvm/lib/IR/PassTimingInfo.cpp +++ b/llvm/lib/IR/PassTimingInfo.cpp @@ -270,8 +270,9 @@ if (!Enabled) return; - PIC.registerBeforePassCallback( - [this](StringRef P, Any) { return this->runBeforePass(P); }); + PIC.registerBeforePassCallback([this](StringRef P, bool PassIsRequired, Any) { + return this->runBeforePass(P); + }); PIC.registerAfterPassCallback( [this](StringRef P, Any) { this->runAfterPass(P); }); PIC.registerAfterPassInvalidatedCallback( diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -197,7 +197,7 @@ } PassInstrumentationCallbacks PIC; - StandardInstrumentations SI; + StandardInstrumentations SI(Conf.DebugPassManager); SI.registerCallbacks(PIC); PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC); AAManager AA; diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Passes/StandardInstrumentations.h" +#include "llvm/ADT/Any.h" #include "llvm/ADT/Optional.h" #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LazyCallGraph.h" @@ -21,12 +22,20 @@ #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassInstrumentation.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +// TODO: remove once all required passes are marked as such. +static cl::opt + EnableOptnone("enable-npm-optnone", cl::init(false), + cl::desc("Enable skipping optional passes optnone functions " + "under new pass manager")); + namespace { /// Extracting Module out of \p IR unit. Also fills a textual description @@ -233,7 +242,9 @@ StoreModuleDesc = llvm::forcePrintModuleIR() && llvm::shouldPrintAfterPass(); if (llvm::shouldPrintBeforePass() || StoreModuleDesc) PIC.registerBeforePassCallback( - [this](StringRef P, Any IR) { return this->printBeforePass(P, IR); }); + [this](StringRef P, bool PassIsRequired, Any IR) { + return this->printBeforePass(P, IR); + }); if (llvm::shouldPrintAfterPass()) { PIC.registerAfterPassCallback( @@ -243,8 +254,38 @@ } } +void OptNoneInstrumentation::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + PIC.registerBeforePassCallback( + [this](StringRef P, bool PassIsRequired, Any IR) { + return this->skip(P, PassIsRequired, IR); + }); +} + +bool OptNoneInstrumentation::skip(StringRef PassID, bool PassIsRequired, + Any IR) { + if (!EnableOptnone) + return true; + const Function *F = nullptr; + if (any_isa(IR)) { + F = any_cast(IR); + } else if (any_isa(IR)) { + F = any_cast(IR)->getHeader()->getParent(); + } + if (F) { + bool HasOptNone = F->hasOptNone(); + if (HasOptNone && !PassIsRequired) { + if (DebugPM) + dbgs() << "Skipping pass: " << PassID << " (optnone)\n"; + return false; + } + } + return true; +} + void StandardInstrumentations::registerCallbacks( PassInstrumentationCallbacks &PIC) { PrintIR.registerCallbacks(PIC); TimePasses.registerCallbacks(PIC); + OptNone.registerCallbacks(PIC); } diff --git a/llvm/test/Feature/optnone-opt.ll b/llvm/test/Feature/optnone-opt.ll --- a/llvm/test/Feature/optnone-opt.ll +++ b/llvm/test/Feature/optnone-opt.ll @@ -1,9 +1,15 @@ -; RUN: opt -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O0 -; RUN: opt -O1 -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O1 -; RUN: opt -O2 -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O1 --check-prefix=OPT-O2O3 -; RUN: opt -O3 -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O1 --check-prefix=OPT-O2O3 -; RUN: opt -dce -die -gvn-hoist -loweratomic -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-MORE -; RUN: opt -indvars -licm -loop-deletion -loop-extract -loop-idiom -loop-instsimplify -loop-reduce -loop-reroll -loop-rotate -loop-unroll -loop-unswitch -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-LOOP +; RUN: opt -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O0 +; RUN: opt -O1 -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O1 +; RUN: opt -O2 -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O1 --check-prefix=O2O3 +; RUN: opt -O3 -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O1 --check-prefix=O2O3 +; RUN: opt -dce -die -gvn-hoist -loweratomic -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=MORE +; RUN: opt -indvars -licm -loop-deletion -loop-extract -loop-idiom -loop-instsimplify -loop-reduce -loop-reroll -loop-rotate -loop-unroll -loop-unswitch -enable-new-pm=0 -S -debug %s 2>&1 | FileCheck %s --check-prefix=LOOP +; RUN: opt -enable-npm-optnone -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O0 +; RUN: opt -enable-npm-optnone -O1 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 +; RUN: opt -enable-npm-optnone -O2 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3 +; RUN: opt -enable-npm-optnone -O3 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3 +; RUN: opt -enable-npm-optnone -dce -gvn-hoist -loweratomic -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-MORE +; RUN: opt -enable-npm-optnone -indvars -licm -loop-deletion -loop-idiom -loop-instsimplify -loop-reduce -loop-unroll -simple-loop-unswitch -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-LOOP ; REQUIRES: asserts @@ -34,32 +40,53 @@ attributes #0 = { optnone noinline } ; Nothing that runs at -O0 gets skipped. -; OPT-O0-NOT: Skipping pass +; O0-NOT: Skipping pass +; NPM-O0-NOT: Skipping pass ; IR passes run at -O1 and higher. -; OPT-O1-DAG: Skipping pass 'Aggressive Dead Code Elimination' -; OPT-O1-DAG: Skipping pass 'Combine redundant instructions' -; OPT-O1-DAG: Skipping pass 'Early CSE' -; OPT-O1-DAG: Skipping pass 'Reassociate expressions' -; OPT-O1-DAG: Skipping pass 'Simplify the CFG' -; OPT-O1-DAG: Skipping pass 'Sparse Conditional Constant Propagation' +; O1-DAG: Skipping pass 'Aggressive Dead Code Elimination' +; O1-DAG: Skipping pass 'Combine redundant instructions' +; O1-DAG: Skipping pass 'Early CSE' +; O1-DAG: Skipping pass 'Reassociate expressions' +; O1-DAG: Skipping pass 'Simplify the CFG' +; O1-DAG: Skipping pass 'Sparse Conditional Constant Propagation' +; NPM-O1-DAG: Skipping pass: SimplifyCFGPass +; NPM-O1-DAG: Skipping pass: SROA +; NPM-O1-DAG: Skipping pass: EarlyCSEPass +; NPM-O1-DAG: Skipping pass: LowerExpectIntrinsicPass +; NPM-O1-DAG: Skipping pass: PromotePass +; NPM-O1-DAG: Skipping pass: InstCombinePass ; Additional IR passes run at -O2 and higher. -; OPT-O2O3-DAG: Skipping pass 'Global Value Numbering' -; OPT-O2O3-DAG: Skipping pass 'SLP Vectorizer' +; O2O3-DAG: Skipping pass 'Global Value Numbering' +; O2O3-DAG: Skipping pass 'SLP Vectorizer' +; NPM-O2O3-DAG: Skipping pass: GVN +; NPM-O2O3-DAG: Skipping pass: SLPVectorizerPass ; Additional IR passes that opt doesn't turn on by default. -; OPT-MORE-DAG: Skipping pass 'Dead Code Elimination' -; OPT-MORE-DAG: Skipping pass 'Dead Instruction Elimination' +; MORE-DAG: Skipping pass 'Dead Code Elimination' +; MORE-DAG: Skipping pass 'Dead Instruction Elimination' +; NPM-MORE-DAG: Skipping pass: GVNHoistPass +; NPM-MORE-DAG: Skipping pass: LowerAtomicPass ; Loop IR passes that opt doesn't turn on by default. -; OPT-LOOP-DAG: Skipping pass 'Delete dead loops' -; OPT-LOOP-DAG: Skipping pass 'Induction Variable Simplification' -; OPT-LOOP-DAG: Skipping pass 'Loop Invariant Code Motion' -; OPT-LOOP-DAG: Skipping pass 'Loop Strength Reduction' -; OPT-LOOP-DAG: Skipping pass 'Recognize loop idioms' -; OPT-LOOP-DAG: Skipping pass 'Reroll loops' -; OPT-LOOP-DAG: Skipping pass 'Rotate Loops' -; OPT-LOOP-DAG: Skipping pass 'Simplify instructions in loops' -; OPT-LOOP-DAG: Skipping pass 'Unroll loops' -; OPT-LOOP-DAG: Skipping pass 'Unswitch loops' +; LOOP-DAG: Skipping pass 'Delete dead loops' +; LOOP-DAG: Skipping pass 'Induction Variable Simplification' +; LOOP-DAG: Skipping pass 'Loop Invariant Code Motion' +; LOOP-DAG: Skipping pass 'Loop Strength Reduction' +; LOOP-DAG: Skipping pass 'Recognize loop idioms' +; LOOP-DAG: Skipping pass 'Reroll loops' +; LOOP-DAG: Skipping pass 'Rotate Loops' +; LOOP-DAG: Skipping pass 'Simplify instructions in loops' +; LOOP-DAG: Skipping pass 'Unroll loops' +; LOOP-DAG: Skipping pass 'Unswitch loops' +; NPM-LOOP-DAG: Skipping pass: LoopSimplifyPass +; NPM-LOOP-DAG: Skipping pass: LCSSAPass +; NPM-LOOP-DAG: Skipping pass: IndVarSimplifyPass +; NPM-LOOP-DAG: Skipping pass: SimpleLoopUnswitchPass +; NPM-LOOP-DAG: Skipping pass: LoopUnrollPass +; NPM-LOOP-DAG: Skipping pass: LoopStrengthReducePass +; NPM-LOOP-DAG: Skipping pass: LoopDeletionPass +; NPM-LOOP-DAG: Skipping pass: LICMPass +; NPM-LOOP-DAG: Skipping pass: LoopIdiomRecognizePass +; NPM-LOOP-DAG: Skipping pass: LoopInstSimplifyPass diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -260,7 +260,7 @@ } } PassInstrumentationCallbacks PIC; - StandardInstrumentations SI; + StandardInstrumentations SI(DebugPM); SI.registerCallbacks(PIC); PipelineTuningOptions PTO; diff --git a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp --- a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp +++ b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp @@ -317,18 +317,20 @@ PassInstrumentationCallbacks Callbacks; MockPassInstrumentationCallbacks() { - ON_CALL(*this, runBeforePass(_, _)).WillByDefault(Return(true)); + ON_CALL(*this, runBeforePass(_, _, _)).WillByDefault(Return(true)); } - MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any)); + MOCK_METHOD3(runBeforePass, + bool(StringRef PassID, bool PassIsRequired, llvm::Any)); MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any)); MOCK_METHOD1(runAfterPassInvalidated, void(StringRef PassID)); MOCK_METHOD2(runBeforeAnalysis, void(StringRef PassID, llvm::Any)); MOCK_METHOD2(runAfterAnalysis, void(StringRef PassID, llvm::Any)); void registerPassInstrumentation() { - Callbacks.registerBeforePassCallback([this](StringRef P, llvm::Any IR) { - return this->runBeforePass(P, IR); - }); + Callbacks.registerBeforePassCallback( + [this](StringRef P, bool PassIsRequired, llvm::Any IR) { + return this->runBeforePass(P, PassIsRequired, IR); + }); Callbacks.registerAfterPassCallback( [this](StringRef P, llvm::Any IR) { this->runAfterPass(P, IR); }); Callbacks.registerAfterPassInvalidatedCallback( @@ -347,7 +349,7 @@ // Make sure to avoid ignoring Mock passes/analysis, we definitely want // to check these explicitly. EXPECT_CALL(*this, - runBeforePass(Not(HasNameRegex("Mock")), HasName(IRName))) + runBeforePass(Not(HasNameRegex("Mock")), _, HasName(IRName))) .Times(AnyNumber()); EXPECT_CALL(*this, runAfterPass(Not(HasNameRegex("Mock")), HasName(IRName))) .Times(AnyNumber()); @@ -497,7 +499,7 @@ // PassInstrumentation calls should happen in-sequence, in the same order // as passes/analyses are scheduled. ::testing::Sequence PISequence; - EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), + EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), _, HasName(""))) .InSequence(PISequence); EXPECT_CALL(CallbacksHandle, @@ -525,7 +527,7 @@ CallbacksHandle.ignoreNonMockPassInstrumentation(""); // Skip the pass by returning false. - EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), + EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), _, HasName(""))) .WillOnce(Return(false)); @@ -575,7 +577,7 @@ // as passes/analyses are scheduled. ::testing::Sequence PISequence; EXPECT_CALL(CallbacksHandle, - runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo"))) + runBeforePass(HasNameRegex("MockPassHandle"), _, HasName("foo"))) .InSequence(PISequence); EXPECT_CALL( CallbacksHandle, @@ -608,7 +610,7 @@ // Skip the pass by returning false. EXPECT_CALL(CallbacksHandle, - runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo"))) + runBeforePass(HasNameRegex("MockPassHandle"), _, HasName("foo"))) .WillOnce(Return(false)); EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)).Times(0); @@ -662,7 +664,7 @@ // as passes/analyses are scheduled. ::testing::Sequence PISequence; EXPECT_CALL(CallbacksHandle, - runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop"))) + runBeforePass(HasNameRegex("MockPassHandle"), _, HasName("loop"))) .InSequence(PISequence); EXPECT_CALL( CallbacksHandle, @@ -703,7 +705,7 @@ // as passes/analyses are scheduled. ::testing::Sequence PISequence; EXPECT_CALL(CallbacksHandle, - runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop"))) + runBeforePass(HasNameRegex("MockPassHandle"), _, HasName("loop"))) .InSequence(PISequence); EXPECT_CALL( CallbacksHandle, @@ -740,7 +742,7 @@ // Skip the pass by returning false. EXPECT_CALL(CallbacksHandle, - runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop"))) + runBeforePass(HasNameRegex("MockPassHandle"), _, HasName("loop"))) .WillOnce(Return(false)); EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)).Times(0); @@ -791,8 +793,8 @@ // 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)"))) + EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), _, + HasName("(foo)"))) .InSequence(PISequence); EXPECT_CALL( CallbacksHandle, @@ -832,8 +834,8 @@ // 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)"))) + EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), _, + HasName("(foo)"))) .InSequence(PISequence); EXPECT_CALL( CallbacksHandle, @@ -869,8 +871,8 @@ CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)"); // Skip the pass by returning false. - EXPECT_CALL(CallbacksHandle, - runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)"))) + EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"), _, + HasName("(foo)"))) .WillOnce(Return(false)); // neither Analysis nor Pass are called. diff --git a/polly/include/polly/ScopPass.h b/polly/include/polly/ScopPass.h --- a/polly/include/polly/ScopPass.h +++ b/polly/include/polly/ScopPass.h @@ -204,7 +204,7 @@ template class FunctionToScopPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit FunctionToScopPassAdaptor(ScopPassT Pass) : Pass(std::move(Pass)) {}