1 //===- PassManagerOptions.cpp - PassManager Command Line Options ----------===// 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/Pass/Pass.h" 10 #include "mlir/Pass/PassManager.h" 11 #include "mlir/Pass/PassRegistry.h" 12 #include "llvm/Support/CommandLine.h" 13 #include "llvm/Support/ManagedStatic.h" 14 15 using namespace mlir; 16 17 namespace { 18 struct PassManagerOptions { 19 //===--------------------------------------------------------------------===// 20 // Crash Reproducer Generator 21 //===--------------------------------------------------------------------===// 22 llvm::cl::opt<std::string> reproducerFile{ 23 "pass-pipeline-crash-reproducer", 24 llvm::cl::desc("Generate a .mlir reproducer file at the given output path" 25 " if the pass manager crashes or fails")}; 26 27 //===--------------------------------------------------------------------===// 28 // Multi-threading 29 //===--------------------------------------------------------------------===// 30 llvm::cl::opt<bool> disableThreads{ 31 "disable-pass-threading", 32 llvm::cl::desc("Disable multithreading in the pass manager"), 33 llvm::cl::init(false)}; 34 35 //===--------------------------------------------------------------------===// 36 // IR Printing 37 //===--------------------------------------------------------------------===// 38 PassPipelineCLParser printBefore{"print-ir-before", 39 "Print IR before specified passes"}; 40 PassPipelineCLParser printAfter{"print-ir-after", 41 "Print IR after specified passes"}; 42 llvm::cl::opt<bool> printBeforeAll{ 43 "print-ir-before-all", llvm::cl::desc("Print IR before each pass"), 44 llvm::cl::init(false)}; 45 llvm::cl::opt<bool> printAfterAll{"print-ir-after-all", 46 llvm::cl::desc("Print IR after each pass"), 47 llvm::cl::init(false)}; 48 llvm::cl::opt<bool> printAfterChange{ 49 "print-ir-after-change", 50 llvm::cl::desc( 51 "When printing the IR after a pass, only print if the IR changed"), 52 llvm::cl::init(false)}; 53 llvm::cl::opt<bool> printModuleScope{ 54 "print-ir-module-scope", 55 llvm::cl::desc("When printing IR for print-ir-[before|after]{-all} " 56 "always print the top-level module operation"), 57 llvm::cl::init(false)}; 58 59 /// Add an IR printing instrumentation if enabled by any 'print-ir' flags. 60 void addPrinterInstrumentation(PassManager &pm); 61 62 //===--------------------------------------------------------------------===// 63 // Pass Timing 64 //===--------------------------------------------------------------------===// 65 llvm::cl::opt<bool> passTiming{ 66 "pass-timing", 67 llvm::cl::desc("Display the execution times of each pass")}; 68 llvm::cl::opt<PassDisplayMode> passTimingDisplayMode{ 69 "pass-timing-display", 70 llvm::cl::desc("Display method for pass timing data"), 71 llvm::cl::init(PassDisplayMode::Pipeline), 72 llvm::cl::values( 73 clEnumValN(PassDisplayMode::List, "list", 74 "display the results in a list sorted by total time"), 75 clEnumValN(PassDisplayMode::Pipeline, "pipeline", 76 "display the results with a nested pipeline view"))}; 77 78 //===--------------------------------------------------------------------===// 79 // Pass Statistics 80 //===--------------------------------------------------------------------===// 81 llvm::cl::opt<bool> passStatistics{ 82 "pass-statistics", llvm::cl::desc("Display the statistics of each pass")}; 83 llvm::cl::opt<PassDisplayMode> passStatisticsDisplayMode{ 84 "pass-statistics-display", 85 llvm::cl::desc("Display method for pass statistics"), 86 llvm::cl::init(PassDisplayMode::Pipeline), 87 llvm::cl::values( 88 clEnumValN( 89 PassDisplayMode::List, "list", 90 "display the results in a merged list sorted by pass name"), 91 clEnumValN(PassDisplayMode::Pipeline, "pipeline", 92 "display the results with a nested pipeline view"))}; 93 94 /// Add a pass timing instrumentation if enabled by 'pass-timing' flags. 95 void addTimingInstrumentation(PassManager &pm); 96 }; 97 } // end anonymous namespace 98 99 static llvm::ManagedStatic<Optional<PassManagerOptions>> options; 100 101 /// Add an IR printing instrumentation if enabled by any 'print-ir' flags. 102 void PassManagerOptions::addPrinterInstrumentation(PassManager &pm) { 103 std::function<bool(Pass *, Operation *)> shouldPrintBeforePass; 104 std::function<bool(Pass *, Operation *)> shouldPrintAfterPass; 105 106 // Handle print-before. 107 if (printBeforeAll) { 108 // If we are printing before all, then just return true for the filter. 109 shouldPrintBeforePass = [](Pass *, Operation *) { return true; }; 110 } else if (printBefore.hasAnyOccurrences()) { 111 // Otherwise if there are specific passes to print before, then check to see 112 // if the pass info for the current pass is included in the list. 113 shouldPrintBeforePass = [&](Pass *pass, Operation *) { 114 auto *passInfo = pass->lookupPassInfo(); 115 return passInfo && printBefore.contains(passInfo); 116 }; 117 } 118 119 // Handle print-after. 120 if (printAfterAll) { 121 // If we are printing after all, then just return true for the filter. 122 shouldPrintAfterPass = [](Pass *, Operation *) { return true; }; 123 } else if (printAfter.hasAnyOccurrences()) { 124 // Otherwise if there are specific passes to print after, then check to see 125 // if the pass info for the current pass is included in the list. 126 shouldPrintAfterPass = [&](Pass *pass, Operation *) { 127 auto *passInfo = pass->lookupPassInfo(); 128 return passInfo && printAfter.contains(passInfo); 129 }; 130 } 131 132 // If there are no valid printing filters, then just return. 133 if (!shouldPrintBeforePass && !shouldPrintAfterPass) 134 return; 135 136 // Otherwise, add the IR printing instrumentation. 137 pm.enableIRPrinting(shouldPrintBeforePass, shouldPrintAfterPass, 138 printModuleScope, printAfterChange, llvm::errs()); 139 } 140 141 /// Add a pass timing instrumentation if enabled by 'pass-timing' flags. 142 void PassManagerOptions::addTimingInstrumentation(PassManager &pm) { 143 if (passTiming) 144 pm.enableTiming(passTimingDisplayMode); 145 } 146 147 void mlir::registerPassManagerCLOptions() { 148 // Reset the options instance if it hasn't been enabled yet. 149 if (!options->hasValue()) 150 options->emplace(); 151 } 152 153 void mlir::applyPassManagerCLOptions(PassManager &pm) { 154 // Generate a reproducer on crash/failure. 155 if ((*options)->reproducerFile.getNumOccurrences()) 156 pm.enableCrashReproducerGeneration((*options)->reproducerFile); 157 158 // Disable multi-threading. 159 if ((*options)->disableThreads) 160 pm.disableMultithreading(); 161 162 // Enable statistics dumping. 163 if ((*options)->passStatistics) 164 pm.enableStatistics((*options)->passStatisticsDisplayMode); 165 166 // Add the IR printing instrumentation. 167 (*options)->addPrinterInstrumentation(pm); 168 169 // Note: The pass timing instrumentation should be added last to avoid any 170 // potential "ghost" timing from other instrumentations being unintentionally 171 // included in the timing results. 172 (*options)->addTimingInstrumentation(pm); 173 } 174