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 }