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); +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits