Index: include/llvm/Testing/IR/Passes.h =================================================================== --- /dev/null +++ include/llvm/Testing/IR/Passes.h @@ -0,0 +1,241 @@ +#ifndef LLVM_TESTING_IR_PASSES_H +#define LLVM_TESTING_IR_PASSES_H +#include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Transforms/Scalar/LoopPassManager.h" + +// Workaround for the gcc 7.1 bug PR80916. +#if defined(__GNUC__) && __GNUC__ > 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#if defined(__GNUC__) && __GNUC__ > 6 +#pragma GCC diagnostic pop +#endif + +namespace llvm { +using ::testing::Return; +using ::testing::Invoke; +using ::testing::_; + +/// \brief A CRTP base for analysis mock handles +/// +/// This class reconciles mocking with the value semantics implementation of +/// the +/// AnalysisManager. Analysis mock handles should derive from this class and +/// call \c setDefault() in their constroctur for wiring up the defaults +/// defined +/// by this base with their mock run() and invalidate() implementations. +template , + typename... ExtraArgTs> +class MockAnalysisHandleBase { +public: + class Analysis : public AnalysisInfoMixin { + friend AnalysisInfoMixin; + friend MockAnalysisHandleBase; + static AnalysisKey Key; + + DerivedT *Handle; + + Analysis(DerivedT &Handle) : Handle(&Handle) { + static_assert(std::is_base_of::value, + "Must pass the derived type to this template!"); + } + + public: + class Result { + friend MockAnalysisHandleBase; + + DerivedT *Handle; + + Result(DerivedT &Handle) : Handle(&Handle) {} + + public: + // Forward invalidation events to the mock handle. + bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA, + typename AnalysisManagerT::Invalidator &Inv) { + return Handle->invalidate(IR, PA, Inv); + } + }; + + Result run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) { + return Handle->run(IR, AM, ExtraArgs...); + } + }; + + Analysis getAnalysis() { return Analysis(static_cast(*this)); } + typename Analysis::Result getResult() { + return typename Analysis::Result(static_cast(*this)); + } + +protected: + // FIXME: MSVC seems unable to handle a lambda argument to Invoke from within + // the template, so we use a boring static function. + static bool invalidateCallback(IRUnitT &IR, const PreservedAnalyses &PA, + typename AnalysisManagerT::Invalidator &Inv) { + auto PAC = PA.template getChecker(); + return !PAC.preserved() && + !PAC.template preservedSet>(); + } + + /// Derived classes should call this in their constructor to set up default + /// mock actions. (We can't do this in our constructor because this has to + /// run after the DerivedT is constructed.) + void setDefaults() { + ON_CALL(static_cast(*this), + run(_, _, testing::Matcher(_)...)) + .WillByDefault(Return(this->getResult())); + ON_CALL(static_cast(*this), invalidate(_, _, _)) + .WillByDefault(Invoke(&invalidateCallback)); + } +}; + +/// \brief A CRTP base for pass mock handles +/// +/// This class reconciles mocking with the value semantics implementation of the +/// PassManager. Pass mock handles should derive from this class and +/// call \c setDefault() in their constroctur for wiring up the defaults defined +/// by this base with their mock run() and invalidate() implementations. +template +AnalysisKey MockAnalysisHandleBase::Analysis::Key; + +template , + typename... ExtraArgTs> +class MockPassHandleBase { +public: + class Pass : public PassInfoMixin { + friend MockPassHandleBase; + + DerivedT *Handle; + + Pass(DerivedT &Handle) : Handle(&Handle) { + static_assert(std::is_base_of::value, + "Must pass the derived type to this template!"); + } + + public: + PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, + ExtraArgTs... ExtraArgs) { + return Handle->run(IR, AM, ExtraArgs...); + } + }; + + Pass getPass() { return Pass(static_cast(*this)); } + +protected: + /// Derived classes should call this in their constructor to set up default + /// mock actions. (We can't do this in our constructor because this has to + /// run after the DerivedT is constructed.) + void setDefaults() { + ON_CALL(static_cast(*this), + run(_, _, testing::Matcher(_)...)) + .WillByDefault(Return(PreservedAnalyses::all())); + } +}; + +/// Mock handles for passes for the IRUnits Module, CGSCC, Function, Loop. +/// These handles define the appropriate run() mock interface for the respective +/// IRUnit type. +template struct MockPassHandle; +template <> +struct MockPassHandle + : MockPassHandleBase, Loop, LoopAnalysisManager, + LoopStandardAnalysisResults &, LPMUpdater &> { + MOCK_METHOD4(run, + PreservedAnalyses(Loop &, LoopAnalysisManager &, + LoopStandardAnalysisResults &, LPMUpdater &)); + MockPassHandle() { setDefaults(); } +}; + +template <> +struct MockPassHandle + : MockPassHandleBase, Function> { + MOCK_METHOD2(run, PreservedAnalyses(Function &, FunctionAnalysisManager &)); + + MockPassHandle() { setDefaults(); } +}; + +template <> +struct MockPassHandle + : MockPassHandleBase, LazyCallGraph::SCC, + CGSCCAnalysisManager, LazyCallGraph &, + CGSCCUpdateResult &> { + MOCK_METHOD4(run, + PreservedAnalyses(LazyCallGraph::SCC &, CGSCCAnalysisManager &, + LazyCallGraph &G, CGSCCUpdateResult &UR)); + + MockPassHandle() { setDefaults(); } +}; + +template <> +struct MockPassHandle + : MockPassHandleBase, Module> { + MOCK_METHOD2(run, PreservedAnalyses(Module &, ModuleAnalysisManager &)); + + MockPassHandle() { setDefaults(); } +}; + +/// Mock handles for analyses for the IRUnits Module, CGSCC, Function, Loop. +/// These handles define the appropriate run() and invalidate() mock interfaces +/// for the respective IRUnit type. +template struct MockAnalysisHandle; +template <> +struct MockAnalysisHandle + : MockAnalysisHandleBase, Loop, + LoopAnalysisManager, + LoopStandardAnalysisResults &> { + + MOCK_METHOD3_T(run, typename Analysis::Result(Loop &, LoopAnalysisManager &, + LoopStandardAnalysisResults &)); + + MOCK_METHOD3_T(invalidate, bool(Loop &, const PreservedAnalyses &, + LoopAnalysisManager::Invalidator &)); + + MockAnalysisHandle() { this->setDefaults(); } +}; + +template <> +struct MockAnalysisHandle + : MockAnalysisHandleBase, Function> { + MOCK_METHOD2(run, Analysis::Result(Function &, FunctionAnalysisManager &)); + + MOCK_METHOD3(invalidate, bool(Function &, const PreservedAnalyses &, + FunctionAnalysisManager::Invalidator &)); + + MockAnalysisHandle() { setDefaults(); } +}; + +template <> +struct MockAnalysisHandle + : MockAnalysisHandleBase, + LazyCallGraph::SCC, CGSCCAnalysisManager, + LazyCallGraph &> { + MOCK_METHOD3(run, Analysis::Result(LazyCallGraph::SCC &, + CGSCCAnalysisManager &, LazyCallGraph &)); + + MOCK_METHOD3(invalidate, bool(LazyCallGraph::SCC &, const PreservedAnalyses &, + CGSCCAnalysisManager::Invalidator &)); + + MockAnalysisHandle() { setDefaults(); } +}; + +template <> +struct MockAnalysisHandle + : MockAnalysisHandleBase, Module> { + MOCK_METHOD2(run, Analysis::Result(Module &, ModuleAnalysisManager &)); + + MOCK_METHOD3(invalidate, bool(Module &, const PreservedAnalyses &, + ModuleAnalysisManager::Invalidator &)); + + MockAnalysisHandle() { setDefaults(); } +}; +} +#endif /* LLVM_TESTING_IR_PASSES_H */ Index: unittests/IR/PassBuilderCallbacksTest.cpp =================================================================== --- unittests/IR/PassBuilderCallbacksTest.cpp +++ unittests/IR/PassBuilderCallbacksTest.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include using namespace llvm; @@ -39,220 +40,6 @@ using testing::WithArgs; using testing::_; -/// \brief A CRTP base for analysis mock handles -/// -/// This class reconciles mocking with the value semantics implementation of the -/// AnalysisManager. Analysis mock handles should derive from this class and -/// call \c setDefault() in their constroctur for wiring up the defaults defined -/// by this base with their mock run() and invalidate() implementations. -template , - typename... ExtraArgTs> -class MockAnalysisHandleBase { -public: - class Analysis : public AnalysisInfoMixin { - friend AnalysisInfoMixin; - friend MockAnalysisHandleBase; - static AnalysisKey Key; - - DerivedT *Handle; - - Analysis(DerivedT &Handle) : Handle(&Handle) { - static_assert(std::is_base_of::value, - "Must pass the derived type to this template!"); - } - - public: - class Result { - friend MockAnalysisHandleBase; - - DerivedT *Handle; - - Result(DerivedT &Handle) : Handle(&Handle) {} - - public: - // Forward invalidation events to the mock handle. - bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA, - typename AnalysisManagerT::Invalidator &Inv) { - return Handle->invalidate(IR, PA, Inv); - } - }; - - Result run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) { - return Handle->run(IR, AM, ExtraArgs...); - } - }; - - Analysis getAnalysis() { return Analysis(static_cast(*this)); } - typename Analysis::Result getResult() { - return typename Analysis::Result(static_cast(*this)); - } - -protected: - // FIXME: MSVC seems unable to handle a lambda argument to Invoke from within - // the template, so we use a boring static function. - static bool invalidateCallback(IRUnitT &IR, const PreservedAnalyses &PA, - typename AnalysisManagerT::Invalidator &Inv) { - auto PAC = PA.template getChecker(); - return !PAC.preserved() && - !PAC.template preservedSet>(); - } - - /// Derived classes should call this in their constructor to set up default - /// mock actions. (We can't do this in our constructor because this has to - /// run after the DerivedT is constructed.) - void setDefaults() { - ON_CALL(static_cast(*this), - run(_, _, testing::Matcher(_)...)) - .WillByDefault(Return(this->getResult())); - ON_CALL(static_cast(*this), invalidate(_, _, _)) - .WillByDefault(Invoke(&invalidateCallback)); - } -}; - -/// \brief A CRTP base for pass mock handles -/// -/// This class reconciles mocking with the value semantics implementation of the -/// PassManager. Pass mock handles should derive from this class and -/// call \c setDefault() in their constroctur for wiring up the defaults defined -/// by this base with their mock run() and invalidate() implementations. -template -AnalysisKey MockAnalysisHandleBase::Analysis::Key; - -template , - typename... ExtraArgTs> -class MockPassHandleBase { -public: - class Pass : public PassInfoMixin { - friend MockPassHandleBase; - - DerivedT *Handle; - - Pass(DerivedT &Handle) : Handle(&Handle) { - static_assert(std::is_base_of::value, - "Must pass the derived type to this template!"); - } - - public: - PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, - ExtraArgTs... ExtraArgs) { - return Handle->run(IR, AM, ExtraArgs...); - } - }; - - Pass getPass() { return Pass(static_cast(*this)); } - -protected: - /// Derived classes should call this in their constructor to set up default - /// mock actions. (We can't do this in our constructor because this has to - /// run after the DerivedT is constructed.) - void setDefaults() { - ON_CALL(static_cast(*this), - run(_, _, testing::Matcher(_)...)) - .WillByDefault(Return(PreservedAnalyses::all())); - } -}; - -/// Mock handles for passes for the IRUnits Module, CGSCC, Function, Loop. -/// These handles define the appropriate run() mock interface for the respective -/// IRUnit type. -template struct MockPassHandle; -template <> -struct MockPassHandle - : MockPassHandleBase, Loop, LoopAnalysisManager, - LoopStandardAnalysisResults &, LPMUpdater &> { - MOCK_METHOD4(run, - PreservedAnalyses(Loop &, LoopAnalysisManager &, - LoopStandardAnalysisResults &, LPMUpdater &)); - MockPassHandle() { setDefaults(); } -}; - -template <> -struct MockPassHandle - : MockPassHandleBase, Function> { - MOCK_METHOD2(run, PreservedAnalyses(Function &, FunctionAnalysisManager &)); - - MockPassHandle() { setDefaults(); } -}; - -template <> -struct MockPassHandle - : MockPassHandleBase, LazyCallGraph::SCC, - CGSCCAnalysisManager, LazyCallGraph &, - CGSCCUpdateResult &> { - MOCK_METHOD4(run, - PreservedAnalyses(LazyCallGraph::SCC &, CGSCCAnalysisManager &, - LazyCallGraph &G, CGSCCUpdateResult &UR)); - - MockPassHandle() { setDefaults(); } -}; - -template <> -struct MockPassHandle - : MockPassHandleBase, Module> { - MOCK_METHOD2(run, PreservedAnalyses(Module &, ModuleAnalysisManager &)); - - MockPassHandle() { setDefaults(); } -}; - -/// Mock handles for analyses for the IRUnits Module, CGSCC, Function, Loop. -/// These handles define the appropriate run() and invalidate() mock interfaces -/// for the respective IRUnit type. -template struct MockAnalysisHandle; -template <> -struct MockAnalysisHandle - : MockAnalysisHandleBase, Loop, - LoopAnalysisManager, - LoopStandardAnalysisResults &> { - - MOCK_METHOD3_T(run, typename Analysis::Result(Loop &, LoopAnalysisManager &, - LoopStandardAnalysisResults &)); - - MOCK_METHOD3_T(invalidate, bool(Loop &, const PreservedAnalyses &, - LoopAnalysisManager::Invalidator &)); - - MockAnalysisHandle() { this->setDefaults(); } -}; - -template <> -struct MockAnalysisHandle - : MockAnalysisHandleBase, Function> { - MOCK_METHOD2(run, Analysis::Result(Function &, FunctionAnalysisManager &)); - - MOCK_METHOD3(invalidate, bool(Function &, const PreservedAnalyses &, - FunctionAnalysisManager::Invalidator &)); - - MockAnalysisHandle() { setDefaults(); } -}; - -template <> -struct MockAnalysisHandle - : MockAnalysisHandleBase, - LazyCallGraph::SCC, CGSCCAnalysisManager, - LazyCallGraph &> { - MOCK_METHOD3(run, Analysis::Result(LazyCallGraph::SCC &, - CGSCCAnalysisManager &, LazyCallGraph &)); - - MOCK_METHOD3(invalidate, bool(LazyCallGraph::SCC &, const PreservedAnalyses &, - CGSCCAnalysisManager::Invalidator &)); - - MockAnalysisHandle() { setDefaults(); } -}; - -template <> -struct MockAnalysisHandle - : MockAnalysisHandleBase, Module> { - MOCK_METHOD2(run, Analysis::Result(Module &, ModuleAnalysisManager &)); - - MOCK_METHOD3(invalidate, bool(Module &, const PreservedAnalyses &, - ModuleAnalysisManager::Invalidator &)); - - MockAnalysisHandle() { setDefaults(); } -}; - static std::unique_ptr parseIR(LLVMContext &C, const char *IR) { SMDiagnostic Err; return parseAssemblyString(IR, Err, C); Index: unittests/Transforms/Scalar/LoopPassManagerTest.cpp =================================================================== --- unittests/Transforms/Scalar/LoopPassManagerTest.cpp +++ unittests/Transforms/Scalar/LoopPassManagerTest.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Testing/IR/Passes.h" // Workaround for the gcc 7.1 bug PR80916. #if defined(__GNUC__) && __GNUC__ > 6 @@ -45,76 +46,6 @@ using testing::InvokeWithoutArgs; using testing::_; -template , - typename... ExtraArgTs> -class MockAnalysisHandleBase { -public: - class Analysis : public AnalysisInfoMixin { - friend AnalysisInfoMixin; - friend MockAnalysisHandleBase; - static AnalysisKey Key; - - DerivedT *Handle; - - Analysis(DerivedT &Handle) : Handle(&Handle) { - static_assert(std::is_base_of::value, - "Must pass the derived type to this template!"); - } - - public: - class Result { - friend MockAnalysisHandleBase; - - DerivedT *Handle; - - Result(DerivedT &Handle) : Handle(&Handle) {} - - public: - // Forward invalidation events to the mock handle. - bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA, - typename AnalysisManagerT::Invalidator &Inv) { - return Handle->invalidate(IR, PA, Inv); - } - }; - - Result run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) { - return Handle->run(IR, AM, ExtraArgs...); - } - }; - - Analysis getAnalysis() { return Analysis(static_cast(*this)); } - typename Analysis::Result getResult() { - return typename Analysis::Result(static_cast(*this)); - } - -protected: - // FIXME: MSVC seems unable to handle a lambda argument to Invoke from within - // the template, so we use a boring static function. - static bool invalidateCallback(IRUnitT &IR, const PreservedAnalyses &PA, - typename AnalysisManagerT::Invalidator &Inv) { - auto PAC = PA.template getChecker(); - return !PAC.preserved() && - !PAC.template preservedSet>(); - } - - /// Derived classes should call this in their constructor to set up default - /// mock actions. (We can't do this in our constructor because this has to - /// run after the DerivedT is constructed.) - void setDefaults() { - ON_CALL(static_cast(*this), - run(_, _, testing::Matcher(_)...)) - .WillByDefault(Return(this->getResult())); - ON_CALL(static_cast(*this), invalidate(_, _, _)) - .WillByDefault(Invoke(&invalidateCallback)); - } -}; - -template -AnalysisKey MockAnalysisHandleBase::Analysis::Key; - /// Mock handle for loop analyses. /// /// This is provided as a template accepting an (optional) integer. Because @@ -145,73 +76,11 @@ }; typedef MockLoopAnalysisHandleTemplate<> MockLoopAnalysisHandle; +typedef MockAnalysisHandle MockFunctionAnalysisHandle; -struct MockFunctionAnalysisHandle - : MockAnalysisHandleBase { - MOCK_METHOD2(run, Analysis::Result(Function &, FunctionAnalysisManager &)); - - MOCK_METHOD3(invalidate, bool(Function &, const PreservedAnalyses &, - FunctionAnalysisManager::Invalidator &)); - - MockFunctionAnalysisHandle() { setDefaults(); } -}; - -template , - typename... ExtraArgTs> -class MockPassHandleBase { -public: - class Pass : public PassInfoMixin { - friend MockPassHandleBase; - - DerivedT *Handle; - - Pass(DerivedT &Handle) : Handle(&Handle) { - static_assert(std::is_base_of::value, - "Must pass the derived type to this template!"); - } - - public: - PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, - ExtraArgTs... ExtraArgs) { - return Handle->run(IR, AM, ExtraArgs...); - } - }; - - Pass getPass() { return Pass(static_cast(*this)); } - -protected: - /// Derived classes should call this in their constructor to set up default - /// mock actions. (We can't do this in our constructor because this has to - /// run after the DerivedT is constructed.) - void setDefaults() { - ON_CALL(static_cast(*this), - run(_, _, testing::Matcher(_)...)) - .WillByDefault(Return(PreservedAnalyses::all())); - } -}; - -struct MockLoopPassHandle - : MockPassHandleBase { - MOCK_METHOD4(run, - PreservedAnalyses(Loop &, LoopAnalysisManager &, - LoopStandardAnalysisResults &, LPMUpdater &)); - MockLoopPassHandle() { setDefaults(); } -}; - -struct MockFunctionPassHandle - : MockPassHandleBase { - MOCK_METHOD2(run, PreservedAnalyses(Function &, FunctionAnalysisManager &)); - - MockFunctionPassHandle() { setDefaults(); } -}; - -struct MockModulePassHandle : MockPassHandleBase { - MOCK_METHOD2(run, PreservedAnalyses(Module &, ModuleAnalysisManager &)); - - MockModulePassHandle() { setDefaults(); } -}; +typedef MockPassHandle MockLoopPassHandle; +typedef MockPassHandle MockFunctionPassHandle; +typedef MockPassHandle MockModulePassHandle; /// Define a custom matcher for objects which support a 'getName' method /// returning a StringRef.