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

     1  //===- IRPrinting.cpp -----------------------------------------------------===//
     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 "PassDetail.h"
    19  #include "mlir/IR/Module.h"
    20  #include "mlir/Pass/PassManager.h"
    21  #include "llvm/Support/Format.h"
    22  #include "llvm/Support/FormatVariadic.h"
    23  
    24  using namespace mlir;
    25  using namespace mlir::detail;
    26  
    27  namespace {
    28  class IRPrinterInstrumentation : public PassInstrumentation {
    29  public:
    30    /// A filter function to decide if the given pass should be printed. Returns
    31    /// true if the pass should be printed, false otherwise.
    32    using ShouldPrintFn = std::function<bool(Pass *)>;
    33  
    34    IRPrinterInstrumentation(ShouldPrintFn &&shouldPrintBeforePass,
    35                             ShouldPrintFn &&shouldPrintAfterPass,
    36                             bool printModuleScope, raw_ostream &out)
    37        : shouldPrintBeforePass(shouldPrintBeforePass),
    38          shouldPrintAfterPass(shouldPrintAfterPass),
    39          printModuleScope(printModuleScope), out(out) {
    40      assert((shouldPrintBeforePass || shouldPrintAfterPass) &&
    41             "expected atleast one valid filter function");
    42    }
    43  
    44  private:
    45    /// Instrumentation hooks.
    46    void runBeforePass(Pass *pass, Operation *op) override;
    47    void runAfterPass(Pass *pass, Operation *op) override;
    48    void runAfterPassFailed(Pass *pass, Operation *op) override;
    49  
    50    /// Filter functions for before and after pass execution.
    51    ShouldPrintFn shouldPrintBeforePass, shouldPrintAfterPass;
    52  
    53    /// Flag to toggle if the printer should always print at module scope.
    54    bool printModuleScope;
    55  
    56    /// The stream to output to.
    57    raw_ostream &out;
    58  };
    59  } // end anonymous namespace
    60  
    61  /// Returns true if the given pass is hidden from IR printing.
    62  static bool isHiddenPass(Pass *pass) {
    63    return isAdaptorPass(pass) || isVerifierPass(pass);
    64  }
    65  
    66  static void printIR(Operation *op, bool printModuleScope, raw_ostream &out) {
    67    // Check for printing at module scope.
    68    auto function = dyn_cast<FuncOp>(op);
    69    if (printModuleScope && function) {
    70      // Print the function name and a newline before the Module.
    71      out << " (function: " << function.getName() << ")\n";
    72      function.getParentOfType<ModuleOp>().print(out);
    73      return;
    74    }
    75  
    76    // Print a newline before the IR.
    77    out << "\n";
    78  
    79    // Print the given function.
    80    if (function) {
    81      function.print(out);
    82      return;
    83    }
    84  
    85    // Print the given module.
    86    assert(isa<ModuleOp>(op) && "unexpected IR unit");
    87    cast<ModuleOp>(op).print(out);
    88  }
    89  
    90  /// Instrumentation hooks.
    91  void IRPrinterInstrumentation::runBeforePass(Pass *pass, Operation *op) {
    92    // Skip hidden passes and passes that the user filtered out.
    93    if (!shouldPrintBeforePass || isHiddenPass(pass) ||
    94        !shouldPrintBeforePass(pass))
    95      return;
    96    out << formatv("*** IR Dump Before {0} ***", pass->getName());
    97    printIR(op, printModuleScope, out);
    98    out << "\n\n";
    99  }
   100  
   101  void IRPrinterInstrumentation::runAfterPass(Pass *pass, Operation *op) {
   102    // Skip hidden passes and passes that the user filtered out.
   103    if (!shouldPrintAfterPass || isHiddenPass(pass) ||
   104        !shouldPrintAfterPass(pass))
   105      return;
   106    out << formatv("*** IR Dump After {0} ***", pass->getName());
   107    printIR(op, printModuleScope, out);
   108    out << "\n\n";
   109  }
   110  
   111  void IRPrinterInstrumentation::runAfterPassFailed(Pass *pass, Operation *op) {
   112    // Skip adaptor passes and passes that the user filtered out.
   113    if (!shouldPrintAfterPass || isAdaptorPass(pass) ||
   114        !shouldPrintAfterPass(pass))
   115      return;
   116    out << formatv("*** IR Dump After {0} Failed ***", pass->getName());
   117    printIR(op, printModuleScope, out);
   118    out << "\n\n";
   119  }
   120  
   121  //===----------------------------------------------------------------------===//
   122  // PassManager
   123  //===----------------------------------------------------------------------===//
   124  
   125  /// Add an instrumentation to print the IR before and after pass execution.
   126  void PassManager::enableIRPrinting(
   127      std::function<bool(Pass *)> shouldPrintBeforePass,
   128      std::function<bool(Pass *)> shouldPrintAfterPass, bool printModuleScope,
   129      raw_ostream &out) {
   130    addInstrumentation(new IRPrinterInstrumentation(
   131        std::move(shouldPrintBeforePass), std::move(shouldPrintAfterPass),
   132        printModuleScope, out));
   133  }