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"
28 namespace pass_options {
36 template <
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>());
59 template <
typename ParserT>
61 os << (value ? StringRef(
"true") : StringRef(
"false"));
63 template <
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;
77 template <
typename ParserT,
typename DataT>
95 virtual ~OptionBase() =
default;
98 virtual void anchor();
101 virtual void print(raw_ostream &os) = 0;
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) {
169 detail::pass_options::printOptionValue<ParserT>(os, 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>
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; }
220 void print(raw_ostream &os)
final {
221 os << this->ArgStr <<
'=';
222 printValue(os, this->getParser(), this->getValue());
226 void copyValueFrom(
const OptionBase &other)
final {
227 this->setValue(
static_cast<const Option<DataType, OptionParser> &
>(other)
229 optHasValue = other.optHasValue;
238 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
240 :
public llvm::cl::list<DataType, bool, OptionParser>,
243 template <
typename... Args>
246 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...),
247 elementParser(*this) {
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);
259 elementParser.initialize();
265 this->optHasValue = other.optHasValue;
270 StringRef arg)
override {
271 if (this->isDefaultAssigned()) {
273 this->overwriteDefault();
275 this->optHasValue =
true;
277 *
this, argName, arg, elementParser,
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; }
304 void print(raw_ostream &os)
final {
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 {
327 *
this =
static_cast<const ListOption<DataType, OptionParser> &
>(other);
347 raw_ostream &errorStream = llvm::errs());
351 void print(raw_ostream &os)
const;
355 void printHelp(
size_t indent,
size_t descIndent)
const;
362 std::vector<OptionBase *> options;
379 template <
typename T>
385 auto result = std::make_unique<T>();
386 if (failed(result->parseFromString(options)))
409 template <
typename VectorT,
typename ElementT>
416 bool parse(Option &opt, StringRef argName, StringRef arg,
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) {
440 outs() <<
" --" << opt.ArgStr;
441 outs() <<
"=<vector<" << elementParser.getValueName() <<
">>";
442 Option::printHelpStr(opt.HelpStr, globalWidth,
getOptionWidth(opt));
447 StringRef vectorExt(
"vector<>");
448 return elementParser.getOptionWidth(opt) + vectorExt.size();
456 template <
typename T>
460 parser(Option &opt) : detail::VectorParserBase<std::vector<T>, T>(opt) {}
462 template <
typename T,
unsigned N>
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;
525 struct ParsedPassManager {
530 assert(value &&
"parsed value was invalid");
534 std::unique_ptr<mlir::OpPassManager>
value;
541 bool parse(Option &, StringRef, StringRef arg, ParsedPassManager &value);
550 const OptVal &defaultValue,
size_t globalWidth)
const;
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
size_t getOptionWidth(const Option &opt) const
VectorParserBase(Option &opt)
bool parse(Option &opt, StringRef argName, StringRef arg, parser_data_type &vector)
void printOptionInfo(const Option &opt, size_t globalWidth) const
static void print(raw_ostream &os, const VectorT &vector)
static void print(raw_ostream &os, const mlir::OpPassManager &value)
Print an instance of the underling option value to the given stream.
StringRef getValueName() const override
void printOptionDiff(const Option &opt, mlir::OpPassManager &pm, const OptVal &defaultValue, size_t globalWidth) const
bool parse(Option &, StringRef, StringRef arg, ParsedPassManager &value)
ParsedPassManager parser_data_type
This class represents a pass manager that runs passes on either a specific operation type,...
Subclasses of PassPipelineOptions provide a set of options that can be used to initialize a pass pipe...
static std::unique_ptr< T > createFromString(StringRef options)
Factory that parses the provided options and returns a unique_ptr to the struct.
This class represents a specific pass option that contains a list of values of the provided data type...
ListOption< DataType, OptionParser > & operator=(ArrayRef< DataType > values)
Allow assigning from an ArrayRef.
ListOption(PassOptions &parent, StringRef arg, Args &&...args)
ListOption< DataType, OptionParser > & operator=(const ListOption< DataType, OptionParser > &other)
MutableArrayRef< DataType > operator*()
Allow accessing the data held by this option.
ArrayRef< DataType > operator*() const
bool handleOccurrence(unsigned pos, StringRef argName, StringRef arg) override
~ListOption() override=default
This class represents a specific pass option, with a provided data type.
Option & operator=(const Option &other)
~Option() override=default
Option(PassOptions &parent, StringRef arg, Args &&...args)
Base container class and manager for all pass options.
size_t getOptionWidth() const
Return the maximum width required when printing the help string.
void printHelp(size_t indent, size_t descIndent) const
Print the help string for the options held by this struct.
PassOptions(PassOptions &&)=delete
LogicalResult parseFromString(StringRef options, raw_ostream &errorStream=llvm::errs())
Parse options out as key=value pairs that can then be handed off to the llvm::cl command line passing...
void print(raw_ostream &os) const
Print the options held by this struct in a form that can be parsed via 'parseFromString'.
void copyOptionValuesFrom(const PassOptions &other)
Copy the option values from 'other' into 'this', where 'other' has the same options as 'this'.
PassOptions(const PassOptions &)=delete
Delete the copy constructor to avoid copying the internal options map.
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.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
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.
llvm::is_detected< has_stream_operator_trait, T > has_stream_operator
int compare(const Fraction &x, const Fraction &y)
Three-way comparison between two fractions.
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
mlir::OpPassManager & getValue() const
Returns the current value of the option.
void setValue(const mlir::OpPassManager &newValue)
Set the value of the option.
OptionValue(const OptionValue< mlir::OpPassManager > &rhs)
bool compare(const mlir::OpPassManager &rhs) const
Compare the option with the provided value.
bool compare(const GenericOptionValue &rhs) const override
OptionValue< mlir::OpPassManager > & operator=(const mlir::OpPassManager &rhs)
OptionValue(const mlir::OpPassManager &value)
void setValue(StringRef pipelineStr)
bool hasValue() const
Returns if the current option has a value.
ParsedPassManager(ParsedPassManager &&)
std::unique_ptr< mlir::OpPassManager > value
A default empty option struct to be used for passes that do not need to take any options.