[llvm-branch-commits] [mlir] e9cda7c - [mlir][Pass] Add a new PassNameCLParser specifically for parsing lists of pass names

River Riddle via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 15 15:04:21 PST 2020


Author: River Riddle
Date: 2020-12-15T14:56:09-08:00
New Revision: e9cda7c5a0b70dd029e201cd2cc2e1d7105d0672

URL: https://github.com/llvm/llvm-project/commit/e9cda7c5a0b70dd029e201cd2cc2e1d7105d0672
DIFF: https://github.com/llvm/llvm-project/commit/e9cda7c5a0b70dd029e201cd2cc2e1d7105d0672.diff

LOG: [mlir][Pass] Add a new PassNameCLParser specifically for parsing lists of pass names

This parser does not include the general `pass_pipeline` option, the pass pipeline entries, or the options of pass entries. This is useful for cases such as `print-ir-after` that just want the user to select specific pass types. This revision greatly reduces the amount of text in --help for several MLIR based tools.

Fixes PR#45495

Differential Revision: https://reviews.llvm.org/D92987

Added: 
    

Modified: 
    mlir/include/mlir/Pass/PassRegistry.h
    mlir/lib/Pass/PassManagerOptions.cpp
    mlir/lib/Pass/PassRegistry.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Pass/PassRegistry.h b/mlir/include/mlir/Pass/PassRegistry.h
index 52ded58ccfe6..9937102f316d 100644
--- a/mlir/include/mlir/Pass/PassRegistry.h
+++ b/mlir/include/mlir/Pass/PassRegistry.h
@@ -246,6 +246,26 @@ class PassPipelineCLParser {
   std::unique_ptr<detail::PassPipelineCLParserImpl> impl;
 };
 
+/// This class implements a command-line parser spefically for MLIR pass names.
+/// It registers a cl option with a given argument and description that accepts
+/// a comma delimited list of pass names.
+class PassNameCLParser {
+public:
+  /// Construct a parser with the given command line description.
+  PassNameCLParser(StringRef arg, StringRef description);
+  ~PassNameCLParser();
+
+  /// Returns true if this parser contains any valid options to add.
+  bool hasAnyOccurrences() const;
+
+  /// Returns true if the given pass registry entry was registered at the
+  /// top-level of the parser, i.e. not within an explicit textual pipeline.
+  bool contains(const PassRegistryEntry *entry) const;
+
+private:
+  std::unique_ptr<detail::PassPipelineCLParserImpl> impl;
+};
+
 } // end namespace mlir
 
 #endif // MLIR_PASS_PASSREGISTRY_H_

diff  --git a/mlir/lib/Pass/PassManagerOptions.cpp b/mlir/lib/Pass/PassManagerOptions.cpp
index a581ce070fc4..0af58ad9738b 100644
--- a/mlir/lib/Pass/PassManagerOptions.cpp
+++ b/mlir/lib/Pass/PassManagerOptions.cpp
@@ -32,10 +32,10 @@ struct PassManagerOptions {
   //===--------------------------------------------------------------------===//
   // IR Printing
   //===--------------------------------------------------------------------===//
-  PassPipelineCLParser printBefore{"print-ir-before",
-                                   "Print IR before specified passes"};
-  PassPipelineCLParser printAfter{"print-ir-after",
-                                  "Print IR after specified passes"};
+  PassNameCLParser printBefore{"print-ir-before",
+                               "Print IR before specified passes"};
+  PassNameCLParser printAfter{"print-ir-after",
+                              "Print IR after specified passes"};
   llvm::cl::opt<bool> printBeforeAll{
       "print-ir-before-all", llvm::cl::desc("Print IR before each pass"),
       llvm::cl::init(false)};

diff  --git a/mlir/lib/Pass/PassRegistry.cpp b/mlir/lib/Pass/PassRegistry.cpp
index 50cbee8dc12d..f41ca72d7838 100644
--- a/mlir/lib/Pass/PassRegistry.cpp
+++ b/mlir/lib/Pass/PassRegistry.cpp
@@ -543,6 +543,12 @@ struct PassNameParser : public llvm::cl::parser<PassArgData> {
   size_t getOptionWidth(const llvm::cl::Option &opt) const override;
   bool parse(llvm::cl::Option &opt, StringRef argName, StringRef arg,
              PassArgData &value);
+
+  /// If true, this parser only parses entries that correspond to a concrete
+  /// pass registry entry, and does not add a `pass-pipeline` argument, does not
+  /// include the options for pass entries, and does not include pass pipelines
+  /// entries.
+  bool passNamesOnly = false;
 };
 } // namespace
 
