[mlir] Include anchor op when printing pass managers

Previously a pipeline nested on `anchor-op` would print as just
`'pipeline'`, now it will print as `'anchor-op(pipeline)'`. This ensures
the text form includes all information needed to reconstruct the pass
manager.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D134622
This commit is contained in:
rkayaith
2022-09-25 16:47:39 -04:00
parent de9731b703
commit e874bbc292
5 changed files with 24 additions and 28 deletions

View File

@@ -118,7 +118,7 @@ public:
virtual LogicalResult initializeOptions(StringRef options);
/// Prints out the pass in the textual representation of pipelines. If this is
/// an adaptor pass, print with the op_name(sub_pass,...) format.
/// an adaptor pass, print its pass managers.
void printAsTextualPipeline(raw_ostream &os);
//===--------------------------------------------------------------------===//

View File

@@ -50,17 +50,13 @@ void Pass::copyOptionValuesFrom(const Pass *other) {
}
/// Prints out the pass in the textual representation of pipelines. If this is
/// an adaptor pass, print with the op_name(sub_pass,...) format.
/// an adaptor pass, print its pass managers.
void Pass::printAsTextualPipeline(raw_ostream &os) {
// Special case for adaptors to use the 'op_name(sub_passes)' format.
// Special case for adaptors to print its pass managers.
if (auto *adaptor = dyn_cast<OpToOpPassAdaptor>(this)) {
llvm::interleave(
adaptor->getPassManagers(),
[&](OpPassManager &pm) {
os << pm.getOpAnchorName() << "(";
pm.printAsTextualPipeline(os);
os << ")";
},
[&](OpPassManager &pm) { pm.printAsTextualPipeline(os); },
[&] { os << ","; });
return;
}
@@ -355,26 +351,22 @@ StringRef OpPassManager::getOpAnchorName() const {
return impl->getOpAnchorName();
}
/// Prints out the given passes as the textual representation of a pipeline.
static void printAsTextualPipeline(ArrayRef<std::unique_ptr<Pass>> passes,
raw_ostream &os) {
llvm::interleave(
passes,
[&](const std::unique_ptr<Pass> &pass) {
pass->printAsTextualPipeline(os);
},
[&] { os << ","; });
}
/// Prints out the passes of the pass manager as the textual representation
/// of pipelines.
void OpPassManager::printAsTextualPipeline(raw_ostream &os) const {
::printAsTextualPipeline(impl->passes, os);
os << getOpAnchorName() << "(";
llvm::interleave(
impl->passes,
[&](const std::unique_ptr<Pass> &pass) {
pass->printAsTextualPipeline(os);
},
[&]() { os << ","; });
os << ")";
}
void OpPassManager::dump() {
llvm::errs() << "Pass Manager with " << impl->passes.size() << " passes: ";
::printAsTextualPipeline(impl->passes, llvm::errs());
printAsTextualPipeline(llvm::errs());
llvm::errs() << "\n";
}

View File

@@ -145,20 +145,22 @@ void testPrintPassPipeline() {
mlirOpPassManagerAddOwnedPass(nestedFuncPm, printOpStatPass);
// Print the top level pass manager
// CHECK: Top-level: builtin.module(func.func(print-op-stats{json=false}))
// CHECK: Top-level: builtin.module(
// CHECK-SAME: builtin.module(func.func(print-op-stats{json=false}))
// CHECK-SAME: )
fprintf(stderr, "Top-level: ");
mlirPrintPassPipeline(mlirPassManagerGetAsOpPassManager(pm), printToStderr,
NULL);
fprintf(stderr, "\n");
// Print the pipeline nested one level down
// CHECK: Nested Module: func.func(print-op-stats{json=false})
// CHECK: Nested Module: builtin.module(func.func(print-op-stats{json=false}))
fprintf(stderr, "Nested Module: ");
mlirPrintPassPipeline(nestedModulePm, printToStderr, NULL);
fprintf(stderr, "\n");
// Print the pipeline nested two levels down
// CHECK: Nested Module>Func: print-op-stats
// CHECK: Nested Module>Func: func.func(print-op-stats{json=false})
fprintf(stderr, "Nested Module>Func: ");
mlirPrintPassPipeline(nestedFuncPm, printToStderr, NULL);
fprintf(stderr, "\n");
@@ -197,8 +199,10 @@ void testParsePassPipeline() {
exit(EXIT_FAILURE);
}
// CHECK: Round-trip: builtin.module(func.func(print-op-stats{json=false}),
// func.func(print-op-stats{json=false}))
// CHECK: Round-trip: builtin.module(builtin.module(
// CHECK-SAME: func.func(print-op-stats{json=false}),
// CHECK-SAME: func.func(print-op-stats{json=false})
// CHECK-SAME: ))
fprintf(stderr, "Round-trip: ");
mlirPrintPassPipeline(mlirPassManagerGetAsOpPassManager(pm), printToStderr,
NULL);

View File

@@ -14,4 +14,4 @@
// CHECK_1: test-options-pass{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{list=1 string= string-list=a,b}
// CHECK_3: builtin.module(func.func(test-options-pass{list=3 string= }),func.func(test-options-pass{list=1,2,3,4 string= }))
// CHECK_3: builtin.module(builtin.module(func.func(test-options-pass{list=3 string= }),func.func(test-options-pass{list=1,2,3,4 string= })))

View File

@@ -46,7 +46,7 @@ def testParseSuccess():
# A registered pass should parse successfully.
pm = PassManager.parse("builtin.module(func.func(print-op-stats{json=false}))")
# CHECK: Roundtrip: builtin.module(func.func(print-op-stats{json=false}))
# CHECK: Roundtrip: builtin.module(builtin.module(func.func(print-op-stats{json=false})))
log("Roundtrip: ", pm)
run(testParseSuccess)