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>
78 static std::enable_if_t<has_stream_operator<DataT>::value>
82 template <
typename ParserT,
typename DataT>
83 static std::enable_if_t<!has_stream_operator<DataT>::value>
98 virtual ~OptionBase() =
default;
101 virtual void anchor();
104 virtual void print(raw_ostream &os) = 0;
107 StringRef getArgStr()
const {
return getOption()->ArgStr; }
110 bool hasValue()
const {
return optHasValue; }
114 virtual const llvm::cl::Option *getOption()
const = 0;
117 virtual void copyValueFrom(
const OptionBase &other) = 0;
120 bool optHasValue =
false;
129 template <
typename DataType>
134 std::optional<StringRef> findArgStrForValue(
const DataType &value) {
135 for (
auto &it : this->Values)
136 if (it.V.compare(value))
145 template <
typename PassOptionsT>
150 bool parse(llvm::cl::Option &, StringRef, StringRef arg,
151 PassOptionsT &value) {
152 return failed(value.parseFromString(arg));
156 static void print(llvm::raw_ostream &os,
const PassOptionsT &value) {
162 template <
typename DataT>
163 static void printValue(raw_ostream &os, GenericOptionParser<DataT> &parser,
164 const DataT &value) {
165 if (std::optional<StringRef> argStr = parser.findArgStrForValue(value))
168 llvm_unreachable(
"unknown data value for option");
170 template <
typename DataT,
typename ParserT>
171 static void printValue(raw_ostream &os, ParserT &parser,
const DataT &value) {
172 detail::pass_options::printOptionValue<ParserT>(os, value);
178 template <
typename DataType>
182 std::is_base_of_v<PassOptions, DataType>, PassOptionsParser<DataType>,
187 std::conditional_t<std::is_base_of<llvm::cl::generic_parser_base,
189 GenericOptionParser<DataType>,
194 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
196 :
public llvm::cl::opt<DataType, false, OptionParser>,
199 template <
typename... Args>
202 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...) {
203 assert(!this->isPositional() && !this->isSink() &&
204 "sink and positional options are not supported");
205 parent.options.push_back(
this);
208 this->setCallback([
this](
const auto &) { this->optHasValue =
true; });
211 using llvm::cl::opt<DataType,
false,
214 *
this = other.getValue();
220 const llvm::cl::Option *getOption() const final {
return this; }
223 void print(raw_ostream &os)
final {
224 os << this->ArgStr <<
'=';
225 printValue(os, this->getParser(), this->getValue());
229 void copyValueFrom(
const OptionBase &other)
final {
230 this->setValue(
static_cast<const Option<DataType, OptionParser> &
>(other)
232 optHasValue = other.optHasValue;
241 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
243 :
public llvm::cl::list<DataType, bool, OptionParser>,
246 template <
typename... Args>
249 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...),
250 elementParser(*this) {
251 assert(!this->isPositional() && !this->isSink() &&
252 "sink and positional options are not supported");
253 assert(!(this->getMiscFlags() & llvm::cl::MiscFlags::CommaSeparated) &&
254 "ListOption is implicitly comma separated, specifying "
255 "CommaSeparated is extraneous");
256 parent.options.push_back(
this);
257 elementParser.initialize();
263 this->optHasValue = other.optHasValue;
268 StringRef arg)
override {
269 if (this->isDefaultAssigned()) {
271 this->overwriteDefault();
273 this->optHasValue =
true;
275 *
this, argName, arg, elementParser,
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; }
299 void print(raw_ostream &os)
final {
302 if ((**this).empty())
305 os << this->ArgStr <<
"={";
306 auto printElementFn = [&](
const DataType &value) {
307 printValue(os, this->getParser(), value);
309 llvm::interleave(*
this, os, printElementFn,
",");
314 void copyValueFrom(
const OptionBase &other)
final {
315 *
this =
static_cast<const ListOption<DataType, OptionParser> &
>(other);
335 raw_ostream &errorStream = llvm::errs());
339 void print(raw_ostream &os)
const;
343 void printHelp(
size_t indent,
size_t descIndent)
const;
350 std::vector<OptionBase *> options;
367 template <
typename T>
373 auto result = std::make_unique<T>();
374 if (failed(result->parseFromString(options)))
396 template <
typename VectorT,
typename ElementT>
403 bool parse(Option &opt, StringRef argName, StringRef arg,
405 if (!arg.consume_front(
"[") || !arg.consume_back(
"]")) {
406 return opt.error(
"expected vector option to be wrapped with '[]'",
411 opt, argName, arg, elementParser,
412 [&](
const ElementT &value) { vector.push_back(value); }));
415 static void print(raw_ostream &os,
const VectorT &vector) {
418 [&](
const ElementT &value) {
427 outs() <<
" --" << opt.ArgStr;
428 outs() <<
"=<vector<" << elementParser.getValueName() <<
">>";
429 Option::printHelpStr(opt.HelpStr, globalWidth,
getOptionWidth(opt));
434 StringRef vectorExt(
"vector<>");
435 return elementParser.getOptionWidth(opt) + vectorExt.size();
443 template <
typename T>
447 parser(Option &opt) : detail::VectorParserBase<std::vector<T>, T>(opt) {}
449 template <
typename T,
unsigned N>
474 assert(hasValue() &&
"invalid option value");
487 if (!rhsOV.hasValue())
489 return compare(rhsOV.getValue());
493 void anchor()
override;
497 std::unique_ptr<mlir::OpPassManager> value;
510 struct ParsedPassManager {
515 assert(value &&
"parsed value was invalid");
519 std::unique_ptr<mlir::OpPassManager>
value;
526 bool parse(Option &, StringRef, StringRef arg, ParsedPassManager &value);
535 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.