Skip to content

Commit b1b84a6

Browse files
authored
Pretty print on -dump-pass-pipeline (#143223)
This PR makes `dump-pass-pipeline` pretty-print the dumped pipeline. For large pipelines the current behavior produces a wall of text that is hard to visually navigate. For the command ```bash mlir-opt --pass-pipeline="builtin.module(flatten-memref, expand-strided-metadata,func.func(arith-expand,func.func(affine-scalrep)))" --dump-pass-pipeline ``` Before: ```bash Pass Manager with 3 passes: builtin.module(flatten-memref,expand-strided-metadata,func.func(arith-expand{include-bf16=false include-f8e8m0=false},func.func(affine-scalrep))) ``` After: ```bash Pass Manager with 3 passes: builtin.module( flatten-memref, expand-strided-metadata, func.func( arith-expand{include-bf16=false include-f8e8m0=false}, func.func( affine-scalrep ) ) ) ``` Another nice feature of this is that the pretty-printed string can still be copy/pasted into `-pass-pipeline` using a quote: ```bash $ bin/mlir-opt --dump-pass-pipeline test.mlir --pass-pipeline=' builtin.module( flatten-memref, expand-strided-metadata, func.func( arith-expand{include-bf16=false include-f8e8m0=false}, func.func( affine-scalrep ) ) )' ``` --------- Co-authored-by: Jeremy Kun <[email protected]>
1 parent d34b392 commit b1b84a6

File tree

9 files changed

+137
-33
lines changed

9 files changed

+137
-33
lines changed

mlir/include/mlir/Pass/Pass.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ class Pass {
118118
function_ref<LogicalResult(const Twine &)> errorHandler);
119119

120120
/// Prints out the pass in the textual representation of pipelines. If this is
121-
/// an adaptor pass, print its pass managers.
122-
void printAsTextualPipeline(raw_ostream &os);
121+
/// an adaptor pass, print its pass managers. When `pretty` is true, the
122+
/// printed pipeline is formatted for readability.
123+
void printAsTextualPipeline(raw_ostream &os, bool pretty = false);
123124

124125
//===--------------------------------------------------------------------===//
125126
// Statistics

mlir/include/mlir/Pass/PassManager.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,12 @@ class OpPassManager {
140140
detail::OpPassManagerImpl &getImpl();
141141

142142
/// Prints out the passes of the pass manager as the textual representation
143-
/// of pipelines.
143+
/// of pipelines. When `pretty` is true, the printed pipeline is formatted
144+
/// for readability.
145+
///
144146
/// Note: The quality of the string representation depends entirely on the
145147
/// the correctness of per-pass overrides of Pass::printAsTextualPipeline.
146-
void printAsTextualPipeline(raw_ostream &os) const;
148+
void printAsTextualPipeline(raw_ostream &os, bool pretty = false) const;
147149

148150
/// Raw dump of the pass manager to llvm::errs().
149151
void dump();

mlir/lib/Pass/Pass.cpp

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "mlir/IR/Threading.h"
1919
#include "mlir/IR/Verifier.h"
2020
#include "mlir/Support/FileUtilities.h"
21+
#include "mlir/Support/IndentedOstream.h"
2122
#include "llvm/ADT/Hashing.h"
2223
#include "llvm/ADT/STLExtras.h"
2324
#include "llvm/ADT/ScopeExit.h"
@@ -80,14 +81,19 @@ void Pass::copyOptionValuesFrom(const Pass *other) {
8081
}
8182

8283
/// Prints out the pass in the textual representation of pipelines. If this is
83-
/// an adaptor pass, print its pass managers.
84-
void Pass::printAsTextualPipeline(raw_ostream &os) {
84+
/// an adaptor pass, print its pass managers. When `pretty` is true, the
85+
/// printed pipeline is formatted for readability.
86+
void Pass::printAsTextualPipeline(raw_ostream &os, bool pretty) {
8587
// Special case for adaptors to print its pass managers.
8688
if (auto *adaptor = dyn_cast<OpToOpPassAdaptor>(this)) {
8789
llvm::interleave(
8890
adaptor->getPassManagers(),
89-
[&](OpPassManager &pm) { pm.printAsTextualPipeline(os); },
90-
[&] { os << ","; });
91+
[&](OpPassManager &pm) { pm.printAsTextualPipeline(os, pretty); },
92+
[&] {
93+
os << ",";
94+
if (pretty)
95+
os << "\n";
96+
});
9197
return;
9298
}
9399
// Otherwise, print the pass argument followed by its options. If the pass
@@ -390,27 +396,51 @@ StringRef OpPassManager::getOpAnchorName() const {
390396
}
391397

392398
/// Prints out the passes of the pass manager as the textual representation
393-
/// of pipelines.
399+
/// of pipelines. When `pretty` is true, the printed pipeline is formatted for
400+
/// readability.
394401
void printAsTextualPipeline(
395-
raw_ostream &os, StringRef anchorName,
396-
const llvm::iterator_range<OpPassManager::pass_iterator> &passes) {
402+
raw_indented_ostream &os, StringRef anchorName,
403+
const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
404+
bool pretty = false) {
397405
os << anchorName << "(";
406+
if (pretty) {
407+
os << "\n";
408+
os.indent();
409+
}
398410
llvm::interleave(
399-
passes, [&](mlir::Pass &pass) { pass.printAsTextualPipeline(os); },
400-
[&]() { os << ","; });
411+
passes,
412+
[&](mlir::Pass &pass) { pass.printAsTextualPipeline(os, pretty); },
413+
[&]() {
414+
os << ",";
415+
if (pretty)
416+
os << "\n";
417+
});
418+
if (pretty) {
419+
os << "\n";
420+
os.unindent();
421+
}
401422
os << ")";
402423
}
403-
void OpPassManager::printAsTextualPipeline(raw_ostream &os) const {
424+
void printAsTextualPipeline(
425+
raw_ostream &os, StringRef anchorName,
426+
const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
427+
bool pretty) {
428+
raw_indented_ostream indentedOS(os);
429+
printAsTextualPipeline(indentedOS, anchorName, passes, pretty);
430+
}
431+
void OpPassManager::printAsTextualPipeline(raw_ostream &os, bool pretty) const {
404432
StringRef anchorName = getOpAnchorName();
433+
raw_indented_ostream indentedOS(os);
405434
::printAsTextualPipeline(
406-
os, anchorName,
435+
indentedOS, anchorName,
407436
{MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.begin(),
408-
MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.end()});
437+
MutableArrayRef<std::unique_ptr<Pass>>{impl->passes}.end()},
438+
pretty);
409439
}
410440

411441
void OpPassManager::dump() {
412442
llvm::errs() << "Pass Manager with " << impl->passes.size() << " passes:\n";
413-
printAsTextualPipeline(llvm::errs());
443+
printAsTextualPipeline(llvm::errs(), /*pretty=*/true);
414444
llvm::errs() << "\n";
415445
}
416446

@@ -466,7 +496,6 @@ llvm::hash_code OpPassManager::hash() {
466496
return hashCode;
467497
}
468498

469-
470499
//===----------------------------------------------------------------------===//
471500
// OpToOpPassAdaptor
472501
//===----------------------------------------------------------------------===//
@@ -871,7 +900,8 @@ LogicalResult PassManager::run(Operation *op) {
871900
// Initialize all of the passes within the pass manager with a new generation.
872901
llvm::hash_code newInitKey = context->getRegistryHash();
873902
llvm::hash_code pipelineKey = hash();
874-
if (newInitKey != initializationKey || pipelineKey != pipelineInitializationKey) {
903+
if (newInitKey != initializationKey ||
904+
pipelineKey != pipelineInitializationKey) {
875905
if (failed(initialize(context, impl->initializationGeneration + 1)))
876906
return failure();
877907
initializationKey = newInitKey;

mlir/lib/Pass/PassCrashRecovery.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ makeReproducerStreamFactory(StringRef outputFile) {
443443

444444
void printAsTextualPipeline(
445445
raw_ostream &os, StringRef anchorName,
446-
const llvm::iterator_range<OpPassManager::pass_iterator> &passes);
446+
const llvm::iterator_range<OpPassManager::pass_iterator> &passes,
447+
bool pretty = false);
447448

448449
std::string mlir::makeReproducer(
449450
StringRef anchorName,

mlir/test/Pass/pipeline-options-parsing.mlir

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,71 @@
3838

3939
// 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}}
4040
// CHECK_2: test-options-pass{enum=one list={1} string= string-list={a,b}}
41-
// 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= })))
42-
// 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 })))
43-
// 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} })))
44-
// 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 })))
45-
// 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 }}}))
46-
// CHECK_8{LITERAL}: builtin.module(func.func(test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one string=bar }}}))
47-
// CHECK_9: builtin.module(func.func(test-options-pass{enum=zero string= string-list={}}))
48-
// CHECK_10: builtin.module(func.func(test-options-pass{enum=zero string= string-list={,}}))
41+
42+
// CHECK_3: builtin.module(
43+
// CHECK_3-NEXT: builtin.module(
44+
// CHECK_3-NEXT: func.func(
45+
// CHECK_3-NEXT: test-options-pass{enum=zero list={3} string= }
46+
// CHECK_3-NEXT: ),
47+
// CHECK_3-NEXT: func.func(
48+
// CHECK_3-NEXT: test-options-pass{enum=one list={1,2,3,4} string= }
49+
// CHECK_3-NEXT: )
50+
// CHECK_3-NEXT: )
51+
// CHECK_3-NEXT: )
52+
53+
// CHECK_4: builtin.module(
54+
// CHECK_4-NEXT: builtin.module(
55+
// CHECK_4-NEXT: func.func(
56+
// CHECK_4-NEXT: test-options-pass{enum=zero list={3} string= }
57+
// CHECK_4-NEXT: ),
58+
// CHECK_4-NEXT: func.func(
59+
// CHECK_4-NEXT: test-options-pass{enum=one list={1,2,3,4} string=foobar }
60+
// CHECK_4-NEXT: )
61+
// CHECK_4-NEXT: )
62+
// CHECK_4-NEXT: )
63+
64+
// CHECK_5: builtin.module(
65+
// CHECK_5-NEXT: builtin.module(
66+
// CHECK_5-NEXT: func.func(
67+
// CHECK_5-NEXT: test-options-pass{enum=zero list={3} string= }
68+
// CHECK_5-NEXT: ),
69+
// CHECK_5-NEXT: func.func(
70+
// CHECK_5-NEXT: test-options-pass{enum=one list={1,2,3,4} string={foo bar baz} }
71+
// CHECK_5-NEXT: )
72+
// CHECK_5-NEXT: )
73+
// CHECK_5-NEXT: )
74+
75+
// CHECK_6: builtin.module(
76+
// CHECK_6-NEXT: builtin.module(
77+
// CHECK_6-NEXT: func.func(
78+
// CHECK_6-NEXT: test-options-pass{enum=zero list={3} string= }
79+
// CHECK_6-NEXT: ),
80+
// CHECK_6-NEXT: func.func(
81+
// CHECK_6-NEXT: test-options-pass{enum=one list={1,2,3,4} string=foo"bar"baz }
82+
// CHECK_6-NEXT: )
83+
// CHECK_6-NEXT: )
84+
// CHECK_6-NEXT: )
85+
86+
// CHECK_7{LITERAL}: builtin.module(
87+
// CHECK_7{LITERAL}-NEXT: func.func(
88+
// 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 }}}
89+
// CHECK_7{LITERAL}-NEXT: )
90+
// CHECK_7{LITERAL}-NEXT: )
91+
92+
// CHECK_8{LITERAL}: builtin.module(
93+
// CHECK_8{LITERAL}-NEXT: func.func(
94+
// CHECK_8{LITERAL}-NEXT: test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one string=bar }}}
95+
// CHECK_8{LITERAL}-NEXT: )
96+
// CHECK_8{LITERAL}-NEXT: )
97+
98+
// CHECK_9: builtin.module(
99+
// CHECK_9-NEXT: func.func(
100+
// CHECK_9-NEXT: test-options-pass{enum=zero string= string-list={}}
101+
// CHECK_9-NEXT: )
102+
// CHECK_9-NEXT: )
103+
104+
// CHECK_10: builtin.module(
105+
// CHECK_10-NEXT: func.func(
106+
// CHECK_10-NEXT: test-options-pass{enum=zero string= string-list={,}}
107+
// CHECK_10-NEXT: )
108+
// CHECK_10-NEXT: )

mlir/test/Pass/pipeline-parsing.mlir

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
// CHECK_ERROR_7: can't run 'wrong-op' pass manager on 'builtin.module' op
2222

2323
// RUN: mlir-opt %s -pass-pipeline='any(cse)' -dump-pass-pipeline 2>&1 | FileCheck %s -check-prefix=CHECK_ROUNDTRIP
24-
// CHECK_ROUNDTRIP: any(cse)
24+
// CHECK_ROUNDTRIP: any(
25+
// CHECK_ROUNDTRIP-NEXT: cse
26+
// CHECK_ROUNDTRIP-NEXT: )
2527

2628
func.func @foo() {
2729
return

mlir/test/Pass/run-reproducer.mlir

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ func.func @bar() {
1414
external_resources: {
1515
mlir_reproducer: {
1616
verify_each: true,
17-
// CHECK: builtin.module(func.func(cse,canonicalize{ max-iterations=1 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=false}))
17+
// CHECK: builtin.module(
18+
// CHECK-NEXT: func.func(
19+
// CHECK-NEXT: cse,
20+
// CHECK-NEXT: canonicalize{ max-iterations=1 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=false}
21+
// CHECK-NEXT: )
22+
// CHECK-NEXT: )
1823
pipeline: "builtin.module(func.func(cse,canonicalize{max-iterations=1 max-num-rewrites=-1 region-simplify=normal top-down=false}))",
1924
disable_threading: true
2025
}

mlir/test/Transforms/composite-pass.mlir

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// RUN: mlir-opt %s --log-actions-to=- --composite-fixed-point-pass='name=TestCompositePass pipeline=any(canonicalize,cse)' -split-input-file | FileCheck %s
33

44
// Ensure the composite pass correctly prints its options.
5-
// PIPELINE: builtin.module(composite-fixed-point-pass{max-iterations=10 name=TestCompositePass
6-
// PIPELINE-SAME: pipeline=canonicalize{ max-iterations=10 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=true},cse})
5+
// PIPELINE: builtin.module(
6+
// PIPELINE-NEXT: composite-fixed-point-pass{max-iterations=10 name=TestCompositePass
7+
// PIPELINE-SAME: pipeline=canonicalize{ max-iterations=10 max-num-rewrites=-1 region-simplify=normal test-convergence=false top-down=true},cse}
78

89
// CHECK-LABEL: running `TestCompositePass`
910
// CHECK: running `Canonicalizer`
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
// RUN: mlir-opt %s -pass-pipeline="builtin.module(inline)" -dump-pass-pipeline 2>&1 | FileCheck %s
2-
// CHECK: builtin.module(inline{default-pipeline=canonicalize inlining-threshold=4294967295 max-iterations=4 })
2+
// CHECK: builtin.module(
3+
// CHECK-NEXT: inline{default-pipeline=canonicalize inlining-threshold=4294967295 max-iterations=4 }
4+
// CHECK-NEXT: )

0 commit comments

Comments
 (0)