[mlir] Include anchor op when printing pass managers
authorrkayaith <rkayaith@gmail.com>
Sun, 25 Sep 2022 20:47:39 +0000 (16:47 -0400)
committerrkayaith <rkayaith@gmail.com>
Thu, 20 Oct 2022 23:17:45 +0000 (19:17 -0400)
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

mlir/include/mlir/Pass/Pass.h
mlir/lib/Pass/Pass.cpp
mlir/test/CAPI/pass.c
mlir/test/Pass/pipeline-options-parsing.mlir
mlir/test/python/pass_manager.py

index 1db6ef6..45dc818 100644 (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);
 
   //===--------------------------------------------------------------------===//
index 40b8d16..3ca6bce 100644 (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) {
+/// Prints out the passes of the pass manager as the textual representation
+/// of pipelines.
+void OpPassManager::printAsTextualPipeline(raw_ostream &os) const {
+  os << getOpAnchorName() << "(";
   llvm::interleave(
-      passes,
+      impl->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 << ","; });
+  os << ")";
 }
 
 void OpPassManager::dump() {
   llvm::errs() << "Pass Manager with " << impl->passes.size() << " passes: ";
-  ::printAsTextualPipeline(impl->passes, llvm::errs());
+  printAsTextualPipeline(llvm::errs());
   llvm::errs() << "\n";
 }
 
index e48045a..4c68a3e 100644 (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);
index 74eea1a..34e812f 100644 (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= })))
index 1730426..df55f20 100644 (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)