[Mlir-commits] [mlir] Pretty print on -dump-pass-pipeline (PR #143223)
Jeremy Kun
llvmlistbot at llvm.org
Fri Jun 6 19:53:21 PDT 2025
https://github.com/j2kun updated https://github.com/llvm/llvm-project/pull/143223
>From 8604bf62da04f5a79c6ff220ae45316a22d08cb7 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Fri, 6 Jun 2025 18:29:22 -0700
Subject: [PATCH 1/3] Pretty print on -dump-pass-pipeline
---
mlir/lib/Pass/Pass.cpp | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp
index e0e9b5f54042a..6e8d3bbfdff81 100644
--- a/mlir/lib/Pass/Pass.cpp
+++ b/mlir/lib/Pass/Pass.cpp
@@ -18,6 +18,7 @@
#include "mlir/IR/Threading.h"
#include "mlir/IR/Verifier.h"
#include "mlir/Support/FileUtilities.h"
+#include "mlir/Support/IndentedOstream.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
@@ -392,18 +393,28 @@ StringRef OpPassManager::getOpAnchorName() const {
/// Prints out the passes of the pass manager as the textual representation
/// of pipelines.
void printAsTextualPipeline(
- raw_ostream &os, StringRef anchorName,
+ raw_indented_ostream &os, StringRef anchorName,
const llvm::iterator_range<OpPassManager::pass_iterator> &passes) {
- os << anchorName << "(";
+ os << anchorName << "(\n";
+ os.indent();
llvm::interleave(
passes, [&](mlir::Pass &pass) { pass.printAsTextualPipeline(os); },
- [&]() { os << ","; });
+ [&]() { os << ",\n"; });
+ os << "\n";
+ os.unindent();
os << ")";
}
+void printAsTextualPipeline(
+ raw_ostream &os, StringRef anchorName,
+ const llvm::iterator_range<OpPassManager::pass_iterator> &passes) {
+ raw_indented_ostream indentedOS(os);
+ printAsTextualPipeline(indentedOS, anchorName, passes);
+}
void OpPassManager::printAsTextualPipeline(raw_ostream &os) const {
StringRef anchorName = getOpAnchorName();
+ raw_indented_ostream indentedOS(os);
::printAsTextualPipeline(
- os, anchorName,
+ indentedOS, anchorName,
{MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.begin(),
MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.end()});
}
>From 3b0e3dd81bed6ee8253a6aa42dc918bdc1c9af91 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Fri, 6 Jun 2025 19:03:02 -0700
Subject: [PATCH 2/3] add a pretty option and fix most tests
---
mlir/include/mlir/Pass/Pass.h | 2 +-
mlir/include/mlir/Pass/PassManager.h | 2 +-
mlir/lib/Pass/Pass.cpp | 37 ++++++++++++-------
mlir/test/Pass/pipeline-parsing.mlir | 4 +-
mlir/test/Pass/run-reproducer.mlir | 4 +-
mlir/test/Transforms/composite-pass.mlir | 5 ++-
.../inlining-dump-default-pipeline.mlir | 4 +-
7 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/mlir/include/mlir/Pass/Pass.h b/mlir/include/mlir/Pass/Pass.h
index 9e8ba7158f1b3..3f0a838f2447f 100644
--- a/mlir/include/mlir/Pass/Pass.h
+++ b/mlir/include/mlir/Pass/Pass.h
@@ -119,7 +119,7 @@ class Pass {
/// Prints out the pass in the textual representation of pipelines. If this is
/// an adaptor pass, print its pass managers.
- void printAsTextualPipeline(raw_ostream &os);
+ void printAsTextualPipeline(raw_ostream &os, bool pretty = false);
//===--------------------------------------------------------------------===//
// Statistics
diff --git a/mlir/include/mlir/Pass/PassManager.h b/mlir/include/mlir/Pass/PassManager.h
index 2287b0a33f47d..ec2207c278cdd 100644
--- a/mlir/include/mlir/Pass/PassManager.h
+++ b/mlir/include/mlir/Pass/PassManager.h
@@ -143,7 +143,7 @@ class OpPassManager {
/// of pipelines.
/// Note: The quality of the string representation depends entirely on the
/// the correctness of per-pass overrides of Pass::printAsTextualPipeline.
- void printAsTextualPipeline(raw_ostream &os) const;
+ void printAsTextualPipeline(raw_ostream &os, bool pretty = false) const;
/// Raw dump of the pass manager to llvm::errs().
void dump();
diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp
index 6e8d3bbfdff81..d34a4726cad26 100644
--- a/mlir/lib/Pass/Pass.cpp
+++ b/mlir/lib/Pass/Pass.cpp
@@ -82,12 +82,12 @@ void Pass::copyOptionValuesFrom(const Pass *other) {
/// Prints out the pass in the textual representation of pipelines. If this is
/// an adaptor pass, print its pass managers.
-void Pass::printAsTextualPipeline(raw_ostream &os) {
+void Pass::printAsTextualPipeline(raw_ostream &os, bool pretty) {
// Special case for adaptors to print its pass managers.
if (auto *adaptor = dyn_cast<OpToOpPassAdaptor>(this)) {
llvm::interleave(
adaptor->getPassManagers(),
- [&](OpPassManager &pm) { pm.printAsTextualPipeline(os); },
+ [&](OpPassManager &pm) { pm.printAsTextualPipeline(os, pretty); },
[&] { os << ","; });
return;
}
@@ -394,14 +394,24 @@ StringRef OpPassManager::getOpAnchorName() const {
/// of pipelines.
void printAsTextualPipeline(
raw_indented_ostream &os, StringRef anchorName,
- const llvm::iterator_range<OpPassManager::pass_iterator> &passes) {
- os << anchorName << "(\n";
- os.indent();
+ const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
+ bool pretty = false) {
+ os << anchorName << "(";
+ if (pretty) {
+ os << "\n";
+ os.indent();
+ }
llvm::interleave(
passes, [&](mlir::Pass &pass) { pass.printAsTextualPipeline(os); },
- [&]() { os << ",\n"; });
- os << "\n";
- os.unindent();
+ [&]() {
+ os << ",";
+ if (pretty)
+ os << "\n";
+ });
+ if (pretty) {
+ os << "\n";
+ os.unindent();
+ }
os << ")";
}
void printAsTextualPipeline(
@@ -410,18 +420,19 @@ void printAsTextualPipeline(
raw_indented_ostream indentedOS(os);
printAsTextualPipeline(indentedOS, anchorName, passes);
}
-void OpPassManager::printAsTextualPipeline(raw_ostream &os) const {
+void OpPassManager::printAsTextualPipeline(raw_ostream &os, bool pretty) const {
StringRef anchorName = getOpAnchorName();
raw_indented_ostream indentedOS(os);
::printAsTextualPipeline(
indentedOS, anchorName,
{MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.begin(),
- MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.end()});
+ MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.end()},
+ pretty);
}
void OpPassManager::dump() {
llvm::errs() << "Pass Manager with " << impl->passes.size() << " passes:\n";
- printAsTextualPipeline(llvm::errs());
+ printAsTextualPipeline(llvm::errs(), /*pretty=*/true);
llvm::errs() << "\n";
}
@@ -477,7 +488,6 @@ llvm::hash_code OpPassManager::hash() {
return hashCode;
}
-
//===----------------------------------------------------------------------===//
// OpToOpPassAdaptor
//===----------------------------------------------------------------------===//
@@ -882,7 +892,8 @@ LogicalResult PassManager::run(Operation *op) {
// Initialize all of the passes within the pass manager with a new generation.
llvm::hash_code newInitKey = context->getRegistryHash();
llvm::hash_code pipelineKey = hash();
- if (newInitKey != initializationKey || pipelineKey != pipelineInitializationKey) {
+ if (newInitKey != initializationKey ||
+ pipelineKey != pipelineInitializationKey) {
if (failed(initialize(context, impl->initializationGeneration + 1)))
return failure();
initializationKey = newInitKey;
diff --git a/mlir/test/Pass/pipeline-parsing.mlir b/mlir/test/Pass/pipeline-parsing.mlir
index f41553d2669f0..7f368c6df2af5 100644
--- a/mlir/test/Pass/pipeline-parsing.mlir
+++ b/mlir/test/Pass/pipeline-parsing.mlir
@@ -21,7 +21,9 @@
// CHECK_ERROR_7: can't run 'wrong-op' pass manager on 'builtin.module' op
// RUN: mlir-opt %s -pass-pipeline='any(cse)' -dump-pass-pipeline 2>&1 | FileCheck %s -check-prefix=CHECK_ROUNDTRIP
-// CHECK_ROUNDTRIP: any(cse)
+// CHECK_ROUNDTRIP: any(
+// CHECK_ROUNDTRIP-NEXT: cse
+// CHECK_ROUNDTRIP-NEXT: )
func.func @foo() {
return
diff --git a/mlir/test/Pass/run-reproducer.mlir b/mlir/test/Pass/run-reproducer.mlir
index bf3ab2dae2ff8..5e455cb30a66c 100644
--- a/mlir/test/Pass/run-reproducer.mlir
+++ b/mlir/test/Pass/run-reproducer.mlir
@@ -14,7 +14,9 @@ func.func @bar() {
external_resources: {
mlir_reproducer: {
verify_each: true,
- // CHECK: builtin.module(func.func(cse,canonicalize{ max-iterations=1 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=false}))
+ // CHECK: builtin.module(
+ // CHECK-NEXT: func.func(cse,canonicalize{ max-iterations=1 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=false})
+ // CHECK-NEXT: )
pipeline: "builtin.module(func.func(cse,canonicalize{max-iterations=1 max-num-rewrites=-1 region-simplify=normal top-down=false}))",
disable_threading: true
}
diff --git a/mlir/test/Transforms/composite-pass.mlir b/mlir/test/Transforms/composite-pass.mlir
index 75587edd5b96d..65764a96a4016 100644
--- a/mlir/test/Transforms/composite-pass.mlir
+++ b/mlir/test/Transforms/composite-pass.mlir
@@ -2,8 +2,9 @@
// RUN: mlir-opt %s --log-actions-to=- --composite-fixed-point-pass='name=TestCompositePass pipeline=any(canonicalize,cse)' -split-input-file | FileCheck %s
// Ensure the composite pass correctly prints its options.
-// PIPELINE: builtin.module(composite-fixed-point-pass{max-iterations=10 name=TestCompositePass
-// PIPELINE-SAME: pipeline=canonicalize{ max-iterations=10 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=true},cse})
+// PIPELINE: builtin.module(
+// PIPELINE-NEXT: composite-fixed-point-pass{max-iterations=10 name=TestCompositePass
+// PIPELINE-SAME: pipeline=canonicalize{ max-iterations=10 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=true},cse}
// CHECK-LABEL: running `TestCompositePass`
// CHECK: running `Canonicalizer`
diff --git a/mlir/test/Transforms/inlining-dump-default-pipeline.mlir b/mlir/test/Transforms/inlining-dump-default-pipeline.mlir
index 4f8638054206e..ef5fac49c6ce2 100644
--- a/mlir/test/Transforms/inlining-dump-default-pipeline.mlir
+++ b/mlir/test/Transforms/inlining-dump-default-pipeline.mlir
@@ -1,2 +1,4 @@
// RUN: mlir-opt %s -pass-pipeline="builtin.module(inline)" -dump-pass-pipeline 2>&1 | FileCheck %s
-// CHECK: builtin.module(inline{default-pipeline=canonicalize inlining-threshold=4294967295 max-iterations=4 })
+// CHECK: builtin.module(
+// CHECK-NEXT: inline{default-pipeline=canonicalize inlining-threshold=4294967295 max-iterations=4 }
+// CHECK-NEXT: )
>From 6821a6ed1593deed1696f3c6691081aaa988385c Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Fri, 6 Jun 2025 19:53:10 -0700
Subject: [PATCH 3/3] fix tests
---
mlir/lib/Pass/Pass.cpp | 12 ++--
mlir/lib/Pass/PassCrashRecovery.cpp | 3 +-
mlir/test/Pass/pipeline-options-parsing.mlir | 76 +++++++++++++++++---
mlir/test/Pass/run-reproducer.mlir | 5 +-
4 files changed, 82 insertions(+), 14 deletions(-)
diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp
index d34a4726cad26..66f8fc4d0234d 100644
--- a/mlir/lib/Pass/Pass.cpp
+++ b/mlir/lib/Pass/Pass.cpp
@@ -88,7 +88,11 @@ void Pass::printAsTextualPipeline(raw_ostream &os, bool pretty) {
llvm::interleave(
adaptor->getPassManagers(),
[&](OpPassManager &pm) { pm.printAsTextualPipeline(os, pretty); },
- [&] { os << ","; });
+ [&] {
+ os << ",";
+ if (pretty)
+ os << "\n";
+ });
return;
}
// Otherwise, print the pass argument followed by its options. If the pass
@@ -402,7 +406,7 @@ void printAsTextualPipeline(
os.indent();
}
llvm::interleave(
- passes, [&](mlir::Pass &pass) { pass.printAsTextualPipeline(os); },
+ passes, [&](mlir::Pass &pass) { pass.printAsTextualPipeline(os, pretty); },
[&]() {
os << ",";
if (pretty)
@@ -416,9 +420,9 @@ void printAsTextualPipeline(
}
void printAsTextualPipeline(
raw_ostream &os, StringRef anchorName,
- const llvm::iterator_range<OpPassManager::pass_iterator> &passes) {
+ const llvm::iterator_range<OpPassManager::pass_iterator> &passes, bool pretty) {
raw_indented_ostream indentedOS(os);
- printAsTextualPipeline(indentedOS, anchorName, passes);
+ printAsTextualPipeline(indentedOS, anchorName, passes, pretty);
}
void OpPassManager::printAsTextualPipeline(raw_ostream &os, bool pretty) const {
StringRef anchorName = getOpAnchorName();
diff --git a/mlir/lib/Pass/PassCrashRecovery.cpp b/mlir/lib/Pass/PassCrashRecovery.cpp
index 8c6d865cb31dd..b048ff9462392 100644
--- a/mlir/lib/Pass/PassCrashRecovery.cpp
+++ b/mlir/lib/Pass/PassCrashRecovery.cpp
@@ -443,7 +443,8 @@ makeReproducerStreamFactory(StringRef outputFile) {
void printAsTextualPipeline(
raw_ostream &os, StringRef anchorName,
- const llvm::iterator_range<OpPassManager::pass_iterator> &passes);
+ const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
+ bool pretty = false);
std::string mlir::makeReproducer(
StringRef anchorName,
diff --git a/mlir/test/Pass/pipeline-options-parsing.mlir b/mlir/test/Pass/pipeline-options-parsing.mlir
index b8cd605a83a2b..9385d353faf95 100644
--- a/mlir/test/Pass/pipeline-options-parsing.mlir
+++ b/mlir/test/Pass/pipeline-options-parsing.mlir
@@ -38,11 +38,71 @@
// CHECK_1: test-options-pass{enum=zero list={1,2,3,4,5} string=nested_pipeline{arg1=10 arg2=" {} " arg3=true} string-list={a,b,c,d}}
// CHECK_2: test-options-pass{enum=one list={1} string= string-list={a,b}}
-// CHECK_3: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string= })))
-// CHECK_4: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string=foobar })))
-// CHECK_5: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string={foo bar baz} })))
-// CHECK_6: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string=foo"bar"baz })))
-// CHECK_7{LITERAL}: builtin.module(func.func(test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one list={2} string=bar },{enum=two list={3} string=baz }}}))
-// CHECK_8{LITERAL}: builtin.module(func.func(test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one string=bar }}}))
-// CHECK_9: builtin.module(func.func(test-options-pass{enum=zero string= string-list={}}))
-// CHECK_10: builtin.module(func.func(test-options-pass{enum=zero string= string-list={,}}))
+
+// CHECK_3: builtin.module(
+// CHECK_3-NEXT: builtin.module(
+// CHECK_3-NEXT: func.func(
+// CHECK_3-NEXT: test-options-pass{enum=zero list={3} string= }
+// CHECK_3-NEXT: ),
+// CHECK_3-NEXT: func.func(
+// CHECK_3-NEXT: test-options-pass{enum=one list={1,2,3,4} string= }
+// CHECK_3-NEXT: )
+// CHECK_3-NEXT: )
+// CHECK_3-NEXT: )
+
+// CHECK_4: builtin.module(
+// CHECK_4-NEXT: builtin.module(
+// CHECK_4-NEXT: func.func(
+// CHECK_4-NEXT: test-options-pass{enum=zero list={3} string= }
+// CHECK_4-NEXT: ),
+// CHECK_4-NEXT: func.func(
+// CHECK_4-NEXT: test-options-pass{enum=one list={1,2,3,4} string=foobar }
+// CHECK_4-NEXT: )
+// CHECK_4-NEXT: )
+// CHECK_4-NEXT: )
+
+// CHECK_5: builtin.module(
+// CHECK_5-NEXT: builtin.module(
+// CHECK_5-NEXT: func.func(
+// CHECK_5-NEXT: test-options-pass{enum=zero list={3} string= }
+// CHECK_5-NEXT: ),
+// CHECK_5-NEXT: func.func(
+// CHECK_5-NEXT: test-options-pass{enum=one list={1,2,3,4} string={foo bar baz} }
+// CHECK_5-NEXT: )
+// CHECK_5-NEXT: )
+// CHECK_5-NEXT: )
+
+// CHECK_6: builtin.module(
+// CHECK_6-NEXT: builtin.module(
+// CHECK_6-NEXT: func.func(
+// CHECK_6-NEXT: test-options-pass{enum=zero list={3} string= }
+// CHECK_6-NEXT: ),
+// CHECK_6-NEXT: func.func(
+// CHECK_6-NEXT: test-options-pass{enum=one list={1,2,3,4} string=foo"bar"baz }
+// CHECK_6-NEXT: )
+// CHECK_6-NEXT: )
+// CHECK_6-NEXT: )
+
+// CHECK_7{LITERAL}: builtin.module(
+// CHECK_7{LITERAL}-NEXT: func.func(
+// CHECK_7{LITERAL}-NEXT: test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one list={2} string=bar },{enum=two list={3} string=baz }}}
+// CHECK_7{LITERAL}-NEXT: )
+// CHECK_7{LITERAL}-NEXT: )
+
+// CHECK_8{LITERAL}: builtin.module(
+// CHECK_8{LITERAL}-NEXT: func.func(
+// CHECK_8{LITERAL}-NEXT: test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one string=bar }}}
+// CHECK_8{LITERAL}-NEXT: )
+// CHECK_8{LITERAL}-NEXT: )
+
+// CHECK_9: builtin.module(
+// CHECK_9-NEXT: func.func(
+// CHECK_9-NEXT: test-options-pass{enum=zero string= string-list={}}
+// CHECK_9-NEXT: )
+// CHECK_9-NEXT: )
+
+// CHECK_10: builtin.module(
+// CHECK_10-NEXT: func.func(
+// CHECK_10-NEXT: test-options-pass{enum=zero string= string-list={,}}
+// CHECK_10-NEXT: )
+// CHECK_10-NEXT: )
diff --git a/mlir/test/Pass/run-reproducer.mlir b/mlir/test/Pass/run-reproducer.mlir
index 5e455cb30a66c..d2daceab163de 100644
--- a/mlir/test/Pass/run-reproducer.mlir
+++ b/mlir/test/Pass/run-reproducer.mlir
@@ -15,7 +15,10 @@ func.func @bar() {
mlir_reproducer: {
verify_each: true,
// CHECK: builtin.module(
- // CHECK-NEXT: func.func(cse,canonicalize{ max-iterations=1 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=false})
+ // CHECK-NEXT: func.func(
+ // CHECK-NEXT: cse,
+ // CHECK-NEXT: canonicalize{ max-iterations=1 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=false}
+ // CHECK-NEXT: )
// CHECK-NEXT: )
pipeline: "builtin.module(func.func(cse,canonicalize{max-iterations=1 max-num-rewrites=-1 region-simplify=normal top-down=false}))",
disable_threading: true
More information about the Mlir-commits
mailing list