[Mlir-commits] [mlir] [MLIR][mlir-opt] add support for disabling diagnostics (PR #117669)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Nov 26 16:07:18 PST 2024


https://github.com/sfzhu93 updated https://github.com/llvm/llvm-project/pull/117669

>From 949540a1785d56f210f997b608aa3279655e0805 Mon Sep 17 00:00:00 2001
From: Shuofei Zhu <shuofei at meta.com>
Date: Mon, 25 Nov 2024 21:13:45 -0800
Subject: [PATCH 1/2] add support for disabling diagnostics

---
 mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h | 7 +++++++
 mlir/lib/Tools/mlir-opt/MlirOptMain.cpp        | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index ef976c1155795b..026026ac3b78d0 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -82,6 +82,9 @@ class MlirOptMainConfig {
     return *this;
   }
   bool shouldEmitBytecode() const { return emitBytecodeFlag; }
+
+  bool shouldDisableDiagnostic() const { return disableDiagnosticFlag; }
+
   bool shouldElideResourceDataFromBytecode() const {
     return elideResourceDataFromBytecodeFlag;
   }
@@ -208,6 +211,10 @@ class MlirOptMainConfig {
   /// Emit bytecode instead of textual assembly when generating output.
   bool emitBytecodeFlag = false;
 
+  /// Disable the diagnostic handlers. Warnings, errors, remarks, etc. will not
+  /// be printed.
+  bool disableDiagnosticFlag = false;
+
   /// Elide resources when generating bytecode.
   bool elideResourceDataFromBytecodeFlag = false;
 
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index 5a7b17672c518b..c307e1d6abfb0d 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -113,6 +113,10 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
         cl::desc("Enable Debugger hook for debugging MLIR Actions"),
         cl::location(enableDebuggerActionHookFlag), cl::init(false));
 
+    static cl::opt<bool, /*ExternalStorage=*/true> disableRemarkDiagnostic(
+        "mlir-disable-diagnostic", cl::desc("Disable diagnostic information"),
+        cl::location(disableDiagnosticFlag), cl::init(false));
+
     static cl::opt<bool, /*ExternalStorage=*/true> explicitModule(
         "no-implicit-module",
         cl::desc("Disable implicit addition of a top-level module op during "
@@ -473,6 +477,9 @@ static LogicalResult processBuffer(raw_ostream &os,
   // If we are in verify diagnostics mode then we have a lot of work to do,
   // otherwise just perform the actions without worrying about it.
   if (!config.shouldVerifyDiagnostics()) {
+    if (config.shouldDisableDiagnostic())
+      return performActions(os, sourceMgr, &context, config);
+
     SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &context);
     return performActions(os, sourceMgr, &context, config);
   }

>From 58575958a1f4cf99958a2ea8b6ff4082a4525b34 Mon Sep 17 00:00:00 2001
From: Shuofei Zhu <shuofei at meta.com>
Date: Tue, 26 Nov 2024 16:07:05 -0800
Subject: [PATCH 2/2] implement verbosity level

---
 .../include/mlir/Tools/mlir-opt/MlirOptMain.h | 56 ++++++++++-----
 mlir/lib/Tools/mlir-opt/MlirOptMain.cpp       | 72 ++++++++++++++++---
 2 files changed, 103 insertions(+), 25 deletions(-)

diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index 026026ac3b78d0..8796a5450e10d9 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -31,6 +31,13 @@ class DialectRegistry;
 class PassPipelineCLParser;
 class PassManager;
 
+/// enum class to indicate the verbosity level of the diagnostic filter.
+enum class VerbosityLevel {
+  ErrorsOnly = 0,
+  ErrorsAndWarnings,
+  ErrorsWarningsAndRemarks
+};
+
 /// Configuration options for the mlir-opt tool.
 /// This is intended to help building tools like mlir-opt by collecting the
 /// supported options.
@@ -74,6 +81,11 @@ class MlirOptMainConfig {
     dumpPassPipelineFlag = dump;
     return *this;
   }
+
+  VerbosityLevel getDiagnosticVerbosityLevel() const {
+    return diagnosticVerbosityLevelFlag;
+  }
+
   bool shouldDumpPassPipeline() const { return dumpPassPipelineFlag; }
 
   /// Set the output format to bytecode instead of textual IR.
@@ -83,12 +95,12 @@ class MlirOptMainConfig {
   }
   bool shouldEmitBytecode() const { return emitBytecodeFlag; }
 
-  bool shouldDisableDiagnostic() const { return disableDiagnosticFlag; }
-
   bool shouldElideResourceDataFromBytecode() const {
     return elideResourceDataFromBytecodeFlag;
   }
 
+  bool shouldShowNotes() const { return !disableDiagnosticNotesFlag; }
+
   /// Set the IRDL file to load before processing the input.
   MlirOptMainConfig &setIrdlFile(StringRef file) {
     irdlFileFlag = file;
@@ -171,8 +183,9 @@ class MlirOptMainConfig {
   }
   bool shouldUseExplicitModule() const { return useExplicitModuleFlag; }
 
-  /// Set whether to check that emitted diagnostics match `expected-*` lines on
-  /// the corresponding line. This is meant for implementing diagnostic tests.
+  /// Set whether to check that emitted diagnostics match `expected-*` lines
+  /// on the corresponding line. This is meant for implementing diagnostic
+  /// tests.
   MlirOptMainConfig &verifyDiagnostics(bool verify) {
     verifyDiagnosticsFlag = verify;
     return *this;
@@ -205,16 +218,17 @@ class MlirOptMainConfig {
   /// Configuration for the debugging hooks.
   tracing::DebugConfig debugConfig;
 
+  /// Verbosity level of diagnostic information. 0: Errors only,
+  /// 1: Errors and warnings, 2: Errors, warnings and remarks.
+  VerbosityLevel diagnosticVerbosityLevelFlag =
+      VerbosityLevel::ErrorsAndWarnings;
+
   /// Print the pipeline that will be run.
   bool dumpPassPipelineFlag = false;
 
   /// Emit bytecode instead of textual assembly when generating output.
   bool emitBytecodeFlag = false;
 
-  /// Disable the diagnostic handlers. Warnings, errors, remarks, etc. will not
-  /// be printed.
-  bool disableDiagnosticFlag = false;
-
   /// Elide resources when generating bytecode.
   bool elideResourceDataFromBytecodeFlag = false;
 
@@ -242,6 +256,11 @@ class MlirOptMainConfig {
   /// Show the registered dialects before trying to load the input file.
   bool showDialectsFlag = false;
 
+  /// Show the notes in diagnostic information. Notes can be included in
+  /// any diagnostic information, so it is not specified in the verbosity
+  /// level.
+  bool disableDiagnosticNotesFlag = true;
+
   /// Split the input file based on the given marker into chunks and process
   /// each chunk independently. Input is not split if empty.
   std::string splitInputFileFlag = "";
@@ -252,8 +271,9 @@ class MlirOptMainConfig {
   /// Use an explicit top-level module op during parsing.
   bool useExplicitModuleFlag = false;
 
-  /// Set whether to check that emitted diagnostics match `expected-*` lines on
-  /// the corresponding line. This is meant for implementing diagnostic tests.
+  /// Set whether to check that emitted diagnostics match `expected-*` lines
+  /// on the corresponding line. This is meant for implementing diagnostic
+  /// tests.
   bool verifyDiagnosticsFlag = false;
 
   /// Run the verifier after each transformation pass.
@@ -267,13 +287,14 @@ class MlirOptMainConfig {
 };
 
 /// This defines the function type used to setup the pass manager. This can be
-/// used to pass in a callback to setup a default pass pipeline to be applied on
-/// the loaded IR.
+/// used to pass in a callback to setup a default pass pipeline to be applied
+/// on the loaded IR.
 using PassPipelineFn = llvm::function_ref<LogicalResult(PassManager &pm)>;
 
 /// Register and parse command line options.
 /// - toolName is used for the header displayed by `--help`.
-/// - registry should contain all the dialects that can be parsed in the source.
+/// - registry should contain all the dialects that can be parsed in the
+/// source.
 /// - return std::pair<std::string, std::string> for
 ///   inputFilename and outputFilename command line option values.
 std::pair<std::string, std::string>
@@ -283,7 +304,8 @@ registerAndParseCLIOptions(int argc, char **argv, llvm::StringRef toolName,
 /// Perform the core processing behind `mlir-opt`.
 /// - outputStream is the stream where the resulting IR is printed.
 /// - buffer is the in-memory file to parser and process.
-/// - registry should contain all the dialects that can be parsed in the source.
+/// - registry should contain all the dialects that can be parsed in the
+/// source.
 /// - config contains the configuration options for the tool.
 LogicalResult MlirOptMain(llvm::raw_ostream &outputStream,
                           std::unique_ptr<llvm::MemoryBuffer> buffer,
@@ -292,7 +314,8 @@ LogicalResult MlirOptMain(llvm::raw_ostream &outputStream,
 
 /// Implementation for tools like `mlir-opt`.
 /// - toolName is used for the header displayed by `--help`.
-/// - registry should contain all the dialects that can be parsed in the source.
+/// - registry should contain all the dialects that can be parsed in the
+/// source.
 LogicalResult MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
                           DialectRegistry &registry);
 
@@ -301,7 +324,8 @@ LogicalResult MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
 /// CLI options can be accessed before running MlirOptMain.
 /// - inputFilename is the name of the input mlir file.
 /// - outputFilename is the name of the output file.
-/// - registry should contain all the dialects that can be parsed in the source.
+/// - registry should contain all the dialects that can be parsed in the
+/// source.
 LogicalResult MlirOptMain(int argc, char **argv, llvm::StringRef inputFilename,
                           llvm::StringRef outputFilename,
                           DialectRegistry &registry);
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index c307e1d6abfb0d..4a613fe9c8ca1d 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -41,6 +41,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/LogicalResult.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Regex.h"
@@ -108,15 +109,28 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
         cl::desc("IRDL file to register before processing the input"),
         cl::location(irdlFileFlag), cl::init(""), cl::value_desc("filename"));
 
+    static cl::opt<VerbosityLevel, /*ExternalStorage=*/true>
+        diagnosticVerbosityLevel(
+            "mlir-diagnostic-verbosity-level",
+            cl::desc("Choose level of diagnostic information"),
+            cl::location(diagnosticVerbosityLevelFlag),
+            cl::init(VerbosityLevel::ErrorsAndWarnings),
+            cl::values(
+                clEnumValN(VerbosityLevel::ErrorsOnly, "errors", "Errors only"),
+                clEnumValN(VerbosityLevel::ErrorsAndWarnings, "warnings",
+                           "Errors and warnings"),
+                clEnumValN(VerbosityLevel::ErrorsWarningsAndRemarks, "remarks",
+                           "Errors, warnings and remarks")));
+
+    static cl::opt<bool, /*ExternalStorage=*/true> disableDiagnosticNotes(
+        "mlir-disable-diagnostic-notes", cl::desc("Disable diagnostic notes."),
+        cl::location(disableDiagnosticNotesFlag), cl::init(false));
+
     static cl::opt<bool, /*ExternalStorage=*/true> enableDebuggerHook(
         "mlir-enable-debugger-hook",
         cl::desc("Enable Debugger hook for debugging MLIR Actions"),
         cl::location(enableDebuggerActionHookFlag), cl::init(false));
 
-    static cl::opt<bool, /*ExternalStorage=*/true> disableRemarkDiagnostic(
-        "mlir-disable-diagnostic", cl::desc("Disable diagnostic information"),
-        cl::location(disableDiagnosticFlag), cl::init(false));
-
     static cl::opt<bool, /*ExternalStorage=*/true> explicitModule(
         "no-implicit-module",
         cl::desc("Disable implicit addition of a top-level module op during "
@@ -137,7 +151,8 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
         cl::location(showDialectsFlag), cl::init(false));
 
     static cl::opt<std::string, /*ExternalStorage=*/true> splitInputFile{
-        "split-input-file", llvm::cl::ValueOptional,
+        "split-input-file",
+        llvm::cl::ValueOptional,
         cl::callback([&](const std::string &str) {
           // Implicit value: use default marker if flag was used without value.
           if (str.empty())
@@ -145,7 +160,8 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
         }),
         cl::desc("Split the input file into chunks using the given or "
                  "default marker and process each chunk independently"),
-        cl::location(splitInputFileFlag), cl::init("")};
+        cl::location(splitInputFileFlag),
+        cl::init("")};
 
     static cl::opt<std::string, /*ExternalStorage=*/true> outputSplitMarker(
         "output-split-marker",
@@ -206,6 +222,44 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
   /// setDialectPluginsCallback(DialectRegistry&).
   cl::list<std::string> *dialectPlugins = nullptr;
 };
+
+/// A scoped diagnostic handler that suppresses certain diagnostics based on
+/// the verbosity level and whether the diagnostic is a note.
+class DiagnosticFilter : public ScopedDiagnosticHandler {
+public:
+  DiagnosticFilter(MLIRContext *ctx, VerbosityLevel verbosityLevel,
+                   bool showNotes = true)
+      : ScopedDiagnosticHandler(ctx) {
+    setHandler([verbosityLevel, showNotes](Diagnostic &diag) {
+      auto severity = diag.getSeverity();
+      switch (severity) {
+      case DiagnosticSeverity::Error:
+        // failure indicates that the error is not handled by the filter and
+        // goes through to the default handler. Therefore, the error can be
+        // successfully printed.
+        return failure();
+      case DiagnosticSeverity::Warning:
+        if (verbosityLevel == VerbosityLevel::ErrorsOnly)
+          return success();
+        else
+          return failure();
+      case DiagnosticSeverity::Remark:
+        if (verbosityLevel == VerbosityLevel::ErrorsOnly ||
+            verbosityLevel == VerbosityLevel::ErrorsAndWarnings)
+          return success();
+        else
+          return failure();
+      case DiagnosticSeverity::Note:
+        if (showNotes)
+          return failure();
+        else
+          return success();
+      default:
+        llvm_unreachable("Unknown diagnostic severity");
+      }
+    });
+  }
+};
 } // namespace
 
 ManagedStatic<MlirOptMainConfigCLOptions> clOptionsConfig;
@@ -477,10 +531,10 @@ static LogicalResult processBuffer(raw_ostream &os,
   // If we are in verify diagnostics mode then we have a lot of work to do,
   // otherwise just perform the actions without worrying about it.
   if (!config.shouldVerifyDiagnostics()) {
-    if (config.shouldDisableDiagnostic())
-      return performActions(os, sourceMgr, &context, config);
-
     SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &context);
+    DiagnosticFilter diagnosticFilter(&context,
+                                      config.getDiagnosticVerbosityLevel(),
+                                      config.shouldShowNotes());
     return performActions(os, sourceMgr, &context, config);
   }
 



More information about the Mlir-commits mailing list