1 //===- PassManagerOptions.cpp - PassManager Command Line Options ----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "mlir/Pass/Pass.h"
10 #include "mlir/Pass/PassManager.h"
11 #include "mlir/Pass/PassRegistry.h"
12 #include "mlir/Support/Timing.h"
13 #include "llvm/Support/CommandLine.h"
14 #include "llvm/Support/ManagedStatic.h"
19 struct PassManagerOptions
{
20 //===--------------------------------------------------------------------===//
21 // Crash Reproducer Generator
22 //===--------------------------------------------------------------------===//
23 llvm::cl::opt
<std::string
> reproducerFile
{
24 "mlir-pass-pipeline-crash-reproducer",
25 llvm::cl::desc("Generate a .mlir reproducer file at the given output path"
26 " if the pass manager crashes or fails")};
27 llvm::cl::opt
<bool> localReproducer
{
28 "mlir-pass-pipeline-local-reproducer",
29 llvm::cl::desc("When generating a crash reproducer, attempt to generated "
30 "a reproducer with the smallest pipeline."),
31 llvm::cl::init(false)};
33 //===--------------------------------------------------------------------===//
35 //===--------------------------------------------------------------------===//
36 PassNameCLParser printBefore
{"mlir-print-ir-before",
37 "Print IR before specified passes"};
38 PassNameCLParser printAfter
{"mlir-print-ir-after",
39 "Print IR after specified passes"};
40 llvm::cl::opt
<bool> printBeforeAll
{
41 "mlir-print-ir-before-all", llvm::cl::desc("Print IR before each pass"),
42 llvm::cl::init(false)};
43 llvm::cl::opt
<bool> printAfterAll
{"mlir-print-ir-after-all",
44 llvm::cl::desc("Print IR after each pass"),
45 llvm::cl::init(false)};
46 llvm::cl::opt
<bool> printAfterChange
{
47 "mlir-print-ir-after-change",
49 "When printing the IR after a pass, only print if the IR changed"),
50 llvm::cl::init(false)};
51 llvm::cl::opt
<bool> printAfterFailure
{
52 "mlir-print-ir-after-failure",
54 "When printing the IR after a pass, only print if the pass failed"),
55 llvm::cl::init(false)};
56 llvm::cl::opt
<bool> printModuleScope
{
57 "mlir-print-ir-module-scope",
58 llvm::cl::desc("When printing IR for print-ir-[before|after]{-all} "
59 "always print the top-level operation"),
60 llvm::cl::init(false)};
61 llvm::cl::opt
<std::string
> printTreeDir
{
62 "mlir-print-ir-tree-dir",
63 llvm::cl::desc("When printing the IR before/after a pass, print file "
64 "tree rooted at this directory. Use in conjunction with "
65 "mlir-print-ir-* flags")};
67 /// Add an IR printing instrumentation if enabled by any 'print-ir' flags.
68 void addPrinterInstrumentation(PassManager
&pm
);
70 //===--------------------------------------------------------------------===//
72 //===--------------------------------------------------------------------===//
73 llvm::cl::opt
<bool> passStatistics
{
74 "mlir-pass-statistics",
75 llvm::cl::desc("Display the statistics of each pass")};
76 llvm::cl::opt
<PassDisplayMode
> passStatisticsDisplayMode
{
77 "mlir-pass-statistics-display",
78 llvm::cl::desc("Display method for pass statistics"),
79 llvm::cl::init(PassDisplayMode::Pipeline
),
82 PassDisplayMode::List
, "list",
83 "display the results in a merged list sorted by pass name"),
84 clEnumValN(PassDisplayMode::Pipeline
, "pipeline",
85 "display the results with a nested pipeline view"))};
89 static llvm::ManagedStatic
<PassManagerOptions
> options
;
91 /// Add an IR printing instrumentation if enabled by any 'print-ir' flags.
92 void PassManagerOptions::addPrinterInstrumentation(PassManager
&pm
) {
93 std::function
<bool(Pass
*, Operation
*)> shouldPrintBeforePass
;
94 std::function
<bool(Pass
*, Operation
*)> shouldPrintAfterPass
;
96 // Handle print-before.
98 // If we are printing before all, then just return true for the filter.
99 shouldPrintBeforePass
= [](Pass
*, Operation
*) { return true; };
100 } else if (printBefore
.hasAnyOccurrences()) {
101 // Otherwise if there are specific passes to print before, then check to see
102 // if the pass info for the current pass is included in the list.
103 shouldPrintBeforePass
= [&](Pass
*pass
, Operation
*) {
104 auto *passInfo
= pass
->lookupPassInfo();
105 return passInfo
&& printBefore
.contains(passInfo
);
109 // Handle print-after.
110 if (printAfterAll
|| printAfterFailure
) {
111 // If we are printing after all or failure, then just return true for the
113 shouldPrintAfterPass
= [](Pass
*, Operation
*) { return true; };
114 } else if (printAfter
.hasAnyOccurrences()) {
115 // Otherwise if there are specific passes to print after, then check to see
116 // if the pass info for the current pass is included in the list.
117 shouldPrintAfterPass
= [&](Pass
*pass
, Operation
*) {
118 auto *passInfo
= pass
->lookupPassInfo();
119 return passInfo
&& printAfter
.contains(passInfo
);
123 // If there are no valid printing filters, then just return.
124 if (!shouldPrintBeforePass
&& !shouldPrintAfterPass
)
127 // Otherwise, add the IR printing instrumentation.
128 if (!printTreeDir
.empty()) {
129 pm
.enableIRPrintingToFileTree(shouldPrintBeforePass
, shouldPrintAfterPass
,
130 printModuleScope
, printAfterChange
,
131 printAfterFailure
, printTreeDir
);
135 pm
.enableIRPrinting(shouldPrintBeforePass
, shouldPrintAfterPass
,
136 printModuleScope
, printAfterChange
, printAfterFailure
,
140 void mlir::registerPassManagerCLOptions() {
141 // Make sure that the options struct has been constructed.
145 LogicalResult
mlir::applyPassManagerCLOptions(PassManager
&pm
) {
146 if (!options
.isConstructed())
149 // Generate a reproducer on crash/failure.
150 if (options
->reproducerFile
.getNumOccurrences())
151 pm
.enableCrashReproducerGeneration(options
->reproducerFile
,
152 options
->localReproducer
);
154 // Enable statistics dumping.
155 if (options
->passStatistics
)
156 pm
.enableStatistics(options
->passStatisticsDisplayMode
);
158 if (options
->printModuleScope
&& pm
.getContext()->isMultithreadingEnabled()) {
159 emitError(UnknownLoc::get(pm
.getContext()))
160 << "IR print for module scope can't be setup on a pass-manager "
161 "without disabling multi-threading first.\n";
165 // Add the IR printing instrumentation.
166 options
->addPrinterInstrumentation(pm
);
170 void mlir::applyDefaultTimingPassManagerCLOptions(PassManager
&pm
) {
171 // Create a temporary timing manager for the PM to own, apply its CL options,
172 // and pass it to the PM.
173 auto tm
= std::make_unique
<DefaultTimingManager
>();
174 applyDefaultTimingManagerCLOptions(*tm
);
175 pm
.enableTiming(std::move(tm
));