//===- TestPassManager.cpp - Test pass manager functionality --------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "mlir/IR/BuiltinOps.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassManager.h" using namespace mlir; namespace { struct TestModulePass : public PassWrapper> { void runOnOperation() final {} }; struct TestFunctionPass : public PassWrapper { void runOnFunction() final {} }; class TestOptionsPass : public PassWrapper { public: struct Options : public PassPipelineOptions { ListOption listOption{*this, "list", llvm::cl::MiscFlags::CommaSeparated, llvm::cl::desc("Example list option")}; ListOption stringListOption{ *this, "string-list", llvm::cl::MiscFlags::CommaSeparated, llvm::cl::desc("Example string list option")}; Option stringOption{*this, "string", llvm::cl::desc("Example string option")}; }; TestOptionsPass() = default; TestOptionsPass(const TestOptionsPass &) {} TestOptionsPass(const Options &options) { listOption = options.listOption; stringOption = options.stringOption; stringListOption = options.stringListOption; } void runOnFunction() final {} ListOption listOption{*this, "list", llvm::cl::MiscFlags::CommaSeparated, llvm::cl::desc("Example list option")}; ListOption stringListOption{ *this, "string-list", llvm::cl::MiscFlags::CommaSeparated, llvm::cl::desc("Example string list option")}; Option stringOption{*this, "string", llvm::cl::desc("Example string option")}; }; /// A test pass that always aborts to enable testing the crash recovery /// mechanism of the pass manager. class TestCrashRecoveryPass : public PassWrapper> { void runOnOperation() final { abort(); } }; /// A test pass that contains a statistic. struct TestStatisticPass : public PassWrapper> { TestStatisticPass() = default; TestStatisticPass(const TestStatisticPass &) {} Statistic opCount{this, "num-ops", "Number of operations counted"}; void runOnOperation() final { getOperation()->walk([&](Operation *) { ++opCount; }); } }; } // end anonymous namespace static void testNestedPipeline(OpPassManager &pm) { // Nest a module pipeline that contains: /// A module pass. auto &modulePM = pm.nest(); modulePM.addPass(std::make_unique()); /// A nested function pass. auto &nestedFunctionPM = modulePM.nest(); nestedFunctionPM.addPass(std::make_unique()); // Nest a function pipeline that contains a single pass. auto &functionPM = pm.nest(); functionPM.addPass(std::make_unique()); } static void testNestedPipelineTextual(OpPassManager &pm) { (void)parsePassPipeline("test-pm-nested-pipeline", pm); } namespace mlir { void registerPassManagerTestPass() { PassRegistration("test-options-pass", "Test options parsing capabilities"); PassRegistration("test-module-pass", "Test a module pass in the pass manager"); PassRegistration( "test-function-pass", "Test a function pass in the pass manager"); PassRegistration( "test-pass-crash", "Test a pass in the pass manager that always crashes"); PassRegistration unusedStatP("test-stats-pass", "Test pass statistics"); PassPipelineRegistration<>("test-pm-nested-pipeline", "Test a nested pipeline in the pass manager", testNestedPipeline); PassPipelineRegistration<>("test-textual-pm-nested-pipeline", "Test a nested pipeline in the pass manager", testNestedPipelineTextual); PassPipelineRegistration<>( "test-dump-pipeline", "Dumps the pipeline build so far for debugging purposes", [](OpPassManager &pm) { pm.printAsTextualPipeline(llvm::errs()); llvm::errs() << "\n"; }); PassPipelineRegistration registerOptionsPassPipeline( "test-options-pass-pipeline", "Parses options using pass pipeline registration", [](OpPassManager &pm, const TestOptionsPass::Options &options) { pm.addPass(std::make_unique(options)); }); } } // namespace mlir