[Mlir-commits] [mlir] [MLIR] Add remark flags to mlir-opt (PR #156825)
Guray Ozen
llvmlistbot at llvm.org
Mon Sep 8 07:24:01 PDT 2025
https://github.com/grypp updated https://github.com/llvm/llvm-project/pull/156825
>From a3e2893fd9dc72f0bfabd5be414c2b666367787b Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Thu, 4 Sep 2025 10:26:33 +0200
Subject: [PATCH 1/6] [MLIR] Add remark flags to mlir-opt
---
.../include/mlir/Tools/mlir-opt/MlirOptMain.h | 22 +++++
mlir/lib/Tools/mlir-opt/CMakeLists.txt | 1 +
mlir/lib/Tools/mlir-opt/MlirOptMain.cpp | 88 +++++++++++++++++--
mlir/unittests/IR/CMakeLists.txt | 2 +-
4 files changed, 103 insertions(+), 10 deletions(-)
diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index 94231227599c9..dc6a6a1c3cc42 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -38,6 +38,12 @@ enum class VerbosityLevel {
ErrorsWarningsAndRemarks
};
+using RemarkFormat = enum {
+ REMARK_FORMAT_STDOUT,
+ REMARK_FORMAT_YAML,
+ REMARK_FORMAT_BITSTREAM,
+};
+
/// Configuration options for the mlir-opt tool.
/// This is intended to help building tools like mlir-opt by collecting the
/// supported options.
@@ -221,9 +227,25 @@ class MlirOptMainConfig {
}
bool shouldVerifyRoundtrip() const { return verifyRoundtripFlag; }
+ /// Checks if any remark filters are set.
+ bool shouldEmitRemarks() const {
+ // Emit all remarks only when no filters are specified.
+ const bool hasFilters =
+ !remarksPassedFlag.empty() || !remarksFailedFlag.empty() ||
+ !remarksMissedFlag.empty() || !remarksAnalyseFlag.empty();
+ return hasFilters;
+ }
+
/// Reproducer file generation (no crash required).
StringRef getReproducerFilename() const { return generateReproducerFileFlag; }
+ /// Remark options
+ RemarkFormat remarkFormatFlag;
+ std::string remarksPassedFlag = "";
+ std::string remarksFailedFlag = "";
+ std::string remarksMissedFlag = "";
+ std::string remarksAnalyseFlag = "";
+
protected:
/// Allow operation with no registered dialects.
/// This option is for convenience during testing only and discouraged in
diff --git a/mlir/lib/Tools/mlir-opt/CMakeLists.txt b/mlir/lib/Tools/mlir-opt/CMakeLists.txt
index f24d4c60174ee..858c9c1f97f9c 100644
--- a/mlir/lib/Tools/mlir-opt/CMakeLists.txt
+++ b/mlir/lib/Tools/mlir-opt/CMakeLists.txt
@@ -13,4 +13,5 @@ add_mlir_library(MLIROptLib
MLIRPluginsLib
MLIRSupport
MLIRIRDL
+ MLIRRemarkStreamer
)
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index de714d8b740af..c456540cc1793 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -23,9 +23,11 @@
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Remarks.h"
#include "mlir/Parser/Parser.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Pass/PassRegistry.h"
+#include "mlir/Remark/RemarkStreamer.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Support/Timing.h"
#include "mlir/Support/ToolUtilities.h"
@@ -33,6 +35,7 @@
#include "mlir/Tools/Plugins/DialectPlugin.h"
#include "mlir/Tools/Plugins/PassPlugin.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/LogicalResult.h"
@@ -204,6 +207,41 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
cl::location(generateReproducerFileFlag), cl::init(""),
cl::value_desc("filename"));
+ static cl::OptionCategory remarkCategory(
+ "Remark Options",
+ "Filter remarks by regular expression (llvm::Regex syntax).");
+
+ static llvm::cl::opt<RemarkFormat, /*ExternalStorage=*/true> remarkFormat{
+ "remark-format",
+ llvm::cl::desc("Specify the format for remark output."),
+ cl::location(remarkFormatFlag),
+ llvm::cl::value_desc("format"),
+ llvm::cl::init(REMARK_FORMAT_STDOUT),
+ llvm::cl::values(
+ clEnumValN(REMARK_FORMAT_STDOUT, "emitRemark",
+ "Print as emitRemark to command-line"),
+ clEnumValN(REMARK_FORMAT_YAML, "yaml", "Print yaml file"),
+ clEnumValN(REMARK_FORMAT_BITSTREAM, "bitstream",
+ "Print bitstream file")),
+ llvm::cl::cat(remarkCategory)};
+
+ static cl::opt<std::string, /*ExternalStorage=*/true> remarksPassed(
+ "remarks-passed", cl::desc("Show passed remarks"),
+ cl::location(remarksPassedFlag), cl::init(""), cl::cat(remarkCategory));
+
+ static cl::opt<std::string, /*ExternalStorage=*/true> remarksFailed(
+ "remarks-failed", cl::desc("Show failed remarks"),
+ cl::location(remarksFailedFlag), cl::init(""), cl::cat(remarkCategory));
+
+ static cl::opt<std::string, /*ExternalStorage=*/true> remarksMissed(
+ "remarks-missed", cl::desc("Show missed remarks"),
+ cl::location(remarksMissedFlag), cl::init(""), cl::cat(remarkCategory));
+
+ static cl::opt<std::string, /*ExternalStorage=*/true> remarksAnalyse(
+ "remarks-analyse", cl::desc("Show analysis remarks"),
+ cl::location(remarksAnalyseFlag), cl::init(""),
+ cl::cat(remarkCategory));
+
/// Set the callback to load a pass plugin.
passPlugins.setCallback([&](const std::string &pluginPath) {
auto plugin = PassPlugin::load(pluginPath);
@@ -241,23 +279,23 @@ class DiagnosticFilter : public ScopedDiagnosticHandler {
setHandler([verbosityLevel, showNotes](Diagnostic &diag) {
auto severity = diag.getSeverity();
switch (severity) {
- case DiagnosticSeverity::Error:
+ case mlir::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:
+ case mlir::DiagnosticSeverity::Warning:
if (verbosityLevel == VerbosityLevel::ErrorsOnly)
return success();
else
return failure();
- case DiagnosticSeverity::Remark:
+ case mlir::DiagnosticSeverity::Remark:
if (verbosityLevel == VerbosityLevel::ErrorsOnly ||
verbosityLevel == VerbosityLevel::ErrorsAndWarnings)
return success();
else
return failure();
- case DiagnosticSeverity::Note:
+ case mlir::DiagnosticSeverity::Note:
if (showNotes)
return failure();
else
@@ -462,6 +500,38 @@ performActions(raw_ostream &os,
context->enableMultithreading(wasThreadingEnabled);
+ // Set up optimization remarks.
+ if (config.shouldEmitRemarks()) {
+ remark::RemarkCategories cats{
+ config.remarksPassedFlag, config.remarksFailedFlag,
+ config.remarksMissedFlag, config.remarksAnalyseFlag};
+
+ mlir::MLIRContext &ctx = *context;
+
+ switch (config.remarkFormatFlag) {
+ case REMARK_FORMAT_STDOUT:
+ if (failed(mlir::remark::enableOptimizationRemarks(ctx, nullptr, cats)))
+ return failure();
+ break;
+
+ case REMARK_FORMAT_YAML: {
+ constexpr llvm::StringLiteral file{"mlir-remarks.yaml"};
+ if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
+ ctx, file, llvm::remarks::Format::YAML, cats)))
+ return failure();
+ break;
+ }
+
+ case REMARK_FORMAT_BITSTREAM: {
+ constexpr llvm::StringLiteral File{"mlir-remarks.bitstream"};
+ if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
+ ctx, File, llvm::remarks::Format::Bitstream, cats)))
+ return failure();
+ break;
+ }
+ }
+ }
+
// Prepare the pass manager, applying command-line and reproducer options.
PassManager pm(op.get()->getName(), PassManager::Nesting::Implicit);
pm.enableVerifier(config.shouldVerifyPasses());
@@ -523,8 +593,8 @@ processBuffer(raw_ostream &os, std::unique_ptr<MemoryBuffer> ownedBuffer,
SMLoc());
sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc());
- // Create a context just for the current buffer. Disable threading on creation
- // since we'll inject the thread-pool separately.
+ // Create a context just for the current buffer. Disable threading on
+ // creation since we'll inject the thread-pool separately.
MLIRContext context(registry, MLIRContext::Threading::DISABLED);
if (threadPool)
context.setThreadPool(*threadPool);
@@ -669,9 +739,9 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv,
if (config.shouldListPasses())
return printRegisteredPassesAndReturn();
- // When reading from stdin and the input is a tty, it is often a user mistake
- // and the process "appears to be stuck". Print a message to let the user know
- // about it!
+ // When reading from stdin and the input is a tty, it is often a user
+ // mistake and the process "appears to be stuck". Print a message to let the
+ // user know about it!
if (inputFilename == "-" &&
sys::Process::FileDescriptorIsDisplayed(fileno(stdin)))
llvm::errs() << "(processing input from stdin now, hit ctrl-c/ctrl-d to "
diff --git a/mlir/unittests/IR/CMakeLists.txt b/mlir/unittests/IR/CMakeLists.txt
index 75cd2d65ef5a1..dd3b110dcd295 100644
--- a/mlir/unittests/IR/CMakeLists.txt
+++ b/mlir/unittests/IR/CMakeLists.txt
@@ -14,7 +14,7 @@ add_mlir_unittest(MLIRIRTests
MemrefLayoutTest.cpp
OperationSupportTest.cpp
PatternMatchTest.cpp
- RemarkTest.cpp
+ RemarkTest.cpp
ShapedTypeTest.cpp
SymbolTableTest.cpp
TypeTest.cpp
>From a9a0b54c002278998a26cfc1d2474c6c2ad443df Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Thu, 4 Sep 2025 14:30:54 +0200
Subject: [PATCH 2/6] add test
---
.../include/mlir/Tools/mlir-opt/MlirOptMain.h | 6 +-
mlir/lib/Tools/mlir-opt/MlirOptMain.cpp | 26 ++++--
mlir/test/Pass/remarks.mlir | 48 +++++++++++
mlir/test/lib/Pass/CMakeLists.txt | 1 +
mlir/test/lib/Pass/TestRemarksPipeline.cpp | 80 +++++++++++++++++++
mlir/tools/mlir-opt/mlir-opt.cpp | 2 +
6 files changed, 156 insertions(+), 7 deletions(-)
create mode 100644 mlir/test/Pass/remarks.mlir
create mode 100644 mlir/test/lib/Pass/TestRemarksPipeline.cpp
diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index dc6a6a1c3cc42..73eeb88bf9f09 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -231,8 +231,9 @@ class MlirOptMainConfig {
bool shouldEmitRemarks() const {
// Emit all remarks only when no filters are specified.
const bool hasFilters =
- !remarksPassedFlag.empty() || !remarksFailedFlag.empty() ||
- !remarksMissedFlag.empty() || !remarksAnalyseFlag.empty();
+ !remarksAllFlag.empty() || !remarksPassedFlag.empty() ||
+ !remarksFailedFlag.empty() || !remarksMissedFlag.empty() ||
+ !remarksAnalyseFlag.empty();
return hasFilters;
}
@@ -241,6 +242,7 @@ class MlirOptMainConfig {
/// Remark options
RemarkFormat remarkFormatFlag;
+ std::string remarksAllFlag = "";
std::string remarksPassedFlag = "";
std::string remarksFailedFlag = "";
std::string remarksMissedFlag = "";
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index c456540cc1793..0558ffaa4b7b1 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -225,6 +225,11 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
"Print bitstream file")),
llvm::cl::cat(remarkCategory)};
+ static cl::opt<std::string, /*ExternalStorage=*/true> remarksAll(
+ "remarks",
+ cl::desc("Show all remarks: passed, missed, failed, analysis"),
+ cl::location(remarksAllFlag), cl::init(""), cl::cat(remarkCategory));
+
static cl::opt<std::string, /*ExternalStorage=*/true> remarksPassed(
"remarks-passed", cl::desc("Show passed remarks"),
cl::location(remarksPassedFlag), cl::init(""), cl::cat(remarkCategory));
@@ -502,15 +507,26 @@ performActions(raw_ostream &os,
// Set up optimization remarks.
if (config.shouldEmitRemarks()) {
+ auto combine = [](const std::string &a, const std::string &b) {
+ if (a.empty())
+ return b;
+ if (b.empty())
+ return a;
+ return a + "|" + b;
+ };
+
remark::RemarkCategories cats{
- config.remarksPassedFlag, config.remarksFailedFlag,
- config.remarksMissedFlag, config.remarksAnalyseFlag};
+ combine(config.remarksAllFlag, config.remarksPassedFlag),
+ combine(config.remarksAllFlag, config.remarksMissedFlag),
+ combine(config.remarksAllFlag, config.remarksAnalyseFlag),
+ combine(config.remarksAllFlag, config.remarksFailedFlag)};
mlir::MLIRContext &ctx = *context;
switch (config.remarkFormatFlag) {
case REMARK_FORMAT_STDOUT:
- if (failed(mlir::remark::enableOptimizationRemarks(ctx, nullptr, cats)))
+ if (failed(mlir::remark::enableOptimizationRemarks(
+ ctx, nullptr, cats, true /*printAsEmitRemarks*/)))
return failure();
break;
@@ -523,9 +539,9 @@ performActions(raw_ostream &os,
}
case REMARK_FORMAT_BITSTREAM: {
- constexpr llvm::StringLiteral File{"mlir-remarks.bitstream"};
+ constexpr llvm::StringLiteral file{"mlir-remarks.bitstream"};
if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
- ctx, File, llvm::remarks::Format::Bitstream, cats)))
+ ctx, file, llvm::remarks::Format::Bitstream, cats)))
return failure();
break;
}
diff --git a/mlir/test/Pass/remarks.mlir b/mlir/test/Pass/remarks.mlir
new file mode 100644
index 0000000000000..548215e640006
--- /dev/null
+++ b/mlir/test/Pass/remarks.mlir
@@ -0,0 +1,48 @@
+// RUN: mlir-opt %s --test-remark-pipeline --remarks-passed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED
+// RUN: mlir-opt %s --test-remark-pipeline --remarks-missed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED
+// RUN: mlir-opt %s --test-remark-pipeline --remarks-failed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED
+// RUN: mlir-opt %s --test-remark-pipeline --remarks-analyse="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS
+// RUN: mlir-opt %s --test-remark-pipeline --remarks="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL
+// RUN: mlir-opt %s --test-remark-pipeline --remarks="category-1" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL1
+module @foo {
+ "test.op"() : () -> ()
+ "test.op2"() : () -> ()
+}
+
+
+// CHECK-PASSED: remarks.mlir:8:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-PASSED: remarks.mlir:9:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-PASSED: remarks.mlir:7:1: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+
+// CHECK-MISSED:remarks.mlir:8:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-MISSED:remarks.mlir:9:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-MISSED:remarks.mlir:7:1: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+
+// CHECK-FAILED: remarks.mlir:8:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-FAILED: remarks.mlir:9:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-FAILED: remarks.mlir:7:1: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
+
+// CHECK-ANALYSIS: remarks.mlir:8:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
+// CHECK-ANALYSIS: remarks.mlir:9:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
+// CHECK-ANALYSIS: remarks.mlir:7:1: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
+
+
+// CHECK-ALL: remarks.mlir:8:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:8:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:8:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:8:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
+// CHECK-ALL: remarks.mlir:9:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:9:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:9:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:9:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
+// CHECK-ALL: remarks.mlir:7:1: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:7:1: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:7:1: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL: remarks.mlir:7:1: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
+
+// CHECK-ALL1: remarks.mlir:8:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL1: remarks.mlir:8:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL1: remarks.mlir:9:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL1: remarks.mlir:9:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL1: remarks.mlir:7:1: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL1: remarks.mlir:7:1: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
diff --git a/mlir/test/lib/Pass/CMakeLists.txt b/mlir/test/lib/Pass/CMakeLists.txt
index ab52f621c517e..622864398930f 100644
--- a/mlir/test/lib/Pass/CMakeLists.txt
+++ b/mlir/test/lib/Pass/CMakeLists.txt
@@ -4,6 +4,7 @@ add_mlir_library(MLIRTestPass
TestConvertToSPIRVPass.cpp
TestDynamicPipeline.cpp
TestPassManager.cpp
+ TestRemarksPipeline.cpp
TestSPIRVCPURunnerPipeline.cpp
TestVulkanRunnerPipeline.cpp
diff --git a/mlir/test/lib/Pass/TestRemarksPipeline.cpp b/mlir/test/lib/Pass/TestRemarksPipeline.cpp
new file mode 100644
index 0000000000000..c3c9b16f63b79
--- /dev/null
+++ b/mlir/test/lib/Pass/TestRemarksPipeline.cpp
@@ -0,0 +1,80 @@
+//===------ TestRemarkPipeline.cpp --- dynamic pipeline test pass --------===//
+//
+// 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 implements a pass to test the dynamic pipeline feature.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/Location.h"
+#include "mlir/IR/Remarks.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassManager.h"
+
+using namespace mlir;
+
+namespace {
+
+class TestRemarkPipelinePass
+ : public PassWrapper<TestRemarkPipelinePass, OperationPass<>> {
+public:
+ MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestRemarkPipelinePass)
+
+ StringRef getArgument() const final { return "test-remark-pipeline"; }
+ StringRef getDescription() const final {
+ return "Tests the remark pipeline feature";
+ }
+ void getDependentDialects(DialectRegistry ®istry) const override {
+ OpPassManager pm(ModuleOp::getOperationName(),
+ OpPassManager::Nesting::Implicit);
+
+ pm.getDependentDialects(registry);
+ }
+
+ TestRemarkPipelinePass() = default;
+
+ void runOnOperation() override {
+
+ getOperation()->walk([](Operation *op) {
+ Location loc = op->getLoc();
+ mlir::remark::missed(
+ loc,
+ remark::RemarkOpts::name("test-remark").category("category-1-missed"))
+ << remark::add("This is a test missed remark")
+ << remark::reason("because we are testing the remark pipeline")
+ << remark::suggest("try using the remark pipeline feature");
+
+ mlir::remark::passed(
+ loc,
+ remark::RemarkOpts::name("test-remark").category("category-1-passed"))
+ << remark::add("This is a test passed remark")
+ << remark::reason("because we are testing the remark pipeline")
+ << remark::suggest("try using the remark pipeline feature");
+
+ mlir::remark::failed(
+ loc,
+ remark::RemarkOpts::name("test-remark").category("category-2-failed"))
+ << remark::add("This is a test failed remark")
+ << remark::reason("because we are testing the remark pipeline")
+ << remark::suggest("try using the remark pipeline feature");
+
+ mlir::remark::analysis(loc, remark::RemarkOpts::name("test-remark")
+ .category("category-2-analysis"))
+ << remark::add("This is a test analysis remark");
+ });
+ }
+};
+} // namespace
+
+namespace mlir {
+namespace test {
+void registerTestRemarkPipelinePass() {
+ PassRegistration<TestRemarkPipelinePass>();
+}
+} // namespace test
+} // namespace mlir
diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp
index 7b992b4ee029b..3dd8199bb09c0 100644
--- a/mlir/tools/mlir-opt/mlir-opt.cpp
+++ b/mlir/tools/mlir-opt/mlir-opt.cpp
@@ -97,6 +97,7 @@ void registerTestDiagnosticsPass();
void registerTestDiagnosticsMetadataPass();
void registerTestDominancePass();
void registerTestDynamicPipelinePass();
+void registerTestRemarkPipelinePass();
void registerTestEmulateNarrowTypePass();
void registerTestFooAnalysisPass();
void registerTestComposeSubView();
@@ -243,6 +244,7 @@ void registerTestPasses() {
mlir::test::registerTestDiagnosticsMetadataPass();
mlir::test::registerTestDominancePass();
mlir::test::registerTestDynamicPipelinePass();
+ mlir::test::registerTestRemarkPipelinePass();
mlir::test::registerTestEmulateNarrowTypePass();
mlir::test::registerTestFooAnalysisPass();
mlir::test::registerTestComposeSubView();
>From e76922555e63d77d75fef295e02881a1cbe05014 Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Fri, 5 Sep 2025 17:18:01 +0200
Subject: [PATCH 3/6] address comments
---
.../include/mlir/Tools/mlir-opt/MlirOptMain.h | 40 ++++++++++++++-----
mlir/lib/Tools/mlir-opt/MlirOptMain.cpp | 40 +++++++++++++------
mlir/test/Pass/remarks.mlir | 14 ++++---
mlir/test/lib/Pass/TestRemarksPipeline.cpp | 19 +++------
mlir/tools/mlir-opt/mlir-opt.cpp | 4 +-
5 files changed, 73 insertions(+), 44 deletions(-)
diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index 73eeb88bf9f09..c3ac9d99c24bf 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -231,22 +231,31 @@ class MlirOptMainConfig {
bool shouldEmitRemarks() const {
// Emit all remarks only when no filters are specified.
const bool hasFilters =
- !remarksAllFlag.empty() || !remarksPassedFlag.empty() ||
- !remarksFailedFlag.empty() || !remarksMissedFlag.empty() ||
- !remarksAnalyseFlag.empty();
+ !getRemarksAllFilter().empty() || !getRemarksPassedFilter().empty() ||
+ !getRemarksFailedFilter().empty() ||
+ !getRemarksMissedFilter().empty() || !getRemarksAnalyseFilter().empty();
return hasFilters;
}
/// Reproducer file generation (no crash required).
StringRef getReproducerFilename() const { return generateReproducerFileFlag; }
- /// Remark options
- RemarkFormat remarkFormatFlag;
- std::string remarksAllFlag = "";
- std::string remarksPassedFlag = "";
- std::string remarksFailedFlag = "";
- std::string remarksMissedFlag = "";
- std::string remarksAnalyseFlag = "";
+ /// Set the reproducer output filename
+ RemarkFormat getRemarkFormat() const { return remarkFormatFlag; }
+ /// Set the remark format to use.
+ std::string getRemarksAllFilter() const { return remarksAllFilterFlag; }
+ /// Set the remark output file.
+ std::string getRemarksOutputFile() const { return remarksOutputFileFlag; }
+ /// Set the remark passed filters.
+ std::string getRemarksPassedFilter() const { return remarksPassedFilterFlag; }
+ /// Set the remark failed filters.
+ std::string getRemarksFailedFilter() const { return remarksFailedFilterFlag; }
+ /// Set the remark missed filters.
+ std::string getRemarksMissedFilter() const { return remarksMissedFilterFlag; }
+ /// Set the remark analyse filters.
+ std::string getRemarksAnalyseFilter() const {
+ return remarksAnalyseFilterFlag;
+ }
protected:
/// Allow operation with no registered dialects.
@@ -254,6 +263,17 @@ class MlirOptMainConfig {
/// general.
bool allowUnregisteredDialectsFlag = false;
+ /// Remark format
+ RemarkFormat remarkFormatFlag;
+ /// Remark file to output to
+ std::string remarksOutputFileFlag = "";
+ /// Remark filters
+ std::string remarksAllFilterFlag = "";
+ std::string remarksPassedFilterFlag = "";
+ std::string remarksFailedFilterFlag = "";
+ std::string remarksMissedFilterFlag = "";
+ std::string remarksAnalyseFilterFlag = "";
+
/// Configuration for the debugging hooks.
tracing::DebugConfig debugConfig;
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index 0558ffaa4b7b1..f366d178907ec 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -228,23 +228,35 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
static cl::opt<std::string, /*ExternalStorage=*/true> remarksAll(
"remarks",
cl::desc("Show all remarks: passed, missed, failed, analysis"),
- cl::location(remarksAllFlag), cl::init(""), cl::cat(remarkCategory));
+ cl::location(remarksAllFilterFlag), cl::init(""),
+ cl::cat(remarkCategory));
+
+ static cl::opt<std::string, /*ExternalStorage=*/true> remarksFile(
+ "remarks-output-file",
+ cl::desc(
+ "Output file for yaml and bitstream remark formats. Default is "
+ "mlir-remarks.yaml or mlir-remarks.bitstream"),
+ cl::location(remarksOutputFileFlag), cl::init(""),
+ cl::cat(remarkCategory));
static cl::opt<std::string, /*ExternalStorage=*/true> remarksPassed(
"remarks-passed", cl::desc("Show passed remarks"),
- cl::location(remarksPassedFlag), cl::init(""), cl::cat(remarkCategory));
+ cl::location(remarksPassedFilterFlag), cl::init(""),
+ cl::cat(remarkCategory));
static cl::opt<std::string, /*ExternalStorage=*/true> remarksFailed(
"remarks-failed", cl::desc("Show failed remarks"),
- cl::location(remarksFailedFlag), cl::init(""), cl::cat(remarkCategory));
+ cl::location(remarksFailedFilterFlag), cl::init(""),
+ cl::cat(remarkCategory));
static cl::opt<std::string, /*ExternalStorage=*/true> remarksMissed(
"remarks-missed", cl::desc("Show missed remarks"),
- cl::location(remarksMissedFlag), cl::init(""), cl::cat(remarkCategory));
+ cl::location(remarksMissedFilterFlag), cl::init(""),
+ cl::cat(remarkCategory));
static cl::opt<std::string, /*ExternalStorage=*/true> remarksAnalyse(
"remarks-analyse", cl::desc("Show analysis remarks"),
- cl::location(remarksAnalyseFlag), cl::init(""),
+ cl::location(remarksAnalyseFilterFlag), cl::init(""),
cl::cat(remarkCategory));
/// Set the callback to load a pass plugin.
@@ -516,14 +528,14 @@ performActions(raw_ostream &os,
};
remark::RemarkCategories cats{
- combine(config.remarksAllFlag, config.remarksPassedFlag),
- combine(config.remarksAllFlag, config.remarksMissedFlag),
- combine(config.remarksAllFlag, config.remarksAnalyseFlag),
- combine(config.remarksAllFlag, config.remarksFailedFlag)};
+ combine(config.getRemarksAllFilter(), config.getRemarksPassedFilter()),
+ combine(config.getRemarksAllFilter(), config.getRemarksMissedFilter()),
+ combine(config.getRemarksAllFilter(), config.getRemarksAnalyseFilter()),
+ combine(config.getRemarksAllFilter(), config.getRemarksFailedFilter())};
mlir::MLIRContext &ctx = *context;
- switch (config.remarkFormatFlag) {
+ switch (config.getRemarkFormat()) {
case REMARK_FORMAT_STDOUT:
if (failed(mlir::remark::enableOptimizationRemarks(
ctx, nullptr, cats, true /*printAsEmitRemarks*/)))
@@ -531,7 +543,9 @@ performActions(raw_ostream &os,
break;
case REMARK_FORMAT_YAML: {
- constexpr llvm::StringLiteral file{"mlir-remarks.yaml"};
+ std::string file = config.getRemarksOutputFile().empty()
+ ? "mlir-remarks.yaml"
+ : config.getRemarksOutputFile();
if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
ctx, file, llvm::remarks::Format::YAML, cats)))
return failure();
@@ -539,7 +553,9 @@ performActions(raw_ostream &os,
}
case REMARK_FORMAT_BITSTREAM: {
- constexpr llvm::StringLiteral file{"mlir-remarks.bitstream"};
+ std::string file = config.getRemarksOutputFile().empty()
+ ? "mlir-remarks.bitstream"
+ : config.getRemarksOutputFile();
if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
ctx, file, llvm::remarks::Format::Bitstream, cats)))
return failure();
diff --git a/mlir/test/Pass/remarks.mlir b/mlir/test/Pass/remarks.mlir
index 548215e640006..1f57261874739 100644
--- a/mlir/test/Pass/remarks.mlir
+++ b/mlir/test/Pass/remarks.mlir
@@ -1,9 +1,9 @@
-// RUN: mlir-opt %s --test-remark-pipeline --remarks-passed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED
-// RUN: mlir-opt %s --test-remark-pipeline --remarks-missed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED
-// RUN: mlir-opt %s --test-remark-pipeline --remarks-failed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED
-// RUN: mlir-opt %s --test-remark-pipeline --remarks-analyse="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS
-// RUN: mlir-opt %s --test-remark-pipeline --remarks="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL
-// RUN: mlir-opt %s --test-remark-pipeline --remarks="category-1" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL1
+// RUN: mlir-opt %s --test-remark --remarks-passed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED
+// RUN: mlir-opt %s --test-remark --remarks-missed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED
+// RUN: mlir-opt %s --test-remark --remarks-failed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED
+// RUN: mlir-opt %s --test-remark --remarks-analyse="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS
+// RUN: mlir-opt %s --test-remark --remarks="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL
+// RUN: mlir-opt %s --test-remark --remarks="category-1" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL1
module @foo {
"test.op"() : () -> ()
"test.op2"() : () -> ()
@@ -46,3 +46,5 @@ module @foo {
// CHECK-ALL1: remarks.mlir:9:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
// CHECK-ALL1: remarks.mlir:7:1: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
// CHECK-ALL1: remarks.mlir:7:1: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL1-NOT: remarks.mlir:8:3: remark: [Failure]
+// CHECK-ALL1-NOT: remarks.mlir:8:3: remark: [Analysis]
diff --git a/mlir/test/lib/Pass/TestRemarksPipeline.cpp b/mlir/test/lib/Pass/TestRemarksPipeline.cpp
index c3c9b16f63b79..3e90ff7adbf85 100644
--- a/mlir/test/lib/Pass/TestRemarksPipeline.cpp
+++ b/mlir/test/lib/Pass/TestRemarksPipeline.cpp
@@ -20,23 +20,16 @@ using namespace mlir;
namespace {
-class TestRemarkPipelinePass
- : public PassWrapper<TestRemarkPipelinePass, OperationPass<>> {
+class TestRemarkPass : public PassWrapper<TestRemarkPass, OperationPass<>> {
public:
- MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestRemarkPipelinePass)
+ MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestRemarkPass)
- StringRef getArgument() const final { return "test-remark-pipeline"; }
+ StringRef getArgument() const final { return "test-remark"; }
StringRef getDescription() const final {
return "Tests the remark pipeline feature";
}
- void getDependentDialects(DialectRegistry ®istry) const override {
- OpPassManager pm(ModuleOp::getOperationName(),
- OpPassManager::Nesting::Implicit);
- pm.getDependentDialects(registry);
- }
-
- TestRemarkPipelinePass() = default;
+ TestRemarkPass() = default;
void runOnOperation() override {
@@ -73,8 +66,6 @@ class TestRemarkPipelinePass
namespace mlir {
namespace test {
-void registerTestRemarkPipelinePass() {
- PassRegistration<TestRemarkPipelinePass>();
-}
+void registerTestRemarkPass() { PassRegistration<TestRemarkPass>(); }
} // namespace test
} // namespace mlir
diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp
index 3dd8199bb09c0..e4620c009af8c 100644
--- a/mlir/tools/mlir-opt/mlir-opt.cpp
+++ b/mlir/tools/mlir-opt/mlir-opt.cpp
@@ -97,7 +97,7 @@ void registerTestDiagnosticsPass();
void registerTestDiagnosticsMetadataPass();
void registerTestDominancePass();
void registerTestDynamicPipelinePass();
-void registerTestRemarkPipelinePass();
+void registerTestRemarkPass();
void registerTestEmulateNarrowTypePass();
void registerTestFooAnalysisPass();
void registerTestComposeSubView();
@@ -244,7 +244,7 @@ void registerTestPasses() {
mlir::test::registerTestDiagnosticsMetadataPass();
mlir::test::registerTestDominancePass();
mlir::test::registerTestDynamicPipelinePass();
- mlir::test::registerTestRemarkPipelinePass();
+ mlir::test::registerTestRemarkPass();
mlir::test::registerTestEmulateNarrowTypePass();
mlir::test::registerTestFooAnalysisPass();
mlir::test::registerTestComposeSubView();
>From 88f649de14b3a3f7eb80170a9863c1ce9c62d95e Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Mon, 8 Sep 2025 14:03:16 +0200
Subject: [PATCH 4/6] name change
---
mlir/test/lib/Pass/CMakeLists.txt | 2 +-
.../lib/Pass/{TestRemarksPipeline.cpp => TestRemarksPass.cpp} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename mlir/test/lib/Pass/{TestRemarksPipeline.cpp => TestRemarksPass.cpp} (100%)
diff --git a/mlir/test/lib/Pass/CMakeLists.txt b/mlir/test/lib/Pass/CMakeLists.txt
index 622864398930f..04c91635def85 100644
--- a/mlir/test/lib/Pass/CMakeLists.txt
+++ b/mlir/test/lib/Pass/CMakeLists.txt
@@ -4,7 +4,7 @@ add_mlir_library(MLIRTestPass
TestConvertToSPIRVPass.cpp
TestDynamicPipeline.cpp
TestPassManager.cpp
- TestRemarksPipeline.cpp
+ TestRemarksPass.cpp
TestSPIRVCPURunnerPipeline.cpp
TestVulkanRunnerPipeline.cpp
diff --git a/mlir/test/lib/Pass/TestRemarksPipeline.cpp b/mlir/test/lib/Pass/TestRemarksPass.cpp
similarity index 100%
rename from mlir/test/lib/Pass/TestRemarksPipeline.cpp
rename to mlir/test/lib/Pass/TestRemarksPass.cpp
>From d724f85bb9fa6878051c40ea4e240c16402e9108 Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Mon, 8 Sep 2025 15:21:27 +0200
Subject: [PATCH 5/6] fx
---
mlir/include/mlir/IR/Remarks.h | 2 +-
mlir/lib/IR/Remarks.cpp | 47 ++++++++++++++--
mlir/lib/Tools/mlir-opt/MlirOptMain.cpp | 72 +++++++++++--------------
mlir/test/Pass/remarks.mlir | 44 ++++-----------
mlir/test/lib/Pass/TestRemarksPass.cpp | 9 ++--
5 files changed, 91 insertions(+), 83 deletions(-)
diff --git a/mlir/include/mlir/IR/Remarks.h b/mlir/include/mlir/IR/Remarks.h
index 26d65472f2b1c..20e84ec83cd01 100644
--- a/mlir/include/mlir/IR/Remarks.h
+++ b/mlir/include/mlir/IR/Remarks.h
@@ -29,7 +29,7 @@ namespace mlir::remark {
/// Define an the set of categories to accept. By default none are, the provided
/// regex matches against the category names for each kind of remark.
struct RemarkCategories {
- std::optional<std::string> passed, missed, analysis, failed;
+ std::optional<std::string> all, passed, missed, analysis, failed;
};
/// Categories describe the outcome of an transformation, not the mechanics of
diff --git a/mlir/lib/IR/Remarks.cpp b/mlir/lib/IR/Remarks.cpp
index 78c964427868f..29088bd360e23 100644
--- a/mlir/lib/IR/Remarks.cpp
+++ b/mlir/lib/IR/Remarks.cpp
@@ -248,17 +248,56 @@ RemarkEngine::initialize(std::unique_ptr<MLIRRemarkStreamerBase> streamer,
return success();
}
+/// Returns true if filter is already anchored like ^...$
+static bool isAnchored(llvm::StringRef s) {
+ s = s.trim();
+ return s.starts_with("^") && s.ends_with("$"); // note: startswith/endswith
+}
+
+/// Anchor the entire pattern so it matches the whole string.
+static std::string anchorWhole(llvm::StringRef filter) {
+ if (isAnchored(filter))
+ return filter.str();
+ return (llvm::Twine("^(") + filter + ")$").str();
+}
+
+/// Build a combined filter from cats.all and a category-specific pattern.
+/// If neither is present, return std::nullopt. Otherwise "(all|specific)"
+/// and anchor once. Also validate before returning.
+static std::optional<llvm::Regex>
+buildFilter(const mlir::remark::RemarkCategories &cats,
+ const std::optional<std::string> &specific) {
+ llvm::SmallVector<llvm::StringRef, 2> parts;
+ if (cats.all && !cats.all->empty())
+ parts.emplace_back(*cats.all);
+ if (specific && !specific->empty())
+ parts.emplace_back(*specific);
+
+ if (parts.empty())
+ return std::nullopt;
+
+ std::string joined = llvm::join(parts, "|");
+ std::string anchored = anchorWhole(joined);
+
+ llvm::Regex rx(anchored);
+ std::string err;
+ if (!rx.isValid(err))
+ return std::nullopt;
+
+ return rx;
+}
+
RemarkEngine::RemarkEngine(bool printAsEmitRemarks,
const RemarkCategories &cats)
: printAsEmitRemarks(printAsEmitRemarks) {
if (cats.passed)
- passedFilter = llvm::Regex(cats.passed.value());
+ passedFilter = buildFilter(cats, cats.passed);
if (cats.missed)
- missFilter = llvm::Regex(cats.missed.value());
+ missFilter = buildFilter(cats, cats.missed);
if (cats.analysis)
- analysisFilter = llvm::Regex(cats.analysis.value());
+ analysisFilter = buildFilter(cats, cats.analysis);
if (cats.failed)
- failedFilter = llvm::Regex(cats.failed.value());
+ failedFilter = buildFilter(cats, cats.failed);
}
llvm::LogicalResult mlir::remark::enableOptimizationRemarks(
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index f366d178907ec..d9ce13662a67c 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -517,51 +517,39 @@ performActions(raw_ostream &os,
context->enableMultithreading(wasThreadingEnabled);
- // Set up optimization remarks.
- if (config.shouldEmitRemarks()) {
- auto combine = [](const std::string &a, const std::string &b) {
- if (a.empty())
- return b;
- if (b.empty())
- return a;
- return a + "|" + b;
- };
-
- remark::RemarkCategories cats{
- combine(config.getRemarksAllFilter(), config.getRemarksPassedFilter()),
- combine(config.getRemarksAllFilter(), config.getRemarksMissedFilter()),
- combine(config.getRemarksAllFilter(), config.getRemarksAnalyseFilter()),
- combine(config.getRemarksAllFilter(), config.getRemarksFailedFilter())};
+ remark::RemarkCategories cats{
+ config.getRemarksAllFilter(), config.getRemarksPassedFilter(),
+ config.getRemarksMissedFilter(), config.getRemarksAnalyseFilter(),
+ config.getRemarksFailedFilter()};
- mlir::MLIRContext &ctx = *context;
+ mlir::MLIRContext &ctx = *context;
- switch (config.getRemarkFormat()) {
- case REMARK_FORMAT_STDOUT:
- if (failed(mlir::remark::enableOptimizationRemarks(
- ctx, nullptr, cats, true /*printAsEmitRemarks*/)))
- return failure();
- break;
-
- case REMARK_FORMAT_YAML: {
- std::string file = config.getRemarksOutputFile().empty()
- ? "mlir-remarks.yaml"
- : config.getRemarksOutputFile();
- if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
- ctx, file, llvm::remarks::Format::YAML, cats)))
- return failure();
- break;
- }
+ switch (config.getRemarkFormat()) {
+ case REMARK_FORMAT_STDOUT:
+ if (failed(mlir::remark::enableOptimizationRemarks(
+ ctx, nullptr, cats, true /*printAsEmitRemarks*/)))
+ return failure();
+ break;
+
+ case REMARK_FORMAT_YAML: {
+ std::string file = config.getRemarksOutputFile().empty()
+ ? "mlir-remarks.yaml"
+ : config.getRemarksOutputFile();
+ if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
+ ctx, file, llvm::remarks::Format::YAML, cats)))
+ return failure();
+ break;
+ }
- case REMARK_FORMAT_BITSTREAM: {
- std::string file = config.getRemarksOutputFile().empty()
- ? "mlir-remarks.bitstream"
- : config.getRemarksOutputFile();
- if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
- ctx, file, llvm::remarks::Format::Bitstream, cats)))
- return failure();
- break;
- }
- }
+ case REMARK_FORMAT_BITSTREAM: {
+ std::string file = config.getRemarksOutputFile().empty()
+ ? "mlir-remarks.bitstream"
+ : config.getRemarksOutputFile();
+ if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer(
+ ctx, file, llvm::remarks::Format::Bitstream, cats)))
+ return failure();
+ break;
+ }
}
// Prepare the pass manager, applying command-line and reproducer options.
diff --git a/mlir/test/Pass/remarks.mlir b/mlir/test/Pass/remarks.mlir
index 1f57261874739..b78c538d78385 100644
--- a/mlir/test/Pass/remarks.mlir
+++ b/mlir/test/Pass/remarks.mlir
@@ -1,50 +1,28 @@
-// RUN: mlir-opt %s --test-remark --remarks-passed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED
-// RUN: mlir-opt %s --test-remark --remarks-missed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED
-// RUN: mlir-opt %s --test-remark --remarks-failed="category" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED
-// RUN: mlir-opt %s --test-remark --remarks-analyse="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS
-// RUN: mlir-opt %s --test-remark --remarks="category" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL
-// RUN: mlir-opt %s --test-remark --remarks="category-1" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL1
+// RUN: mlir-opt %s --test-remark --remarks-passed="category-1-passed" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED
+// RUN: mlir-opt %s --test-remark --remarks-missed="a-category-1-missed" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED
+// RUN: mlir-opt %s --test-remark --remarks-failed="category-2-failed" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED
+// RUN: mlir-opt %s --test-remark --remarks-analyse="category-2-analysis" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS
+// RUN: mlir-opt %s --test-remark --remarks="category.*" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL
+// RUN: mlir-opt %s --test-remark --remarks="category-1.*" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL1
module @foo {
"test.op"() : () -> ()
- "test.op2"() : () -> ()
+
}
// CHECK-PASSED: remarks.mlir:8:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-PASSED: remarks.mlir:9:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-PASSED: remarks.mlir:7:1: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
-
-// CHECK-MISSED:remarks.mlir:8:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-MISSED:remarks.mlir:9:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-MISSED:remarks.mlir:7:1: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
-
+// CHECK-MISSED:remarks.mlir:8:3: remark: [Missed] test-remark | Category:a-category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
// CHECK-FAILED: remarks.mlir:8:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-FAILED: remarks.mlir:9:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-FAILED: remarks.mlir:7:1: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
-
// CHECK-ANALYSIS: remarks.mlir:8:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
-// CHECK-ANALYSIS: remarks.mlir:9:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
-// CHECK-ANALYSIS: remarks.mlir:7:1: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
-// CHECK-ALL: remarks.mlir:8:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
// CHECK-ALL: remarks.mlir:8:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
// CHECK-ALL: remarks.mlir:8:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
// CHECK-ALL: remarks.mlir:8:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
-// CHECK-ALL: remarks.mlir:9:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL: remarks.mlir:9:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL: remarks.mlir:9:3: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL: remarks.mlir:9:3: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
-// CHECK-ALL: remarks.mlir:7:1: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL: remarks.mlir:7:1: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL: remarks.mlir:7:1: remark: [Failure] test-remark | Category:category-2-failed | Reason="because we are testing the remark pipeline", Remark="This is a test failed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL: remarks.mlir:7:1: remark: [Analysis] test-remark | Category:category-2-analysis | Remark="This is a test analysis remark"
-// CHECK-ALL1: remarks.mlir:8:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
// CHECK-ALL1: remarks.mlir:8:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL1: remarks.mlir:9:3: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL1: remarks.mlir:9:3: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL1: remarks.mlir:7:1: remark: [Missed] test-remark | Category:category-1-missed | Reason="because we are testing the remark pipeline", Remark="This is a test missed remark", Suggestion="try using the remark pipeline feature"
-// CHECK-ALL1: remarks.mlir:7:1: remark: [Passed] test-remark | Category:category-1-passed | Reason="because we are testing the remark pipeline", Remark="This is a test passed remark", Suggestion="try using the remark pipeline feature"
+// CHECK-ALL1-NOT: remarks.mlir:8:3: remark: [Missed]
// CHECK-ALL1-NOT: remarks.mlir:8:3: remark: [Failure]
// CHECK-ALL1-NOT: remarks.mlir:8:3: remark: [Analysis]
+
+
diff --git a/mlir/test/lib/Pass/TestRemarksPass.cpp b/mlir/test/lib/Pass/TestRemarksPass.cpp
index 3e90ff7adbf85..3b25686b3dc14 100644
--- a/mlir/test/lib/Pass/TestRemarksPass.cpp
+++ b/mlir/test/lib/Pass/TestRemarksPass.cpp
@@ -15,6 +15,7 @@
#include "mlir/IR/Remarks.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
+#include "mlir/Support/WalkResult.h"
using namespace mlir;
@@ -34,10 +35,11 @@ class TestRemarkPass : public PassWrapper<TestRemarkPass, OperationPass<>> {
void runOnOperation() override {
getOperation()->walk([](Operation *op) {
+ if (isa<ModuleOp>(op))
+ return WalkResult::advance();
Location loc = op->getLoc();
- mlir::remark::missed(
- loc,
- remark::RemarkOpts::name("test-remark").category("category-1-missed"))
+ mlir::remark::missed(loc, remark::RemarkOpts::name("test-remark")
+ .category("a-category-1-missed"))
<< remark::add("This is a test missed remark")
<< remark::reason("because we are testing the remark pipeline")
<< remark::suggest("try using the remark pipeline feature");
@@ -59,6 +61,7 @@ class TestRemarkPass : public PassWrapper<TestRemarkPass, OperationPass<>> {
mlir::remark::analysis(loc, remark::RemarkOpts::name("test-remark")
.category("category-2-analysis"))
<< remark::add("This is a test analysis remark");
+ return WalkResult::advance();
});
}
};
>From a117fe5a74faffcc2f6a2dff666b1646ebbb141e Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Mon, 8 Sep 2025 16:23:45 +0200
Subject: [PATCH 6/6] fx
---
mlir/unittests/IR/RemarkTest.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/mlir/unittests/IR/RemarkTest.cpp b/mlir/unittests/IR/RemarkTest.cpp
index 65e1e08b83838..5bfca255c22ca 100644
--- a/mlir/unittests/IR/RemarkTest.cpp
+++ b/mlir/unittests/IR/RemarkTest.cpp
@@ -48,7 +48,8 @@ TEST(Remark, TestOutputOptimizationRemark) {
context.printStackTraceOnDiagnostic(true);
// Setup the remark engine
- mlir::remark::RemarkCategories cats{/*passed=*/categoryVectorizer,
+ mlir::remark::RemarkCategories cats{/*all=*/"",
+ /*passed=*/categoryVectorizer,
/*missed=*/categoryUnroll,
/*analysis=*/categoryRegister,
/*failed=*/categoryInliner};
@@ -197,7 +198,8 @@ TEST(Remark, TestOutputOptimizationRemarkDiagnostic) {
});
// Setup the remark engine
- mlir::remark::RemarkCategories cats{/*passed=*/categoryVectorizer,
+ mlir::remark::RemarkCategories cats{/*all=*/"",
+ /*passed=*/categoryVectorizer,
/*missed=*/categoryUnroll,
/*analysis=*/categoryRegister,
/*failed=*/categoryUnroll};
@@ -278,7 +280,8 @@ TEST(Remark, TestCustomOptimizationRemarkDiagnostic) {
Location loc = UnknownLoc::get(&context);
// Setup the remark engine
- mlir::remark::RemarkCategories cats{/*passed=*/categoryLoopunroll,
+ mlir::remark::RemarkCategories cats{/*all=*/"",
+ /*passed=*/categoryLoopunroll,
/*missed=*/std::nullopt,
/*analysis=*/std::nullopt,
/*failed=*/categoryLoopunroll};
More information about the Mlir-commits
mailing list