@@ -550,8 +556,10 @@ void PassNameParser::initialize() {
   llvm::cl::parser<PassArgData>::initialize();
 
   /// Add an entry for the textual pass pipeline option.
-  addLiteralOption(passPipelineArg, PassArgData(),
-                   "A textual description of a pass pipeline to run");
+  if (!passNamesOnly) {
+    addLiteralOption(passPipelineArg, PassArgData(),
+                     "A textual description of a pass pipeline to run");
+  }
 
   /// Add the pass entries.
   for (const auto &kv : *passRegistry) {
@@ -559,14 +567,24 @@ void PassNameParser::initialize() {
                      kv.second.getPassDescription());
   }
   /// Add the pass pipeline entries.
-  for (const auto &kv : *passPipelineRegistry) {
-    addLiteralOption(kv.second.getPassArgument(), &kv.second,
-                     kv.second.getPassDescription());
+  if (!passNamesOnly) {
+    for (const auto &kv : *passPipelineRegistry) {
+      addLiteralOption(kv.second.getPassArgument(), &kv.second,
+                       kv.second.getPassDescription());
+    }
   }
 }
 
 void PassNameParser::printOptionInfo(const llvm::cl::Option &opt,
                                      size_t globalWidth) const {
+  // If this parser is just parsing pass names, print a simplified option
+  // string.
+  if (passNamesOnly) {
+    llvm::outs() << "  --" << opt.ArgStr << "=<pass-arg>";
+    opt.printHelpStr(opt.HelpStr, globalWidth, opt.ArgStr.size() + 18);
+    return;
+  }
+
   // Print the information for the top-level option.
   if (opt.hasArgStr()) {
     llvm::outs() << "  --" << opt.ArgStr;
@@ -635,11 +653,21 @@ bool PassNameParser::parse(llvm::cl::Option &opt, StringRef argName,
 namespace mlir {
 namespace detail {
 struct PassPipelineCLParserImpl {
-  PassPipelineCLParserImpl(StringRef arg, StringRef description)
+  PassPipelineCLParserImpl(StringRef arg, StringRef description,
+                           bool passNamesOnly)
       : passList(arg, llvm::cl::desc(description)) {
+    passList.getParser().passNamesOnly = passNamesOnly;
     passList.setValueExpectedFlag(llvm::cl::ValueExpected::ValueOptional);
   }
 
+  /// Returns true if the given pass registry entry was registered at the
+  /// top-level of the parser, i.e. not within an explicit textual pipeline.
+  bool contains(const PassRegistryEntry *entry) const {
+    return llvm::any_of(passList, [&](const PassArgData &data) {
+      return data.registryEntry == entry;
+    });
+  }
+
   /// The set of passes and pass pipelines to run.
   llvm::cl::list<PassArgData, bool, PassNameParser> passList;
 };
@@ -648,8 +676,8 @@ struct PassPipelineCLParserImpl {
 
 /// Construct a pass pipeline parser with the given command line description.
 PassPipelineCLParser::PassPipelineCLParser(StringRef arg, StringRef description)
-    : impl(std::make_unique<detail::PassPipelineCLParserImpl>(arg,
-                                                              description)) {}
+    : impl(std::make_unique<detail::PassPipelineCLParserImpl>(
+          arg, description, /*passNamesOnly=*/false)) {}
 PassPipelineCLParser::~PassPipelineCLParser() {}
 
 /// Returns true if this parser contains any valid options to add.
@@ -660,9 +688,7 @@ bool PassPipelineCLParser::hasAnyOccurrences() const {
 /// Returns true if the given pass registry entry was registered at the
 /// top-level of the parser, i.e. not within an explicit textual pipeline.
 bool PassPipelineCLParser::contains(const PassRegistryEntry *entry) const {
-  return llvm::any_of(impl->passList, [&](const PassArgData &data) {
-    return data.registryEntry == entry;
-  });
+  return impl->contains(entry);
 }
 
 /// Adds the passes defined by this parser entry to the given pass manager.
@@ -685,3 +711,25 @@ LogicalResult PassPipelineCLParser::addToPipeline(
   }
   return success();
 }
+
+//===----------------------------------------------------------------------===//
+// PassNameCLParser
+
+/// Construct a pass pipeline parser with the given command line description.
+PassNameCLParser::PassNameCLParser(StringRef arg, StringRef description)
+    : impl(std::make_unique<detail::PassPipelineCLParserImpl>(
+          arg, description, /*passNamesOnly=*/true)) {
+  impl->passList.setMiscFlag(llvm::cl::CommaSeparated);
+}
+PassNameCLParser::~PassNameCLParser() {}
+
+/// Returns true if this parser contains any valid options to add.
+bool PassNameCLParser::hasAnyOccurrences() const {
+  return impl->passList.getNumOccurrences() != 0;
+}
+
+/// Returns true if the given pass registry entry was registered at the
+/// top-level of the parser, i.e. not within an explicit textual pipeline.
+bool PassNameCLParser::contains(const PassRegistryEntry *entry) const {
+  return impl->contains(entry);
+}


        


More information about the llvm-branch-commits mailing list