12 #include "llvm/Support/Format.h" 13 #include "llvm/Support/FormatVariadic.h" 14 #include "llvm/Support/SHA1.h" 26 class OperationFingerPrint {
34 addDataToHash(hasher, op);
39 for (
Block &block : region) {
40 addDataToHash(hasher, &block);
42 addDataToHash(hasher, arg);
49 addDataToHash(hasher, operand);
54 hash = hasher.result();
57 bool operator==(
const OperationFingerPrint &other)
const {
58 return hash == other.hash;
60 bool operator!=(
const OperationFingerPrint &other)
const {
61 return !(*
this == other);
65 template <
typename T>
void addDataToHash(llvm::SHA1 &hasher,
const T &data) {
70 std::array<uint8_t, 20> hash;
79 IRPrinterInstrumentation(std::unique_ptr<PassManager::IRPrinterConfig> config)
80 : config(std::move(config)) {}
89 std::unique_ptr<PassManager::IRPrinterConfig> config;
101 if (!printModuleScope)
102 return op->
print(out <<
" //----- //\n",
106 out <<
" ('" << op->
getName() <<
"' operation";
107 if (
auto symbolName =
109 out <<
": @" << symbolName.getValue();
110 out <<
") //----- //\n";
113 auto *topLevelOp = op;
114 while (
auto *parentOp = topLevelOp->getParentOp())
115 topLevelOp = parentOp;
116 topLevelOp->
print(out, flags);
120 void IRPrinterInstrumentation::runBeforePass(
Pass *pass,
Operation *op) {
121 if (isa<OpToOpPassAdaptor>(pass))
124 if (config->shouldPrintAfterOnlyOnChange())
125 beforePassFingerPrints.try_emplace(pass, op);
127 config->printBeforeIfEnabled(pass, op, [&](raw_ostream &out) {
128 out <<
"// -----// IR Dump Before " << pass->
getName();
129 printIR(op, config->shouldPrintAtModuleScope(), out,
130 config->getOpPrintingFlags());
135 void IRPrinterInstrumentation::runAfterPass(
Pass *pass,
Operation *op) {
136 if (isa<OpToOpPassAdaptor>(pass))
140 if (config->shouldPrintAfterOnlyOnFailure())
145 if (config->shouldPrintAfterOnlyOnChange()) {
146 auto fingerPrintIt = beforePassFingerPrints.find(pass);
147 assert(fingerPrintIt != beforePassFingerPrints.end() &&
148 "expected valid fingerprint");
150 if (fingerPrintIt->second == OperationFingerPrint(op)) {
151 beforePassFingerPrints.erase(fingerPrintIt);
154 beforePassFingerPrints.erase(fingerPrintIt);
157 config->printAfterIfEnabled(pass, op, [&](raw_ostream &out) {
158 out <<
"// -----// IR Dump After " << pass->
getName();
159 printIR(op, config->shouldPrintAtModuleScope(), out,
160 config->getOpPrintingFlags());
165 void IRPrinterInstrumentation::runAfterPassFailed(
Pass *pass,
Operation *op) {
166 if (isa<OpToOpPassAdaptor>(pass))
168 if (config->shouldPrintAfterOnlyOnChange())
169 beforePassFingerPrints.erase(pass);
171 config->printAfterIfEnabled(pass, op, [&](raw_ostream &out) {
172 out << formatv(
"// -----// IR Dump After {0} Failed", pass->
getName());
184 bool printAfterOnlyOnChange,
185 bool printAfterOnlyOnFailure,
187 : printModuleScope(printModuleScope),
188 printAfterOnlyOnChange(printAfterOnlyOnChange),
189 printAfterOnlyOnFailure(printAfterOnlyOnFailure),
190 opPrintingFlags(opPrintingFlags) {}
218 BasicIRPrinterConfig(
219 std::function<
bool(
Pass *,
Operation *)> shouldPrintBeforePass,
220 std::function<
bool(
Pass *,
Operation *)> shouldPrintAfterPass,
221 bool printModuleScope,
bool printAfterOnlyOnChange,
225 printAfterOnlyOnFailure, opPrintingFlags),
226 shouldPrintBeforePass(std::move(shouldPrintBeforePass)),
227 shouldPrintAfterPass(std::move(shouldPrintAfterPass)), out(out) {
228 assert((this->shouldPrintBeforePass || this->shouldPrintAfterPass) &&
229 "expected at least one valid filter function");
234 if (shouldPrintBeforePass && shouldPrintBeforePass(pass, operation))
240 if (shouldPrintAfterPass && shouldPrintAfterPass(pass, operation))
245 std::function<bool(Pass *, Operation *)> shouldPrintBeforePass;
246 std::function<bool(Pass *, Operation *)> shouldPrintAfterPass;
256 if (config->shouldPrintAtModuleScope() &&
258 llvm::report_fatal_error(
"IR printing can't be setup on a pass-manager " 259 "without disabling multi-threading first.");
261 std::make_unique<IRPrinterInstrumentation>(std::move(config)));
266 std::function<
bool(
Pass *,
Operation *)> shouldPrintBeforePass,
267 std::function<
bool(
Pass *,
Operation *)> shouldPrintAfterPass,
268 bool printModuleScope,
bool printAfterOnlyOnChange,
269 bool printAfterOnlyOnFailure, raw_ostream &out,
272 std::move(shouldPrintBeforePass), std::move(shouldPrintAfterPass),
273 printModuleScope, printAfterOnlyOnChange, printAfterOnlyOnFailure,
274 opPrintingFlags, out));
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
This class contains a list of basic blocks and a link to the parent operation it is attached to...
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
const void * getAsOpaquePointer() const
Methods for supporting PointerLikeTypeTraits.
Operation is a basic unit of execution within MLIR.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
operand_range getOperands()
Returns an iterator on the underlying Value's.
virtual ~IRPrinterConfig()
Block represents an ordered list of Operations.
void addInstrumentation(std::unique_ptr< PassInstrumentation > pi)
Add the provided instrumentation to the pass manager.
MLIRContext * getContext() const
Return an instance of the context.
AttrClass getAttrOfType(StringAttr name)
bool operator!=(StringAttr lhs, std::nullptr_t)
virtual StringRef getName() const =0
Returns the derived pass name.
unsigned getNumSuccessors()
void enableIRPrinting(std::unique_ptr< IRPrinterConfig > config)
Add an instrumentation to print the IR before and after pass execution, using the provided configurat...
Block * getBlock()
Returns the operation block that contains this operation.
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...
IRPrinterConfig(bool printModuleScope=false, bool printAfterOnlyOnChange=false, bool printAfterOnlyOnFailure=false, OpPrintingFlags opPrintingFlags=OpPrintingFlags())
Initialize the configuration.
std::enable_if< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT >::type walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one)...
Block * getSuccessor(unsigned index)
bool isMultithreadingEnabled()
Return true if multi-threading is enabled by the context.
Location getLoc()
The source location the operation was defined or derived from.
This class represents an argument of a Block.
void print(raw_ostream &os, const OpPrintingFlags &flags=llvm::None)
static void printIR(Operation *op, bool printModuleScope, raw_ostream &out, OpPrintingFlags flags)
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
OpPrintingFlags & useLocalScope()
Use local scope when printing the operation.
Set of flags used to control the behavior of the various IR print methods (e.g.
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...
The abstract base pass class.
PassInstrumentation provides several entry points into the pass manager infrastructure.
A configuration struct provided to the IR printer instrumentation.
OperationName getName()
The name of an operation is the key identifier for it.
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...