From a3e2893fd9dc72f0bfabd5be414c2b666367787b Mon Sep 17 00:00:00 2001 From: Guray Ozen Date: Thu, 4 Sep 2025 10:26:33 +0200 Subject: [PATCH 1/8] [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{ + "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 remarksPassed( + "remarks-passed", cl::desc("Show passed remarks"), + cl::location(remarksPassedFlag), cl::init(""), cl::cat(remarkCategory)); + + static cl::opt remarksFailed( + "remarks-failed", cl::desc("Show failed remarks"), + cl::location(remarksFailedFlag), cl::init(""), cl::cat(remarkCategory)); + + static cl::opt remarksMissed( + "remarks-missed", cl::desc("Show missed remarks"), + cl::location(remarksMissedFlag), cl::init(""), cl::cat(remarkCategory)); + + static cl::opt 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 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 Date: Thu, 4 Sep 2025 14:30:54 +0200 Subject: [PATCH 2/8] 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 remarksAll( + "remarks", + cl::desc("Show all remarks: passed, missed, failed, analysis"), + cl::location(remarksAllFlag), cl::init(""), cl::cat(remarkCategory)); + static cl::opt 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> { +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(); +} +} // 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 Date: Fri, 5 Sep 2025 17:18:01 +0200 Subject: [PATCH 3/8] 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 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 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 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 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 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 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> { +class TestRemarkPass : public PassWrapper> { 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(); -} +void registerTestRemarkPass() { PassRegistration(); } } // 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 Date: Mon, 8 Sep 2025 14:03:16 +0200 Subject: [PATCH 4/8] 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 Date: Mon, 8 Sep 2025 15:21:27 +0200 Subject: [PATCH 5/8] 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 passed, missed, analysis, failed; + std::optional 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 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 +buildFilter(const mlir::remark::RemarkCategories &cats, + const std::optional &specific) { + llvm::SmallVector 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> { void runOnOperation() override { getOperation()->walk([](Operation *op) { + if (isa(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> { 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 Date: Mon, 8 Sep 2025 16:23:45 +0200 Subject: [PATCH 6/8] 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}; From c52555ba206b87967f01cd51d7dca6abf29d47f3 Mon Sep 17 00:00:00 2001 From: Guray Ozen Date: Wed, 10 Sep 2025 10:29:02 +0200 Subject: [PATCH 7/8] make filter --- mlir/lib/Tools/mlir-opt/MlirOptMain.cpp | 10 +++++----- mlir/test/Pass/remarks.mlir | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp index d9ce13662a67c..85490e582c5f4 100644 --- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp +++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp @@ -226,7 +226,7 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig { llvm::cl::cat(remarkCategory)}; static cl::opt remarksAll( - "remarks", + "remarks-filter", cl::desc("Show all remarks: passed, missed, failed, analysis"), cl::location(remarksAllFilterFlag), cl::init(""), cl::cat(remarkCategory)); @@ -240,22 +240,22 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig { cl::cat(remarkCategory)); static cl::opt remarksPassed( - "remarks-passed", cl::desc("Show passed remarks"), + "remarks-passed-filter", cl::desc("Show passed remarks"), cl::location(remarksPassedFilterFlag), cl::init(""), cl::cat(remarkCategory)); static cl::opt remarksFailed( - "remarks-failed", cl::desc("Show failed remarks"), + "remarks-failed-filter", cl::desc("Show failed remarks"), cl::location(remarksFailedFilterFlag), cl::init(""), cl::cat(remarkCategory)); static cl::opt remarksMissed( - "remarks-missed", cl::desc("Show missed remarks"), + "remarks-missed-filter", cl::desc("Show missed remarks"), cl::location(remarksMissedFilterFlag), cl::init(""), cl::cat(remarkCategory)); static cl::opt remarksAnalyse( - "remarks-analyse", cl::desc("Show analysis remarks"), + "remarks-analyse-filter", cl::desc("Show analysis remarks"), cl::location(remarksAnalyseFilterFlag), cl::init(""), cl::cat(remarkCategory)); diff --git a/mlir/test/Pass/remarks.mlir b/mlir/test/Pass/remarks.mlir index b78c538d78385..cc7aafeb53296 100644 --- a/mlir/test/Pass/remarks.mlir +++ b/mlir/test/Pass/remarks.mlir @@ -1,9 +1,9 @@ -// 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 +// RUN: mlir-opt %s --test-remark --remarks-passed-filter="category-1-passed" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED +// RUN: mlir-opt %s --test-remark --remarks-missed-filter="a-category-1-missed" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED +// RUN: mlir-opt %s --test-remark --remarks-failed-filter="category-2-failed" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED +// RUN: mlir-opt %s --test-remark --remarks-analyse-filter="category-2-analysis" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS +// RUN: mlir-opt %s --test-remark --remarks-filter="category.*" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL +// RUN: mlir-opt %s --test-remark --remarks-filter="category-1.*" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL1 module @foo { "test.op"() : () -> () From 6f55cc0a64e053849fb9d04d3273515d30fe4f1e Mon Sep 17 00:00:00 2001 From: Guray Ozen Date: Wed, 10 Sep 2025 10:32:07 +0200 Subject: [PATCH 8/8] change names --- mlir/lib/Tools/mlir-opt/MlirOptMain.cpp | 8 ++++---- mlir/test/Pass/remarks.mlir | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp index 85490e582c5f4..4f3b2eda7e69b 100644 --- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp +++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp @@ -240,22 +240,22 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig { cl::cat(remarkCategory)); static cl::opt remarksPassed( - "remarks-passed-filter", cl::desc("Show passed remarks"), + "remarks-filter-passed", cl::desc("Show passed remarks"), cl::location(remarksPassedFilterFlag), cl::init(""), cl::cat(remarkCategory)); static cl::opt remarksFailed( - "remarks-failed-filter", cl::desc("Show failed remarks"), + "remarks-filter-failed", cl::desc("Show failed remarks"), cl::location(remarksFailedFilterFlag), cl::init(""), cl::cat(remarkCategory)); static cl::opt remarksMissed( - "remarks-missed-filter", cl::desc("Show missed remarks"), + "remarks-filter-missed", cl::desc("Show missed remarks"), cl::location(remarksMissedFilterFlag), cl::init(""), cl::cat(remarkCategory)); static cl::opt remarksAnalyse( - "remarks-analyse-filter", cl::desc("Show analysis remarks"), + "remarks-filter-analyse", cl::desc("Show analysis remarks"), cl::location(remarksAnalyseFilterFlag), cl::init(""), cl::cat(remarkCategory)); diff --git a/mlir/test/Pass/remarks.mlir b/mlir/test/Pass/remarks.mlir index cc7aafeb53296..8aa04e3c98d80 100644 --- a/mlir/test/Pass/remarks.mlir +++ b/mlir/test/Pass/remarks.mlir @@ -1,7 +1,7 @@ -// RUN: mlir-opt %s --test-remark --remarks-passed-filter="category-1-passed" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED -// RUN: mlir-opt %s --test-remark --remarks-missed-filter="a-category-1-missed" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED -// RUN: mlir-opt %s --test-remark --remarks-failed-filter="category-2-failed" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED -// RUN: mlir-opt %s --test-remark --remarks-analyse-filter="category-2-analysis" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS +// RUN: mlir-opt %s --test-remark --remarks-filter-passed="category-1-passed" 2>&1 | FileCheck %s -check-prefix=CHECK-PASSED +// RUN: mlir-opt %s --test-remark --remarks-filter-missed="a-category-1-missed" 2>&1 | FileCheck %s -check-prefix=CHECK-MISSED +// RUN: mlir-opt %s --test-remark --remarks-filter-failed="category-2-failed" 2>&1 | FileCheck %s -check-prefix=CHECK-FAILED +// RUN: mlir-opt %s --test-remark --remarks-filter-analyse="category-2-analysis" 2>&1 | FileCheck %s -check-prefix=CHECK-ANALYSIS // RUN: mlir-opt %s --test-remark --remarks-filter="category.*" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL // RUN: mlir-opt %s --test-remark --remarks-filter="category-1.*" 2>&1 | FileCheck %s -check-prefix=CHECK-ALL1 module @foo {