Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mlir] Add metadata to Diagnostic. #99398

Merged
merged 11 commits into from
Jul 25, 2024
12 changes: 11 additions & 1 deletion mlir/docs/Diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,19 @@ InFlightDiagnostic Operation::emitOpError();
## Diagnostic

A `Diagnostic` in MLIR contains all of the necessary information for reporting a
message to the user. A `Diagnostic` essentially boils down to three main
message to the user. A `Diagnostic` essentially boils down to four main
components:

* [Source Location](#source-locations)
* Severity Level
- Error, Note, Remark, Warning
* Diagnostic Arguments
- The diagnostic arguments are used when constructing the output message.
* Metadata
- Some additional information attached that can be used to identify
this diagnostic other than source location and severity level
(e.g. for diagnostic handlers to do some filtering).
Metadata is not part of the output message.

### Appending arguments

Expand Down Expand Up @@ -143,6 +148,11 @@ op->emitError("...").attachNote(noteLoc) << "...";
op->emitError("...").attachNote() << "...";
```

### Managing Metadata
Metadata is a mutable vector of DiagnosticArguments.
It can be accessed and modified as a vector.


## InFlight Diagnostic

Now that [Diagnostics](#diagnostic) have been explained, we introduce the
Expand Down
6 changes: 6 additions & 0 deletions mlir/include/mlir/IR/Diagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ class Diagnostic {
return failure();
}

/// Returns the current list of diagnostic metadata.
SmallVectorImpl<DiagnosticArgument> &getMetadata() { return metadata; }

private:
Diagnostic(const Diagnostic &rhs) = delete;
Diagnostic &operator=(const Diagnostic &rhs) = delete;
Expand All @@ -290,6 +293,9 @@ class Diagnostic {

/// A list of attached notes.
NoteVector notes;

/// A list of metadata attached to this Diagnostic.
SmallVector<DiagnosticArgument, 0> metadata;
};

inline raw_ostream &operator<<(raw_ostream &os, const Diagnostic &diag) {
Expand Down
19 changes: 19 additions & 0 deletions mlir/test/IR/diagnostic-handler-metadata.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(test-diagnostic-metadata))" -verify-diagnostics -o - 2>&1 | FileCheck %s
// COM: This test verifies that diagnostic handler can filter the diagnostic based on its metadata
// COM: whether to emit the errors.

// CHECK-LABEL: Test 'test'
func.func @test() {
// expected-error @+1 {{test diagnostic metadata}}
"test.emit_error"() {
// CHECK: attr = "emit_error"
attr = "emit_error"
} : () -> ()

"test.do_not_emit_error"() {
// CHECK: attr = "do_not_emit_error"
attr = "do_not_emit_error"
} : () -> ()

return
}
1 change: 1 addition & 0 deletions mlir/test/lib/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_mlir_library(MLIRTestIR
TestBuiltinDistinctAttributes.cpp
TestClone.cpp
TestDiagnostics.cpp
TestDiagnosticsMetadata.cpp
TestDominance.cpp
TestFunc.cpp
TestInterfaces.cpp
Expand Down
65 changes: 65 additions & 0 deletions mlir/test/lib/IR/TestDiagnosticsMetadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//===- TestDiagnosticsMetadata.cpp - Test Diagnostic Metatdata ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains test passes for constructing and resolving dominance
// information.
//
//===----------------------------------------------------------------------===//

#include "mlir/IR/SymbolTable.h"
#include "mlir/Pass/Pass.h"
#include "llvm/Support/SourceMgr.h"

using namespace mlir;

namespace {
struct TestDiagnosticMetadataPass
: public PassWrapper<TestDiagnosticMetadataPass,
InterfacePass<SymbolOpInterface>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDiagnosticMetadataPass)

StringRef getArgument() const final { return "test-diagnostic-metadata"; }
StringRef getDescription() const final { return "Test diagnostic metadata."; }
TestDiagnosticMetadataPass() = default;
TestDiagnosticMetadataPass(const TestDiagnosticMetadataPass &) {}

void runOnOperation() override {
llvm::errs() << "Test '" << getOperation().getName() << "'\n";

// Build a diagnostic handler that has filtering capabilities.
ScopedDiagnosticHandler handler(&getContext(), [](mlir::Diagnostic &diag) {
return mlir::success(
llvm::none_of(diag.getMetadata(), [](mlir::DiagnosticArgument &arg) {
return arg.getKind() == mlir::DiagnosticArgument::
DiagnosticArgumentKind::String &&
arg.getAsString().contains("hello");
}));
});

// Emit a diagnostic for every operation with a valid loc.
getOperation()->walk([&](Operation *op) {
if (StringAttr strAttr = op->getAttrOfType<StringAttr>("attr")) {
if (strAttr.getValue() == "emit_error")
emitError(op->getLoc(), "test diagnostic metadata")
.getUnderlyingDiagnostic()
->getMetadata()
.push_back(DiagnosticArgument("hello"));
}
});
}
};

} // namespace

namespace mlir {
namespace test {
void registerTestDiagnosticsMetadataPass() {
PassRegistration<TestDiagnosticMetadataPass>{};
}
} // namespace test
} // namespace mlir
2 changes: 2 additions & 0 deletions mlir/tools/mlir-opt/mlir-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ void registerTestDataLayoutQuery();
void registerTestDeadCodeAnalysisPass();
void registerTestDecomposeCallGraphTypes();
void registerTestDiagnosticsPass();
void registerTestDiagnosticsMetadataPass();
void registerTestDominancePass();
void registerTestDynamicPipelinePass();
void registerTestEmulateNarrowTypePass();
Expand Down Expand Up @@ -226,6 +227,7 @@ void registerTestPasses() {
mlir::test::registerTestDeadCodeAnalysisPass();
mlir::test::registerTestDecomposeCallGraphTypes();
mlir::test::registerTestDiagnosticsPass();
mlir::test::registerTestDiagnosticsMetadataPass();
mlir::test::registerTestDominancePass();
mlir::test::registerTestDynamicPipelinePass();
mlir::test::registerTestEmulateNarrowTypePass();
Expand Down