brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 305bf72 Raw
185 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 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"15 16using namespace mlir;17 18namespace {19struct PassManagerOptions {20  //===--------------------------------------------------------------------===//21  // Crash Reproducer Generator22  //===--------------------------------------------------------------------===//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)};32 33  //===--------------------------------------------------------------------===//34  // IR Printing35  //===--------------------------------------------------------------------===//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",48      llvm::cl::desc(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",53      llvm::cl::desc(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")};66 67  /// Add an IR printing instrumentation if enabled by any 'print-ir' flags.68  void addPrinterInstrumentation(PassManager &pm);69 70  //===--------------------------------------------------------------------===//71  // Pass Statistics72  //===--------------------------------------------------------------------===//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),80      llvm::cl::values(81          clEnumValN(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"))};86};87} // namespace88 89static llvm::ManagedStatic<PassManagerOptions> options;90 91/// Add an IR printing instrumentation if enabled by any 'print-ir' flags.92void PassManagerOptions::addPrinterInstrumentation(PassManager &pm) {93  std::function<bool(Pass *, Operation *)> shouldPrintBeforePass;94  std::function<bool(Pass *, Operation *)> shouldPrintAfterPass;95 96  // Handle print-before.97  if (printBeforeAll) {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 see102    // 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);106    };107  }108 109  // Handle print-after.110  if (printAfterAll || printAfterFailure) {111    // If we are printing after all or failure, then just return true for the112    // filter.113    shouldPrintAfterPass = [](Pass *, Operation *) { return true; };114  } else if (printAfter.hasAnyOccurrences()) {115    // Otherwise if there are specific passes to print after, then check to see116    // 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);120    };121  }122 123  // If there are no valid printing filters, then just return.124  if (!shouldPrintBeforePass && !shouldPrintAfterPass)125    return;126 127  // Otherwise, add the IR printing instrumentation.128  if (!printTreeDir.empty()) {129    pm.enableIRPrintingToFileTree(shouldPrintBeforePass, shouldPrintAfterPass,130                                  printModuleScope, printAfterChange,131                                  printAfterFailure, printTreeDir);132    return;133  }134 135  pm.enableIRPrinting(shouldPrintBeforePass, shouldPrintAfterPass,136                      printModuleScope, printAfterChange, printAfterFailure,137                      llvm::errs());138}139 140void mlir::registerPassManagerCLOptions() {141  // Make sure that the options struct has been constructed.142  *options;143}144 145LogicalResult mlir::applyPassManagerCLOptions(PassManager &pm) {146  if (!options.isConstructed())147    return failure();148 149  if (options->reproducerFile.getNumOccurrences() && options->localReproducer &&150      pm.getContext()->isMultithreadingEnabled()) {151    emitError(UnknownLoc::get(pm.getContext()))152        << "Local crash reproduction may not be used without disabling "153           "mutli-threading first.";154    return failure();155  }156 157  // Generate a reproducer on crash/failure.158  if (options->reproducerFile.getNumOccurrences())159    pm.enableCrashReproducerGeneration(options->reproducerFile,160                                       options->localReproducer);161 162  // Enable statistics dumping.163  if (options->passStatistics)164    pm.enableStatistics(options->passStatisticsDisplayMode);165 166  if (options->printModuleScope && pm.getContext()->isMultithreadingEnabled()) {167    emitError(UnknownLoc::get(pm.getContext()))168        << "IR print for module scope can't be setup on a pass-manager "169           "without disabling multi-threading first.\n";170    return failure();171  }172 173  // Add the IR printing instrumentation.174  options->addPrinterInstrumentation(pm);175  return success();176}177 178void mlir::applyDefaultTimingPassManagerCLOptions(PassManager &pm) {179  // Create a temporary timing manager for the PM to own, apply its CL options,180  // and pass it to the PM.181  auto tm = std::make_unique<DefaultTimingManager>();182  applyDefaultTimingManagerCLOptions(*tm);183  pm.enableTiming(std::move(tm));184}185