12 #include "llvm/Support/Format.h"
13 #include "llvm/Support/FormatVariadic.h"
25 IRPrinterInstrumentation(std::unique_ptr<PassManager::IRPrinterConfig> config)
26 : config(std::move(config)) {}
35 std::unique_ptr<PassManager::IRPrinterConfig> config;
47 if (!printModuleScope)
48 return op->
print(out <<
" //----- //\n",
52 out <<
" ('" << op->
getName() <<
"' operation";
55 out <<
": @" << symbolName.getValue();
56 out <<
") //----- //\n";
59 auto *topLevelOp = op;
60 while (
auto *parentOp = topLevelOp->getParentOp())
61 topLevelOp = parentOp;
62 topLevelOp->
print(out, flags);
66 void IRPrinterInstrumentation::runBeforePass(
Pass *pass,
Operation *op) {
67 if (isa<OpToOpPassAdaptor>(pass))
70 if (config->shouldPrintAfterOnlyOnChange())
71 beforePassFingerPrints.try_emplace(pass, op);
73 config->printBeforeIfEnabled(pass, op, [&](raw_ostream &out) {
74 out <<
"// -----// IR Dump Before " << pass->
getName() <<
" ("
76 printIR(op, config->shouldPrintAtModuleScope(), out,
77 config->getOpPrintingFlags());
82 void IRPrinterInstrumentation::runAfterPass(
Pass *pass,
Operation *op) {
83 if (isa<OpToOpPassAdaptor>(pass))
87 if (config->shouldPrintAfterOnlyOnFailure())
92 if (config->shouldPrintAfterOnlyOnChange()) {
93 auto fingerPrintIt = beforePassFingerPrints.find(pass);
94 assert(fingerPrintIt != beforePassFingerPrints.end() &&
95 "expected valid fingerprint");
98 beforePassFingerPrints.erase(fingerPrintIt);
101 beforePassFingerPrints.erase(fingerPrintIt);
104 config->printAfterIfEnabled(pass, op, [&](raw_ostream &out) {
105 out <<
"// -----// IR Dump After " << pass->
getName() <<
" ("
107 printIR(op, config->shouldPrintAtModuleScope(), out,
108 config->getOpPrintingFlags());
113 void IRPrinterInstrumentation::runAfterPassFailed(
Pass *pass,
Operation *op) {
114 if (isa<OpToOpPassAdaptor>(pass))
116 if (config->shouldPrintAfterOnlyOnChange())
117 beforePassFingerPrints.erase(pass);
119 config->printAfterIfEnabled(pass, op, [&](raw_ostream &out) {
120 out << formatv(
"// -----// IR Dump After {0} Failed ({1})", pass->
getName(),
133 bool printAfterOnlyOnChange,
134 bool printAfterOnlyOnFailure,
136 : printModuleScope(printModuleScope),
137 printAfterOnlyOnChange(printAfterOnlyOnChange),
138 printAfterOnlyOnFailure(printAfterOnlyOnFailure),
139 opPrintingFlags(opPrintingFlags) {}
167 BasicIRPrinterConfig(
168 std::function<
bool(
Pass *,
Operation *)> shouldPrintBeforePass,
169 std::function<
bool(
Pass *,
Operation *)> shouldPrintAfterPass,
170 bool printModuleScope,
bool printAfterOnlyOnChange,
174 printAfterOnlyOnFailure, opPrintingFlags),
175 shouldPrintBeforePass(std::move(shouldPrintBeforePass)),
176 shouldPrintAfterPass(std::move(shouldPrintAfterPass)), out(out) {
177 assert((this->shouldPrintBeforePass || this->shouldPrintAfterPass) &&
178 "expected at least one valid filter function");
182 PrintCallbackFn printCallback)
final {
183 if (shouldPrintBeforePass && shouldPrintBeforePass(pass, operation))
188 PrintCallbackFn printCallback)
final {
189 if (shouldPrintAfterPass && shouldPrintAfterPass(pass, operation))
194 std::function<bool(
Pass *,
Operation *)> shouldPrintBeforePass;
195 std::function<bool(
Pass *,
Operation *)> shouldPrintAfterPass;
205 if (config->shouldPrintAtModuleScope() &&
207 llvm::report_fatal_error(
"IR printing can't be setup on a pass-manager "
208 "without disabling multi-threading first.");
210 std::make_unique<IRPrinterInstrumentation>(std::move(config)));
215 std::function<
bool(
Pass *,
Operation *)> shouldPrintBeforePass,
216 std::function<
bool(
Pass *,
Operation *)> shouldPrintAfterPass,
217 bool printModuleScope,
bool printAfterOnlyOnChange,
218 bool printAfterOnlyOnFailure, raw_ostream &out,
221 std::move(shouldPrintBeforePass), std::move(shouldPrintAfterPass),
222 printModuleScope, printAfterOnlyOnChange, printAfterOnlyOnFailure,
223 opPrintingFlags, out));
static void printIR(Operation *op, bool printModuleScope, raw_ostream &out, OpPrintingFlags flags)
Set of flags used to control the behavior of the various IR print methods (e.g.
OpPrintingFlags & useLocalScope()
Use local scope when printing the operation.
A unique fingerprint for a specific operation, and all of it's internal operations.
Operation is the basic unit of execution within MLIR.
AttrClass getAttrOfType(StringAttr name)
void print(raw_ostream &os, const OpPrintingFlags &flags=std::nullopt)
Block * getBlock()
Returns the operation block that contains this operation.
OperationName getName()
The name of an operation is the key identifier for it.
PassInstrumentation provides several entry points into the pass manager infrastructure.
A configuration struct provided to the IR printer instrumentation.
virtual ~IRPrinterConfig()
IRPrinterConfig(bool printModuleScope=false, bool printAfterOnlyOnChange=false, bool printAfterOnlyOnFailure=false, OpPrintingFlags opPrintingFlags=OpPrintingFlags())
Initialize the configuration.
virtual void printBeforeIfEnabled(Pass *pass, Operation *operation, PrintCallbackFn printCallback)
A hook that may be overridden by a derived config that checks if the IR of 'operation' should be dump...
virtual void printAfterIfEnabled(Pass *pass, Operation *operation, PrintCallbackFn printCallback)
A hook that may be overridden by a derived config that checks if the IR of 'operation' should be dump...
MLIRContext * getContext() const
Return an instance of the context.
void enableIRPrinting(std::unique_ptr< IRPrinterConfig > config)
Add an instrumentation to print the IR before and after pass execution, using the provided configurat...
void addInstrumentation(std::unique_ptr< PassInstrumentation > pi)
Add the provided instrumentation to the pass manager.
The abstract base pass class.
virtual StringRef getName() const =0
Returns the derived pass name.
virtual StringRef getArgument() const
Return the command line argument used when registering this pass.
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
Detect if any of the given parameter types has a sub-element handler.
Include the generated interface declarations.