blob: f5780ab27b5ba58f3bfd30c951291d5d80ad0a3e [file] [log] [blame]
River Riddle6810c8b2019-03-16 20:34:23 -07001//===- PassManagerOptions.cpp - PassManager Command Line Options ----------===//
2//
Mehdi Amini30857102020-01-26 03:58:30 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
Mehdi Amini56222a02019-12-23 09:35:36 -08004// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
River Riddle6810c8b2019-03-16 20:34:23 -07006//
Mehdi Amini56222a02019-12-23 09:35:36 -08007//===----------------------------------------------------------------------===//
River Riddle6810c8b2019-03-16 20:34:23 -07008
9#include "mlir/Pass/Pass.h"
10#include "mlir/Pass/PassManager.h"
11#include "mlir/Pass/PassRegistry.h"
Fabian Schuiki33f908c2021-04-21 10:57:29 +020012#include "mlir/Support/Timing.h"
River Riddle6810c8b2019-03-16 20:34:23 -070013#include "llvm/Support/CommandLine.h"
14#include "llvm/Support/ManagedStatic.h"
15
16using namespace mlir;
17
18namespace {
19struct PassManagerOptions {
River Riddle6810c8b2019-03-16 20:34:23 -070020 //===--------------------------------------------------------------------===//
River Riddle7a7dcc12019-10-10 19:19:11 -070021 // Crash Reproducer Generator
22 //===--------------------------------------------------------------------===//
23 llvm::cl::opt<std::string> reproducerFile{
24 "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")};
River Riddle983382f2020-04-29 15:08:15 -070027 llvm::cl::opt<bool> localReproducer{
28 "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)};
River Riddle7a7dcc12019-10-10 19:19:11 -070032
33 //===--------------------------------------------------------------------===//
River Riddle6810c8b2019-03-16 20:34:23 -070034 // IR Printing
35 //===--------------------------------------------------------------------===//
River Riddlee9cda7c2020-12-15 14:42:16 -080036 PassNameCLParser printBefore{"print-ir-before",
37 "Print IR before specified passes"};
38 PassNameCLParser printAfter{"print-ir-after",
39 "Print IR after specified passes"};
River Riddleb245e952019-10-10 19:13:44 -070040 llvm::cl::opt<bool> printBeforeAll{
41 "print-ir-before-all", llvm::cl::desc("Print IR before each pass"),
42 llvm::cl::init(false)};
43 llvm::cl::opt<bool> printAfterAll{"print-ir-after-all",
44 llvm::cl::desc("Print IR after each pass"),
45 llvm::cl::init(false)};
River Riddle8904e912019-12-06 17:04:24 -080046 llvm::cl::opt<bool> printAfterChange{
47 "print-ir-after-change",
48 llvm::cl::desc(
49 "When printing the IR after a pass, only print if the IR changed"),
50 llvm::cl::init(false)};
River Riddle64ce90e2021-05-19 16:53:23 -070051 llvm::cl::opt<bool> printAfterFailure{
52 "print-ir-after-failure",
53 llvm::cl::desc(
54 "When printing the IR after a pass, only print if the pass failed"),
55 llvm::cl::init(false)};
River Riddleb245e952019-10-10 19:13:44 -070056 llvm::cl::opt<bool> printModuleScope{
57 "print-ir-module-scope",
58 llvm::cl::desc("When printing IR for print-ir-[before|after]{-all} "
River Riddle00c6ef82020-12-03 15:46:32 -080059 "always print the top-level operation"),
River Riddleb245e952019-10-10 19:13:44 -070060 llvm::cl::init(false)};
River Riddle6810c8b2019-03-16 20:34:23 -070061
62 /// Add an IR printing instrumentation if enabled by any 'print-ir' flags.
63 void addPrinterInstrumentation(PassManager &pm);
64
65 //===--------------------------------------------------------------------===//
River Riddle33a64542019-12-05 11:52:58 -080066 // Pass Statistics
67 //===--------------------------------------------------------------------===//
68 llvm::cl::opt<bool> passStatistics{
69 "pass-statistics", llvm::cl::desc("Display the statistics of each pass")};
70 llvm::cl::opt<PassDisplayMode> passStatisticsDisplayMode{
71 "pass-statistics-display",
72 llvm::cl::desc("Display method for pass statistics"),
73 llvm::cl::init(PassDisplayMode::Pipeline),
74 llvm::cl::values(
75 clEnumValN(
76 PassDisplayMode::List, "list",
77 "display the results in a merged list sorted by pass name"),
78 clEnumValN(PassDisplayMode::Pipeline, "pipeline",
River Riddleb245e952019-10-10 19:13:44 -070079 "display the results with a nested pipeline view"))};
River Riddle6810c8b2019-03-16 20:34:23 -070080};
81} // end anonymous namespace
82
River Riddle8938dea2020-04-11 23:11:51 -070083static llvm::ManagedStatic<PassManagerOptions> options;
River Riddle6810c8b2019-03-16 20:34:23 -070084
River Riddle6810c8b2019-03-16 20:34:23 -070085/// Add an IR printing instrumentation if enabled by any 'print-ir' flags.
86void PassManagerOptions::addPrinterInstrumentation(PassManager &pm) {
River Riddleda530002019-12-05 14:52:28 -080087 std::function<bool(Pass *, Operation *)> shouldPrintBeforePass;
88 std::function<bool(Pass *, Operation *)> shouldPrintAfterPass;
River Riddle6810c8b2019-03-16 20:34:23 -070089
90 // Handle print-before.
91 if (printBeforeAll) {
92 // If we are printing before all, then just return true for the filter.
River Riddleda530002019-12-05 14:52:28 -080093 shouldPrintBeforePass = [](Pass *, Operation *) { return true; };
River Riddle9274ed62019-09-13 12:09:50 -070094 } else if (printBefore.hasAnyOccurrences()) {
River Riddle6810c8b2019-03-16 20:34:23 -070095 // Otherwise if there are specific passes to print before, then check to see
96 // if the pass info for the current pass is included in the list.
River Riddleda530002019-12-05 14:52:28 -080097 shouldPrintBeforePass = [&](Pass *pass, Operation *) {
River Riddle6810c8b2019-03-16 20:34:23 -070098 auto *passInfo = pass->lookupPassInfo();
River Riddle9274ed62019-09-13 12:09:50 -070099 return passInfo && printBefore.contains(passInfo);
River Riddle6810c8b2019-03-16 20:34:23 -0700100 };
101 }
102
103 // Handle print-after.
River Riddle64ce90e2021-05-19 16:53:23 -0700104 if (printAfterAll || printAfterFailure) {
105 // If we are printing after all or failure, then just return true for the
106 // filter.
River Riddleda530002019-12-05 14:52:28 -0800107 shouldPrintAfterPass = [](Pass *, Operation *) { return true; };
River Riddle9274ed62019-09-13 12:09:50 -0700108 } else if (printAfter.hasAnyOccurrences()) {
River Riddle6810c8b2019-03-16 20:34:23 -0700109 // Otherwise if there are specific passes to print after, then check to see
110 // if the pass info for the current pass is included in the list.
River Riddleda530002019-12-05 14:52:28 -0800111 shouldPrintAfterPass = [&](Pass *pass, Operation *) {
River Riddle6810c8b2019-03-16 20:34:23 -0700112 auto *passInfo = pass->lookupPassInfo();
River Riddle9274ed62019-09-13 12:09:50 -0700113 return passInfo && printAfter.contains(passInfo);
River Riddle6810c8b2019-03-16 20:34:23 -0700114 };
115 }
116
117 // If there are no valid printing filters, then just return.
118 if (!shouldPrintBeforePass && !shouldPrintAfterPass)
119 return;
120
121 // Otherwise, add the IR printing instrumentation.
122 pm.enableIRPrinting(shouldPrintBeforePass, shouldPrintAfterPass,
River Riddle64ce90e2021-05-19 16:53:23 -0700123 printModuleScope, printAfterChange, printAfterFailure,
124 llvm::errs());
River Riddle6810c8b2019-03-16 20:34:23 -0700125}
126
River Riddle6810c8b2019-03-16 20:34:23 -0700127void mlir::registerPassManagerCLOptions() {
River Riddle8938dea2020-04-11 23:11:51 -0700128 // Make sure that the options struct has been constructed.
129 *options;
River Riddle6810c8b2019-03-16 20:34:23 -0700130}
131
132void mlir::applyPassManagerCLOptions(PassManager &pm) {
River Riddle8938dea2020-04-11 23:11:51 -0700133 if (!options.isConstructed())
134 return;
135
River Riddle7a7dcc12019-10-10 19:19:11 -0700136 // Generate a reproducer on crash/failure.
River Riddle8938dea2020-04-11 23:11:51 -0700137 if (options->reproducerFile.getNumOccurrences())
River Riddle983382f2020-04-29 15:08:15 -0700138 pm.enableCrashReproducerGeneration(options->reproducerFile,
139 options->localReproducer);
River Riddle7a7dcc12019-10-10 19:19:11 -0700140
River Riddle33a64542019-12-05 11:52:58 -0800141 // Enable statistics dumping.
River Riddle8938dea2020-04-11 23:11:51 -0700142 if (options->passStatistics)
143 pm.enableStatistics(options->passStatisticsDisplayMode);
River Riddle33a64542019-12-05 11:52:58 -0800144
River Riddle6810c8b2019-03-16 20:34:23 -0700145 // Add the IR printing instrumentation.
River Riddle8938dea2020-04-11 23:11:51 -0700146 options->addPrinterInstrumentation(pm);
Fabian Schuiki33f908c2021-04-21 10:57:29 +0200147}
River Riddle6810c8b2019-03-16 20:34:23 -0700148
Fabian Schuiki33f908c2021-04-21 10:57:29 +0200149void mlir::applyDefaultTimingPassManagerCLOptions(PassManager &pm) {
150 // Create a temporary timing manager for the PM to own, apply its CL options,
151 // and pass it to the PM.
152 auto tm = std::make_unique<DefaultTimingManager>();
153 applyDefaultTimingManagerCLOptions(*tm);
154 pm.enableTiming(std::move(tm));
River Riddle6810c8b2019-03-16 20:34:23 -0700155}