• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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