Skip to content

Commit 3532e16

Browse files
committed
[mlir] Add comment for failed verification in print.
While we have debug output explaining verification failure, many users are confused when they first encounter this/most folks don't run with --debug. Move the checking such that we can emit a comment explaining why/make it more discoverable.
1 parent ca84f2a commit 3532e16

File tree

2 files changed

+54
-35
lines changed

2 files changed

+54
-35
lines changed

mlir/lib/IR/AsmPrinter.cpp

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,12 +1941,43 @@ void FallbackAsmResourceMap::ResourceCollection::buildResources(
19411941

19421942
namespace mlir {
19431943
namespace detail {
1944+
1945+
/// Verifies the operation and switches to generic op printing if verification
1946+
/// fails. We need to do this because custom print functions may fail/crash for
1947+
/// invalid ops.
1948+
static void verifyOpAndAdjustFlags(Operation *op, OpPrintingFlags &printerFlags,
1949+
bool &failedVerification) {
1950+
if (printerFlags.shouldPrintGenericOpForm() ||
1951+
printerFlags.shouldAssumeVerified())
1952+
return;
1953+
1954+
// Ignore errors emitted by the verifier. We check the thread id to avoid
1955+
// consuming other threads' errors.
1956+
auto parentThreadId = llvm::get_threadid();
1957+
ScopedDiagnosticHandler diagHandler(op->getContext(), [&](Diagnostic &diag) {
1958+
if (parentThreadId == llvm::get_threadid()) {
1959+
LLVM_DEBUG({
1960+
diag.print(llvm::dbgs());
1961+
llvm::dbgs() << "\n";
1962+
});
1963+
return success();
1964+
}
1965+
return failure();
1966+
});
1967+
if (failed(verify(op))) {
1968+
printerFlags.printGenericOpForm();
1969+
failedVerification = true;
1970+
}
1971+
}
1972+
19441973
class AsmStateImpl {
19451974
public:
19461975
explicit AsmStateImpl(Operation *op, const OpPrintingFlags &printerFlags,
19471976
AsmState::LocationMap *locationMap)
19481977
: interfaces(op->getContext()), nameState(op, printerFlags),
1949-
printerFlags(printerFlags), locationMap(locationMap) {}
1978+
printerFlags(printerFlags), locationMap(locationMap) {
1979+
verifyOpAndAdjustFlags(op, this->printerFlags, failedVerification);
1980+
}
19501981
explicit AsmStateImpl(MLIRContext *ctx, const OpPrintingFlags &printerFlags,
19511982
AsmState::LocationMap *locationMap)
19521983
: interfaces(ctx), printerFlags(printerFlags), locationMap(locationMap) {}
@@ -1998,6 +2029,8 @@ class AsmStateImpl {
19982029

19992030
void popCyclicPrinting() { cyclicPrintingStack.pop_back(); }
20002031

2032+
bool verificationFailed() const { return failedVerification; }
2033+
20012034
private:
20022035
/// Collection of OpAsm interfaces implemented in the context.
20032036
DialectInterfaceCollection<OpAsmDialectInterface> interfaces;
@@ -2020,6 +2053,10 @@ class AsmStateImpl {
20202053
/// Flags that control op output.
20212054
OpPrintingFlags printerFlags;
20222055

2056+
/// Whether the operation from which the AsmState was created, failed
2057+
/// verification.
2058+
bool failedVerification = false;
2059+
20232060
/// An optional location map to be populated.
20242061
AsmState::LocationMap *locationMap;
20252062

@@ -2047,41 +2084,9 @@ void printDimensionList(raw_ostream &stream, Range &&shape) {
20472084
} // namespace detail
20482085
} // namespace mlir
20492086

2050-
/// Verifies the operation and switches to generic op printing if verification
2051-
/// fails. We need to do this because custom print functions may fail for
2052-
/// invalid ops.
2053-
static OpPrintingFlags verifyOpAndAdjustFlags(Operation *op,
2054-
OpPrintingFlags printerFlags) {
2055-
if (printerFlags.shouldPrintGenericOpForm() ||
2056-
printerFlags.shouldAssumeVerified())
2057-
return printerFlags;
2058-
2059-
// Ignore errors emitted by the verifier. We check the thread id to avoid
2060-
// consuming other threads' errors.
2061-
auto parentThreadId = llvm::get_threadid();
2062-
ScopedDiagnosticHandler diagHandler(op->getContext(), [&](Diagnostic &diag) {
2063-
if (parentThreadId == llvm::get_threadid()) {
2064-
LLVM_DEBUG({
2065-
diag.print(llvm::dbgs());
2066-
llvm::dbgs() << "\n";
2067-
});
2068-
return success();
2069-
}
2070-
return failure();
2071-
});
2072-
if (failed(verify(op))) {
2073-
LDBG() << op->getName()
2074-
<< "' failed to verify and will be printed in generic form";
2075-
printerFlags.printGenericOpForm();
2076-
}
2077-
2078-
return printerFlags;
2079-
}
2080-
20812087
AsmState::AsmState(Operation *op, const OpPrintingFlags &printerFlags,
20822088
LocationMap *locationMap, FallbackAsmResourceMap *map)
2083-
: impl(std::make_unique<AsmStateImpl>(
2084-
op, verifyOpAndAdjustFlags(op, printerFlags), locationMap)) {
2089+
: impl(std::make_unique<AsmStateImpl>(op, printerFlags, locationMap)) {
20852090
if (map)
20862091
attachFallbackResourcePrinter(*map);
20872092
}
@@ -3245,7 +3250,8 @@ class OperationPrinter : public AsmPrinter::Impl, private OpAsmPrinter {
32453250
using Impl::printType;
32463251

32473252
explicit OperationPrinter(raw_ostream &os, AsmStateImpl &state)
3248-
: Impl(os, state), OpAsmPrinter(static_cast<Impl &>(*this)) {}
3253+
: Impl(os, state), OpAsmPrinter(static_cast<Impl &>(*this)),
3254+
verificationFailed(state.verificationFailed()) {}
32493255

32503256
/// Print the given top-level operation.
32513257
void printTopLevelOperation(Operation *op);
@@ -3433,10 +3439,19 @@ class OperationPrinter : public AsmPrinter::Impl, private OpAsmPrinter {
34333439

34343440
// This is the current indentation level for nested structures.
34353441
unsigned currentIndent = 0;
3442+
3443+
/// Whether the operation from which the AsmState was created, failed
3444+
/// verification.
3445+
bool verificationFailed = false;
34363446
};
34373447
} // namespace
34383448

34393449
void OperationPrinter::printTopLevelOperation(Operation *op) {
3450+
if (verificationFailed) {
3451+
os << "// '" << op->getName()
3452+
<< "' failed to verify and will be printed in generic form\n";
3453+
}
3454+
34403455
// Output the aliases at the top level that can't be deferred.
34413456
state.getAliasState().printNonDeferredAliases(*this, newLine);
34423457

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: mlir-opt --mlir-very-unsafe-disable-verifier-on-parsing %s | FileCheck %s
2+
3+
// CHECK: // 'builtin.module' failed to verify and will be printed in generic form
4+
func.func @foo() -> tensor<10xi32> { return }

0 commit comments

Comments
 (0)