14#ifndef MLIR_PASS_PASSOPTIONS_H_
15#define MLIR_PASS_PASSOPTIONS_H_
18#include "llvm/ADT/FunctionExtras.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/CommandLine.h"
21#include "llvm/Support/Compiler.h"
36template <
typename ElementParser,
typename ElementAppendFn>
39 ElementParser &elementParser,
40 ElementAppendFn &&appendFn) {
42 opt, argName, optionStr, [&](StringRef valueStr) {
43 typename ElementParser::parser_data_type value = {};
44 if (elementParser.parse(opt, argName, valueStr, value))
54 decltype(std::declval<raw_ostream &>() << std::declval<T>());
59template <
typename ParserT>
61 os << (value ? StringRef(
"true") : StringRef(
"false"));
63template <
typename ParserT>
66 const size_t spaceIndex = str.find_first_of(
' ');
67 const size_t escapeIndex =
68 std::min({str.find_first_of(
'{'), str.find_first_of(
'\''),
69 str.find_first_of(
'"')});
70 const bool requiresEscape = spaceIndex < escapeIndex;
77template <
typename ParserT,
typename DataT>
84 ParserT::print(os, value);
95 virtual ~OptionBase() =
default;
98 virtual void anchor();
104 StringRef getArgStr()
const {
return getOption()->ArgStr; }
107 bool hasValue()
const {
return optHasValue; }
111 virtual const llvm::cl::Option *getOption()
const = 0;
114 virtual void copyValueFrom(
const OptionBase &other) = 0;
117 bool optHasValue =
false;
126 template <
typename DataType>
131 std::optional<StringRef> findArgStrForValue(
const DataType &value) {
132 for (
auto &it : this->Values)
133 if (it.V.compare(value))
142 template <
typename PassOptionsT>
147 bool parse(llvm::cl::Option &, StringRef, StringRef arg,
148 PassOptionsT &value) {
149 return failed(value.parseFromString(arg));
153 static void print(llvm::raw_ostream &os,
const PassOptionsT &value) {
159 template <
typename DataT>
160 static void printValue(
raw_ostream &os, GenericOptionParser<DataT> &parser,
161 const DataT &value) {
162 if (std::optional<StringRef> argStr = parser.findArgStrForValue(value))
165 llvm_unreachable(
"unknown data value for option");
167 template <
typename DataT,
typename ParserT>
168 static void printValue(
raw_ostream &os, ParserT &parser,
const DataT &value) {
175 template <
typename DataType>
179 std::is_base_of_v<PassOptions, DataType>, PassOptionsParser<DataType>,
184 std::conditional_t<std::is_base_of<llvm::cl::generic_parser_base,
186 GenericOptionParser<DataType>,
191 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
193 :
public llvm::cl::opt<DataType, false, OptionParser>,
196 template <
typename... Args>
197 Option(PassOptions &parent, StringRef arg, Args &&...args)
199 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...) {
200 assert(!this->isPositional() && !this->isSink() &&
201 "sink and positional options are not supported");
202 parent.options.push_back(
this);
205 this->setCallback([
this](
const auto &) { this->optHasValue =
true; });
208 using llvm::cl::opt<DataType,
false,
211 *
this = other.getValue();
217 const llvm::cl::Option *getOption() const final {
return this; }
221 os << this->ArgStr <<
'=';
222 printValue(os, this->getParser(), this->getValue());
226 void copyValueFrom(
const OptionBase &other)
final {
229 optHasValue = other.optHasValue;
238 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
240 :
public llvm::cl::list<DataType, bool, OptionParser>,
243 template <
typename... Args>
244 ListOption(PassOptions &parent, StringRef arg, Args &&...args)
246 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...),
248 assert(!this->isPositional() && !this->isSink() &&
249 "sink and positional options are not supported");
250 assert(!(this->getMiscFlags() & llvm::cl::MiscFlags::CommaSeparated) &&
251 "ListOption is implicitly comma separated, specifying "
252 "CommaSeparated is extraneous");
255 if (!this->isDefaultAssigned())
256 this->setInitialValues({});
258 parent.options.push_back(
this);
265 this->optHasValue = other.optHasValue;
270 StringRef arg)
override {
271 if (this->isDefaultAssigned()) {
273 this->overwriteDefault();
275 this->optHasValue =
true;
278 [&](
const DataType &value) { this->addValue(value); }));
283 ((std::vector<DataType> &)*
this).assign(values.begin(), values.end());
290 return static_cast<std::vector<DataType> &
>(*this);
293 return static_cast<const std::vector<DataType> &
>(*this);
298 const llvm::cl::Option *getOption() const final {
return this; }
306 if (this->isDefaultAssigned() &&
307 this->getDefault().size() == (**this).size()) {
309 for (
unsigned e = (**this).size(); i < e; i++) {
310 if (!this->getDefault()[i].compare((**
this)[i]))
313 if (i == (**this).size())
317 os << this->ArgStr <<
"={";
318 auto printElementFn = [&](
const DataType &value) {
319 printValue(os, this->getParser(), value);
321 llvm::interleave(*
this, os, printElementFn,
",");
326 void copyValueFrom(
const OptionBase &other)
final {
334 PassOptions() =
default;
336 PassOptions(
const PassOptions &) =
delete;
337 PassOptions(PassOptions &&) =
delete;
341 void copyOptionValuesFrom(
const PassOptions &other);
346 LogicalResult parseFromString(StringRef
options,
347 raw_ostream &errorStream = llvm::errs());
351 void print(raw_ostream &os)
const;
355 void printHelp(
size_t indent,
size_t descIndent)
const;
358 size_t getOptionWidth()
const;
362 std::vector<OptionBase *>
options;
384 static std::unique_ptr<T> createFromString(StringRef
options) {
385 auto result = std::make_unique<T>();
394struct EmptyPipelineOptions :
public PassPipelineOptions<EmptyPipelineOptions> {
409template <
typename VectorT,
typename ElementT>
410class VectorParserBase :
public basic_parser_impl {
412 VectorParserBase(Option &opt) : basic_parser_impl(opt), elementParser(opt) {}
414 using parser_data_type = VectorT;
416 bool parse(Option &opt, StringRef argName, StringRef arg,
417 parser_data_type &vector) {
418 if (!arg.consume_front(
"[") || !arg.consume_back(
"]")) {
419 return opt.error(
"expected vector option to be wrapped with '[]'",
424 opt, argName, arg, elementParser,
425 [&](
const ElementT &value) { vector.push_back(value); }));
428 static void print(raw_ostream &os,
const VectorT &vector) {
431 [&](
const ElementT &value) {
433 llvm::cl::parser<ElementT>>(os, value);
438 void printOptionInfo(
const Option &opt,
size_t globalWidth)
const {
440 outs() <<
" --" << opt.ArgStr;
441 outs() <<
"=<vector<" << elementParser.getValueName() <<
">>";
442 Option::printHelpStr(opt.HelpStr, globalWidth, getOptionWidth(opt));
445 size_t getOptionWidth(
const Option &opt)
const {
447 StringRef vectorExt(
"vector<>");
448 return elementParser.getOptionWidth(opt) + vectorExt.size();
458 :
public detail::VectorParserBase<std::vector<T>, T> {
462template <
typename T,
unsigned N>
464 :
public detail::VectorParserBase<SmallVector<T, N>, T> {
488 assert(
hasValue() &&
"invalid option value");
501 if (!rhsOV.hasValue())
503 return compare(rhsOV.getValue());
507 void anchor()
override;
511 std::unique_ptr<mlir::OpPassManager> value;
530 assert(
value &&
"parsed value was invalid");
534 std::unique_ptr<mlir::OpPassManager>
value;
537 using OptVal = OptionValue<mlir::OpPassManager>;
550 const OptVal &defaultValue,
size_t globalWidth)
const;
false
Parses a map_entries map type from a string format back into its numeric value.
static llvm::ManagedStatic< PassManagerOptions > options
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
This class represents a pass manager that runs passes on either a specific operation type,...
ListOption< DataType, OptionParser > & operator=(const ListOption< DataType, OptionParser > &other)
ListOption< DataType, OptionParser > & operator=(ArrayRef< DataType > values)
Allow assigning from an ArrayRef.
ArrayRef< DataType > operator*() const
ListOption(PassOptions &parent, StringRef arg, Args &&...args)
MutableArrayRef< DataType > operator*()
Allow accessing the data held by this option.
bool handleOccurrence(unsigned pos, StringRef argName, StringRef arg) override
~ListOption() override=default
Option & operator=(const Option &other)
~Option() override=default
Option(PassOptions &parent, StringRef arg, Args &&...args)
Base container class and manager for all pass options.
mlir::detail::PassOptions::ListOption elementParser
std::conditional_t< std::is_base_of_v< PassOptions, DataType >, PassOptionsParser< DataType >, std::conditional_t< std::is_base_of< llvm::cl::generic_parser_base, llvm::cl::parser< DataType > >::value, GenericOptionParser< DataType >, llvm::cl::parser< DataType > > > OptionParser
The specific parser to use.
void printOptionDiff(const Option &opt, mlir::OpPassManager &pm, const OptVal &defaultValue, size_t globalWidth) const
ParsedPassManager parser_data_type
StringRef getValueName() const override
static void print(raw_ostream &os, const mlir::OpPassManager &value)
Print an instance of the underling option value to the given stream.
OptionValue< mlir::OpPassManager > OptVal
bool parse(Option &, StringRef, StringRef arg, ParsedPassManager &value)
The OpAsmOpInterface, see OpAsmInterface.td for more details.
llvm::is_detected< has_stream_operator_trait, T > has_stream_operator
static void printOptionValue(raw_ostream &os, const bool &value)
Utility methods for printing option values.
LogicalResult parseCommaSeparatedList(llvm::cl::Option &opt, StringRef argName, StringRef optionStr, function_ref< LogicalResult(StringRef)> elementParseFn)
Parse a string containing a list of comma-delimited elements, invoking the given parser for each sub-...
decltype(std::declval< raw_ostream & >()<< std::declval< T >()) has_stream_operator_trait
Trait used to detect if a type has a operator<< method.
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
llvm::function_ref< Fn > function_ref
bool compare(const GenericOptionValue &rhs) const override
mlir::OpPassManager WrapperType
mlir::OpPassManager & getValue() const
Returns the current value of the option.
bool compare(const mlir::OpPassManager &rhs) const
Compare the option with the provided value.
void setValue(const mlir::OpPassManager &newValue)
Set the value of the option.
void setValue(StringRef pipelineStr)
OptionValue(const mlir::OpPassManager &value)
bool hasValue() const
Returns if the current option has a value.
OptionValue(const OptionValue< mlir::OpPassManager > &rhs)
OptionValue< mlir::OpPassManager > & operator=(const mlir::OpPassManager &rhs)
A utility struct used when parsing a pass manager that prevents the need for a default constructor on...
std::unique_ptr< mlir::OpPassManager > value
ParsedPassManager(ParsedPassManager &&)