github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/third_party/mlir/lib/Pass/PassManagerOptions.cpp (about)

     1  //===- PassManagerOptions.cpp - PassManager Command Line Options ----------===//
     2  //
     3  // Copyright 2019 The MLIR Authors.
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //   http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  // =============================================================================
    17  
    18  #include "mlir/Pass/Pass.h"
    19  #include "mlir/Pass/PassManager.h"
    20  #include "mlir/Pass/PassRegistry.h"
    21  #include "llvm/Support/CommandLine.h"
    22  #include "llvm/Support/ManagedStatic.h"
    23  
    24  using namespace mlir;
    25  
    26  namespace {
    27  struct PassManagerOptions {
    28    typedef llvm::cl::list<const mlir::PassRegistryEntry *, bool, PassNameParser>
    29        PassOptionList;
    30  
    31    PassManagerOptions();
    32  
    33    //===--------------------------------------------------------------------===//
    34    // Multi-threading
    35    //===--------------------------------------------------------------------===//
    36    llvm::cl::opt<bool> disableThreads;
    37  
    38    //===--------------------------------------------------------------------===//
    39    // IR Printing
    40    //===--------------------------------------------------------------------===//
    41    PassOptionList printBefore;
    42    PassOptionList printAfter;
    43    llvm::cl::opt<bool> printBeforeAll;
    44    llvm::cl::opt<bool> printAfterAll;
    45    llvm::cl::opt<bool> printModuleScope;
    46  
    47    /// Add an IR printing instrumentation if enabled by any 'print-ir' flags.
    48    void addPrinterInstrumentation(PassManager &pm);
    49  
    50    //===--------------------------------------------------------------------===//
    51    // Pass Timing
    52    //===--------------------------------------------------------------------===//
    53    llvm::cl::opt<bool> passTiming;
    54    llvm::cl::opt<PassTimingDisplayMode> passTimingDisplayMode;
    55  
    56    /// Add a pass timing instrumentation if enabled by 'pass-timing' flags.
    57    void addTimingInstrumentation(PassManager &pm);
    58  };
    59  } // end anonymous namespace
    60  
    61  static llvm::ManagedStatic<llvm::Optional<PassManagerOptions>> options;
    62  
    63  PassManagerOptions::PassManagerOptions()
    64      //===------------------------------------------------------------------===//
    65      // Multi-threading
    66      //===------------------------------------------------------------------===//
    67      : disableThreads(
    68            "disable-pass-threading",
    69            llvm::cl::desc("Disable multithreading in the pass manager"),
    70            llvm::cl::init(false)),
    71  
    72        //===----------------------------------------------------------------===//
    73        // IR Printing
    74        //===----------------------------------------------------------------===//
    75        printBefore("print-ir-before",
    76                    llvm::cl::desc("Print IR before specified passes")),
    77        printAfter("print-ir-after",
    78                   llvm::cl::desc("Print IR after specified passes")),
    79        printBeforeAll("print-ir-before-all",
    80                       llvm::cl::desc("Print IR before each pass"),
    81                       llvm::cl::init(false)),
    82        printAfterAll("print-ir-after-all",
    83                      llvm::cl::desc("Print IR after each pass"),
    84                      llvm::cl::init(false)),
    85        printModuleScope(
    86            "print-ir-module-scope",
    87            llvm::cl::desc("When printing IR for print-ir-[before|after]{-all} "
    88                           "always print "
    89                           "a module IR"),
    90            llvm::cl::init(false)),
    91  
    92        //===----------------------------------------------------------------===//
    93        // Pass Timing
    94        //===----------------------------------------------------------------===//
    95        passTiming("pass-timing",
    96                   llvm::cl::desc("Display the execution times of each pass")),
    97        passTimingDisplayMode(
    98            "pass-timing-display",
    99            llvm::cl::desc("Display method for pass timing data"),
   100            llvm::cl::init(PassTimingDisplayMode::Pipeline),
   101            llvm::cl::values(
   102                clEnumValN(PassTimingDisplayMode::List, "list",
   103                           "display the results in a list sorted by total time"),
   104                clEnumValN(PassTimingDisplayMode::Pipeline, "pipeline",
   105                           "display the results with a nested pipeline view"))) {}
   106  
   107  /// Add an IR printing instrumentation if enabled by any 'print-ir' flags.
   108  void PassManagerOptions::addPrinterInstrumentation(PassManager &pm) {
   109    std::function<bool(Pass *)> shouldPrintBeforePass, shouldPrintAfterPass;
   110  
   111    // Handle print-before.
   112    if (printBeforeAll) {
   113      // If we are printing before all, then just return true for the filter.
   114      shouldPrintBeforePass = [](Pass *) { return true; };
   115    } else if (printBefore.getNumOccurrences() != 0) {
   116      // Otherwise if there are specific passes to print before, then check to see
   117      // if the pass info for the current pass is included in the list.
   118      shouldPrintBeforePass = [&](Pass *pass) {
   119        auto *passInfo = pass->lookupPassInfo();
   120        return passInfo && llvm::is_contained(printBefore, passInfo);
   121      };
   122    }
   123  
   124    // Handle print-after.
   125    if (printAfterAll) {
   126      // If we are printing after all, then just return true for the filter.
   127      shouldPrintAfterPass = [](Pass *) { return true; };
   128    } else if (printAfter.getNumOccurrences() != 0) {
   129      // Otherwise if there are specific passes to print after, then check to see
   130      // if the pass info for the current pass is included in the list.
   131      shouldPrintAfterPass = [&](Pass *pass) {
   132        auto *passInfo = pass->lookupPassInfo();
   133        return passInfo && llvm::is_contained(printAfter, passInfo);
   134      };
   135    }
   136  
   137    // If there are no valid printing filters, then just return.
   138    if (!shouldPrintBeforePass && !shouldPrintAfterPass)
   139      return;
   140  
   141    // Otherwise, add the IR printing instrumentation.
   142    pm.enableIRPrinting(shouldPrintBeforePass, shouldPrintAfterPass,
   143                        printModuleScope, llvm::errs());
   144  }
   145  
   146  /// Add a pass timing instrumentation if enabled by 'pass-timing' flags.
   147  void PassManagerOptions::addTimingInstrumentation(PassManager &pm) {
   148    if (passTiming)
   149      pm.enableTiming(passTimingDisplayMode);
   150  }
   151  
   152  void mlir::registerPassManagerCLOptions() {
   153    // Reset the options instance if it hasn't been enabled yet.
   154    if (!options->hasValue())
   155      options->emplace();
   156  }
   157  
   158  void mlir::applyPassManagerCLOptions(PassManager &pm) {
   159    // Disable multi-threading.
   160    if ((*options)->disableThreads)
   161      pm.disableMultithreading();
   162  
   163    // Add the IR printing instrumentation.
   164    (*options)->addPrinterInstrumentation(pm);
   165  
   166    // Note: The pass timing instrumentation should be added last to avoid any
   167    // potential "ghost" timing from other instrumentations being unintentionally
   168    // included in the timing results.
   169    (*options)->addTimingInstrumentation(pm);
   170  }