1 //===- TestPassManager.cpp - Test pass manager functionality --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "mlir/IR/BuiltinOps.h"
10 #include "mlir/Pass/Pass.h"
11 #include "mlir/Pass/PassManager.h"
12
13 using namespace mlir;
14
15 namespace {
16 struct TestModulePass
17 : public PassWrapper<TestModulePass, OperationPass<ModuleOp>> {
runOnOperation__anon96b9e0670111::TestModulePass18 void runOnOperation() final {}
19 };
20 struct TestFunctionPass : public PassWrapper<TestFunctionPass, FunctionPass> {
runOnFunction__anon96b9e0670111::TestFunctionPass21 void runOnFunction() final {}
22 };
23 class TestOptionsPass : public PassWrapper<TestOptionsPass, FunctionPass> {
24 public:
25 struct Options : public PassPipelineOptions<Options> {
26 ListOption<int> listOption{*this, "list",
27 llvm::cl::MiscFlags::CommaSeparated,
28 llvm::cl::desc("Example list option")};
29 ListOption<std::string> stringListOption{
30 *this, "string-list", llvm::cl::MiscFlags::CommaSeparated,
31 llvm::cl::desc("Example string list option")};
32 Option<std::string> stringOption{*this, "string",
33 llvm::cl::desc("Example string option")};
34 };
35 TestOptionsPass() = default;
TestOptionsPass(const TestOptionsPass &)36 TestOptionsPass(const TestOptionsPass &) {}
TestOptionsPass(const Options & options)37 TestOptionsPass(const Options &options) {
38 listOption = options.listOption;
39 stringOption = options.stringOption;
40 stringListOption = options.stringListOption;
41 }
42
runOnFunction()43 void runOnFunction() final {}
44
45 ListOption<int> listOption{*this, "list", llvm::cl::MiscFlags::CommaSeparated,
46 llvm::cl::desc("Example list option")};
47 ListOption<std::string> stringListOption{
48 *this, "string-list", llvm::cl::MiscFlags::CommaSeparated,
49 llvm::cl::desc("Example string list option")};
50 Option<std::string> stringOption{*this, "string",
51 llvm::cl::desc("Example string option")};
52 };
53
54 /// A test pass that always aborts to enable testing the crash recovery
55 /// mechanism of the pass manager.
56 class TestCrashRecoveryPass
57 : public PassWrapper<TestCrashRecoveryPass, OperationPass<>> {
runOnOperation()58 void runOnOperation() final { abort(); }
59 };
60
61 /// A test pass that contains a statistic.
62 struct TestStatisticPass
63 : public PassWrapper<TestStatisticPass, OperationPass<>> {
64 TestStatisticPass() = default;
TestStatisticPass__anon96b9e0670111::TestStatisticPass65 TestStatisticPass(const TestStatisticPass &) {}
66
67 Statistic opCount{this, "num-ops", "Number of operations counted"};
68
runOnOperation__anon96b9e0670111::TestStatisticPass69 void runOnOperation() final {
70 getOperation()->walk([&](Operation *) { ++opCount; });
71 }
72 };
73 } // end anonymous namespace
74
testNestedPipeline(OpPassManager & pm)75 static void testNestedPipeline(OpPassManager &pm) {
76 // Nest a module pipeline that contains:
77 /// A module pass.
78 auto &modulePM = pm.nest<ModuleOp>();
79 modulePM.addPass(std::make_unique<TestModulePass>());
80 /// A nested function pass.
81 auto &nestedFunctionPM = modulePM.nest<FuncOp>();
82 nestedFunctionPM.addPass(std::make_unique<TestFunctionPass>());
83
84 // Nest a function pipeline that contains a single pass.
85 auto &functionPM = pm.nest<FuncOp>();
86 functionPM.addPass(std::make_unique<TestFunctionPass>());
87 }
88
testNestedPipelineTextual(OpPassManager & pm)89 static void testNestedPipelineTextual(OpPassManager &pm) {
90 (void)parsePassPipeline("test-pm-nested-pipeline", pm);
91 }
92
93 namespace mlir {
registerPassManagerTestPass()94 void registerPassManagerTestPass() {
95 PassRegistration<TestOptionsPass>("test-options-pass",
96 "Test options parsing capabilities");
97
98 PassRegistration<TestModulePass>("test-module-pass",
99 "Test a module pass in the pass manager");
100
101 PassRegistration<TestFunctionPass>(
102 "test-function-pass", "Test a function pass in the pass manager");
103
104 PassRegistration<TestCrashRecoveryPass>(
105 "test-pass-crash", "Test a pass in the pass manager that always crashes");
106
107 PassRegistration<TestStatisticPass> unusedStatP("test-stats-pass",
108 "Test pass statistics");
109
110 PassPipelineRegistration<>("test-pm-nested-pipeline",
111 "Test a nested pipeline in the pass manager",
112 testNestedPipeline);
113 PassPipelineRegistration<>("test-textual-pm-nested-pipeline",
114 "Test a nested pipeline in the pass manager",
115 testNestedPipelineTextual);
116 PassPipelineRegistration<>(
117 "test-dump-pipeline",
118 "Dumps the pipeline build so far for debugging purposes",
119 [](OpPassManager &pm) {
120 pm.printAsTextualPipeline(llvm::errs());
121 llvm::errs() << "\n";
122 });
123
124 PassPipelineRegistration<TestOptionsPass::Options>
125 registerOptionsPassPipeline(
126 "test-options-pass-pipeline",
127 "Parses options using pass pipeline registration",
128 [](OpPassManager &pm, const TestOptionsPass::Options &options) {
129 pm.addPass(std::make_unique<TestOptionsPass>(options));
130 });
131 }
132 } // namespace mlir
133