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() &&
"positional options are not supported");
201 parent.options.push_back(
this);
204 this->setCallback([
this](
const auto &) { this->optHasValue =
true; });
207 using llvm::cl::opt<DataType,
false,
210 *
this = other.getValue();
216 const llvm::cl::Option *getOption() const final {
return this; }
220 os << this->ArgStr <<
'=';
221 printValue(os, this->getParser(), this->getValue());
225 void copyValueFrom(
const OptionBase &other)
final {
228 optHasValue = other.optHasValue;
237 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
239 :
public llvm::cl::list<DataType, bool, OptionParser>,
242 template <
typename... Args>
243 ListOption(PassOptions &parent, StringRef arg, Args &&...args)
245 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...),
247 assert(!this->isPositional() &&
"positional options are not supported");
248 assert(!(this->getMiscFlags() & llvm::cl::MiscFlags::CommaSeparated) &&
249 "ListOption is implicitly comma separated, specifying "
250 "CommaSeparated is extraneous");
253 if (!this->isDefaultAssigned())
254 this->setInitialValues({});
256 parent.options.push_back(
this);
263 this->optHasValue = other.optHasValue;
268 StringRef arg)
override {
269 if (this->isDefaultAssigned()) {
271 this->overwriteDefault();
273 this->optHasValue =
true;
276 [&](
const DataType &value) { this->addValue(value); }));
281 ((std::vector<DataType> &)*
this).assign(values.begin(), values.end());
288 return static_cast<std::vector<DataType> &
>(*this);
291 return static_cast<const std::vector<DataType> &
>(*this);
296 const llvm::cl::Option *getOption() const final {
return this; }
304 if (this->isDefaultAssigned() &&
305 this->getDefault().size() == (**this).size()) {
307 for (
unsigned e = (**this).size(); i < e; i++) {
308 if (!this->getDefault()[i].compare((**
this)[i]))
311 if (i == (**this).size())
315 os << this->ArgStr <<
"={";
316 auto printElementFn = [&](
const DataType &value) {
317 printValue(os, this->getParser(), value);
319 llvm::interleave(*
this, os, printElementFn,
",");
324 void copyValueFrom(
const OptionBase &other)
final {
332 PassOptions() =
default;
334 PassOptions(
const PassOptions &) =
delete;
335 PassOptions(PassOptions &&) =
delete;
339 void copyOptionValuesFrom(
const PassOptions &other);
344 LogicalResult parseFromString(StringRef
options,
345 raw_ostream &errorStream = llvm::errs());
349 void print(raw_ostream &os)
const;
353 void printHelp(
size_t indent,
size_t descIndent)
const;
356 size_t getOptionWidth()
const;
360 std::vector<OptionBase *>
options;
382 static std::unique_ptr<T> createFromString(StringRef
options) {
383 auto result = std::make_unique<T>();
392struct EmptyPipelineOptions :
public PassPipelineOptions<EmptyPipelineOptions> {
407template <
typename VectorT,
typename ElementT>
408class VectorParserBase :
public basic_parser_impl {
410 VectorParserBase(Option &opt) : basic_parser_impl(opt), elementParser(opt) {}
412 using parser_data_type = VectorT;
414 bool parse(Option &opt, StringRef argName, StringRef arg,
415 parser_data_type &vector) {
416 if (!arg.consume_front(
"[") || !arg.consume_back(
"]")) {
417 return opt.error(
"expected vector option to be wrapped with '[]'",
422 opt, argName, arg, elementParser,
423 [&](
const ElementT &value) { vector.push_back(value); }));
426 static void print(raw_ostream &os,
const VectorT &vector) {
429 [&](
const ElementT &value) {
431 llvm::cl::parser<ElementT>>(os, value);
436 void printOptionInfo(
const Option &opt,
size_t globalWidth)
const {
438 outs() <<
" --" << opt.ArgStr;
439 outs() <<
"=<vector<" << elementParser.getValueName() <<
">>";
440 Option::printHelpStr(opt.HelpStr, globalWidth, getOptionWidth(opt));
443 size_t getOptionWidth(
const Option &opt)
const {
445 StringRef vectorExt(
"vector<>");
446 return elementParser.getOptionWidth(opt) + vectorExt.size();
456 :
public detail::VectorParserBase<std::vector<T>, T> {
460template <
typename T,
unsigned N>
462 :
public detail::VectorParserBase<SmallVector<T, N>, T> {
486 assert(
hasValue() &&
"invalid option value");
499 if (!rhsOV.hasValue())
501 return compare(rhsOV.getValue());
505 void anchor()
override;
509 std::unique_ptr<mlir::OpPassManager> value;
528 assert(
value &&
"parsed value was invalid");
532 std::unique_ptr<mlir::OpPassManager>
value;
535 using OptVal = OptionValue<mlir::OpPassManager>;
548 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
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 &&)