[Mlir-commits] [mlir] [MLIR] Move the `mlir-generate-reproducer` option to be a PassManager option instead of mlir-opt (PR #159004)
Mehdi Amini
llvmlistbot at llvm.org
Thu Sep 25 04:19:29 PDT 2025
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/159004
>From 67bb4b1ace986ffe26a6d5c9c58483103078da99 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Tue, 16 Sep 2025 04:14:54 -0700
Subject: [PATCH] [MLIR] Move the `mlir-generate-reproducer` option to be a
PassManager option instead of mlir-opt
This makes it available to compilers in general, not limited to mlir-opt-like tools.
---
mlir/include/mlir/Pass/PassManager.h | 20 +++++++++++++++++++
.../include/mlir/Tools/mlir-opt/MlirOptMain.h | 8 +-------
mlir/lib/Pass/Pass.cpp | 8 ++++++++
mlir/lib/Pass/PassCrashRecovery.cpp | 17 ++++++++++++----
mlir/lib/Pass/PassManagerOptions.cpp | 8 ++++++++
mlir/lib/Tools/mlir-opt/MlirOptMain.cpp | 17 ----------------
6 files changed, 50 insertions(+), 28 deletions(-)
diff --git a/mlir/include/mlir/Pass/PassManager.h b/mlir/include/mlir/Pass/PassManager.h
index 6e59b0f32ac6f..7f43c0e119403 100644
--- a/mlir/include/mlir/Pass/PassManager.h
+++ b/mlir/include/mlir/Pass/PassManager.h
@@ -222,12 +222,20 @@ struct ReproducerStream {
using ReproducerStreamFactory =
std::function<std::unique_ptr<ReproducerStream>(std::string &error)>;
+ReproducerStreamFactory makeReproducerStreamFactory(StringRef outputFile);
+
std::string
makeReproducer(StringRef anchorName,
const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
Operation *op, StringRef outputFile, bool disableThreads = false,
bool verifyPasses = false);
+std::string
+makeReproducer(StringRef anchorName,
+ const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
+ Operation *op, const ReproducerStreamFactory &streamFactory,
+ bool disableThreads = false, bool verifyPasses = false);
+
/// The main pass manager and pipeline builder.
class PassManager : public OpPassManager {
public:
@@ -282,6 +290,15 @@ class PassManager : public OpPassManager {
/// Add the provided instrumentation to the pass manager.
void addInstrumentation(std::unique_ptr<PassInstrumentation> pi);
+ /// Enable or disable the printing of pass manager reproducer.
+ void enableGeneratePassManagerReproducer(StringRef outputFile) {
+ forceGenerateReproducer = makeReproducerStreamFactory(outputFile);
+ }
+
+ void enableGeneratePassManagerReproducer(ReproducerStreamFactory factory) {
+ forceGenerateReproducer = std::move(factory);
+ }
+
//===--------------------------------------------------------------------===//
// IR Printing
@@ -492,6 +509,9 @@ class PassManager : public OpPassManager {
llvm::hash_code pipelineInitializationKey =
DenseMapInfo<llvm::hash_code>::getTombstoneKey();
+ /// A flag that indicates if the pass manager reproducer should be generated.
+ ReproducerStreamFactory forceGenerateReproducer;
+
/// Flag that specifies if pass timing is enabled.
bool passTiming : 1;
diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index 0fbe15fa2e0db..9690ac6090fe7 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -237,10 +237,7 @@ class MlirOptMainConfig {
return hasFilters;
}
- /// Reproducer file generation (no crash required).
- StringRef getReproducerFilename() const { return generateReproducerFileFlag; }
-
- /// Set the reproducer output filename
+ /// Set the remarks output filename
RemarkFormat getRemarkFormat() const { return remarkFormatFlag; }
/// Set the remark format to use.
std::string getRemarksAllFilter() const { return remarksAllFilterFlag; }
@@ -340,9 +337,6 @@ class MlirOptMainConfig {
/// Verify that the input IR round-trips perfectly.
bool verifyRoundtripFlag = false;
-
- /// The reproducer output filename (no crash required).
- std::string generateReproducerFileFlag = "";
};
/// This defines the function type used to setup the pass manager. This can be
diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp
index 521c7c6be17b6..7eabb62ec84ac 100644
--- a/mlir/lib/Pass/Pass.cpp
+++ b/mlir/lib/Pass/Pass.cpp
@@ -1033,6 +1033,14 @@ LogicalResult PassManager::run(Operation *op) {
<< size() << " passes, verifyPasses=" << verifyPasses << " pipeline: ";
printAsTextualPipeline(os, /*pretty=*/false);
});
+ // Generate reproducers if requested
+ if (forceGenerateReproducer) {
+ StringRef anchorName = getAnyOpAnchorName();
+ const auto &passes = getPasses();
+ makeReproducer(anchorName, passes, op, forceGenerateReproducer,
+ /*disableThreads=*/!getContext()->isMultithreadingEnabled(),
+ verifyPasses);
+ }
MLIRContext *context = getContext();
std::optional<OperationName> anchorOp = getOpName(*context);
diff --git a/mlir/lib/Pass/PassCrashRecovery.cpp b/mlir/lib/Pass/PassCrashRecovery.cpp
index 3c9735f910094..ba66d1df54d85 100644
--- a/mlir/lib/Pass/PassCrashRecovery.cpp
+++ b/mlir/lib/Pass/PassCrashRecovery.cpp
@@ -427,8 +427,8 @@ LogicalResult PassManager::runWithCrashRecovery(Operation *op,
return passManagerResult;
}
-static ReproducerStreamFactory
-makeReproducerStreamFactory(StringRef outputFile) {
+ReproducerStreamFactory
+mlir::makeReproducerStreamFactory(StringRef outputFile) {
// Capture the filename by value in case outputFile is out of scope when
// invoked.
std::string filename = outputFile.str();
@@ -453,13 +453,22 @@ std::string mlir::makeReproducer(
const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
Operation *op, StringRef outputFile, bool disableThreads,
bool verifyPasses) {
+ return makeReproducer(anchorName, passes, op,
+ makeReproducerStreamFactory(outputFile), disableThreads,
+ verifyPasses);
+}
+std::string mlir::makeReproducer(
+ StringRef anchorName,
+ const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
+ Operation *op, const ReproducerStreamFactory &streamFactory,
+ bool disableThreads, bool verifyPasses) {
std::string description;
std::string pipelineStr;
llvm::raw_string_ostream passOS(pipelineStr);
::printAsTextualPipeline(passOS, anchorName, passes);
- appendReproducer(description, op, makeReproducerStreamFactory(outputFile),
- pipelineStr, disableThreads, verifyPasses);
+ appendReproducer(description, op, streamFactory, pipelineStr, disableThreads,
+ verifyPasses);
return description;
}
diff --git a/mlir/lib/Pass/PassManagerOptions.cpp b/mlir/lib/Pass/PassManagerOptions.cpp
index 305bf72bb4799..228a7716a114d 100644
--- a/mlir/lib/Pass/PassManagerOptions.cpp
+++ b/mlir/lib/Pass/PassManagerOptions.cpp
@@ -63,6 +63,11 @@ struct PassManagerOptions {
llvm::cl::desc("When printing the IR before/after a pass, print file "
"tree rooted at this directory. Use in conjunction with "
"mlir-print-ir-* flags")};
+ llvm::cl::opt<std::string> generateReproducerFile{
+ "mlir-generate-reproducer",
+ llvm::cl::desc("Generate an mlir reproducer at the provided filename"
+ " (no crash required)"),
+ llvm::cl::init(""), llvm::cl::value_desc("filename")};
/// Add an IR printing instrumentation if enabled by any 'print-ir' flags.
void addPrinterInstrumentation(PassManager &pm);
@@ -172,6 +177,9 @@ LogicalResult mlir::applyPassManagerCLOptions(PassManager &pm) {
// Add the IR printing instrumentation.
options->addPrinterInstrumentation(pm);
+
+ if (options->generateReproducerFile.getNumOccurrences())
+ pm.enableGeneratePassManagerReproducer(options->generateReproducerFile);
return success();
}
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index 30fd384f3977c..56932045a229d 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -198,15 +198,6 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
static cl::list<std::string> passPlugins(
"load-pass-plugin", cl::desc("Load passes from plugin library"));
- static cl::opt<std::string, /*ExternalStorage=*/true>
- generateReproducerFile(
- "mlir-generate-reproducer",
- llvm::cl::desc(
- "Generate an mlir reproducer at the provided filename"
- " (no crash required)"),
- cl::location(generateReproducerFileFlag), cl::init(""),
- cl::value_desc("filename"));
-
static cl::OptionCategory remarkCategory(
"Remark Options",
"Filter remarks by regular expression (llvm::Regex syntax).");
@@ -568,14 +559,6 @@ performActions(raw_ostream &os,
if (failed(pm.run(*op)))
return failure();
- // Generate reproducers if requested
- if (!config.getReproducerFilename().empty()) {
- StringRef anchorName = pm.getAnyOpAnchorName();
- const auto &passes = pm.getPasses();
- makeReproducer(anchorName, passes, op.get(),
- config.getReproducerFilename());
- }
-
// Print the output.
TimingScope outputTiming = timing.nest("Output");
if (config.shouldEmitBytecode()) {
More information about the Mlir-commits
mailing list