14 #ifndef MLIR_PASS_PASSOPTIONS_H_
15 #define MLIR_PASS_PASSOPTIONS_H_
19 #include "llvm/ADT/FunctionExtras.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/Compiler.h"
29 namespace pass_options {
37 template <
typename ElementParser,
typename ElementAppendFn>
40 ElementParser &elementParser,
41 ElementAppendFn &&appendFn) {
43 opt, argName, optionStr, [&](StringRef valueStr) {
44 typename ElementParser::parser_data_type value = {};
45 if (elementParser.parse(opt, argName, valueStr, value))
55 decltype(std::declval<raw_ostream &>() << std::declval<T>());
60 template <
typename ParserT>
62 os << (value ? StringRef(
"true") : StringRef(
"false"));
64 template <
typename ParserT,
typename DataT>
65 static std::enable_if_t<has_stream_operator<DataT>::value>
69 template <
typename ParserT,
typename DataT>
70 static std::enable_if_t<!has_stream_operator<DataT>::value>
85 virtual ~OptionBase() =
default;
88 virtual void anchor();
91 virtual void print(raw_ostream &os) = 0;
94 StringRef getArgStr()
const {
return getOption()->ArgStr; }
97 bool hasValue()
const {
return optHasValue; }
101 virtual const llvm::cl::Option *getOption()
const = 0;
104 virtual void copyValueFrom(
const OptionBase &other) = 0;
107 bool optHasValue =
false;
116 template <
typename DataType>
121 std::optional<StringRef> findArgStrForValue(
const DataType &value) {
122 for (
auto &it : this->Values)
123 if (it.V.compare(value))
130 template <
typename DataT>
131 static void printValue(raw_ostream &os, GenericOptionParser<DataT> &parser,
132 const DataT &value) {
133 if (std::optional<StringRef> argStr = parser.findArgStrForValue(value))
136 llvm_unreachable(
"unknown data value for option");
138 template <
typename DataT,
typename ParserT>
139 static void printValue(raw_ostream &os, ParserT &parser,
const DataT &value) {
140 detail::pass_options::printOptionValue<ParserT>(os, value);
149 template <
typename DataType>
151 std::conditional_t<std::is_base_of<llvm::cl::generic_parser_base,
153 GenericOptionParser<DataType>,
157 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
159 :
public llvm::cl::opt<DataType, false, OptionParser>,
162 template <
typename... Args>
165 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...) {
166 assert(!this->isPositional() && !this->isSink() &&
167 "sink and positional options are not supported");
168 parent.options.push_back(
this);
171 this->setCallback([
this](
const auto &) { this->optHasValue =
true; });
174 using llvm::cl::opt<DataType,
false,
177 *
this = other.getValue();
183 const llvm::cl::Option *getOption() const final {
return this; }
186 void print(raw_ostream &os)
final {
187 os << this->ArgStr <<
'=';
188 printValue(os, this->getParser(), this->getValue());
192 void copyValueFrom(
const OptionBase &other)
final {
193 this->setValue(
static_cast<const Option<DataType, OptionParser> &
>(other)
195 optHasValue = other.optHasValue;
204 template <
typename DataType,
typename OptionParser = OptionParser<DataType>>
206 :
public llvm::cl::list<DataType, bool, OptionParser>,
209 template <
typename... Args>
212 arg,
llvm::cl::sub(parent), std::forward<Args>(args)...),
213 elementParser(*this) {
214 assert(!this->isPositional() && !this->isSink() &&
215 "sink and positional options are not supported");
216 assert(!(this->getMiscFlags() & llvm::cl::MiscFlags::CommaSeparated) &&
217 "ListOption is implicitly comma separated, specifying "
218 "CommaSeparated is extraneous");
219 parent.options.push_back(
this);
220 elementParser.initialize();
226 this->optHasValue = other.optHasValue;
231 StringRef arg)
override {
232 if (this->isDefaultAssigned()) {
234 this->overwriteDefault();
236 this->optHasValue =
true;
238 *
this, argName, arg, elementParser,
239 [&](
const DataType &value) { this->addValue(value); }));
244 ((std::vector<DataType> &)*
this).assign(values.begin(), values.end());
251 return static_cast<std::vector<DataType> &
>(*this);
254 return static_cast<const std::vector<DataType> &
>(*this);
259 const llvm::cl::Option *getOption() const final {
return this; }
262 void print(raw_ostream &os)
final {
265 if ((**this).empty())
268 os << this->ArgStr <<
'=';
269 auto printElementFn = [&](
const DataType &value) {
270 printValue(os, this->getParser(), value);
272 llvm::interleave(*
this, os, printElementFn,
",");
276 void copyValueFrom(
const OptionBase &other)
final {
277 *
this =
static_cast<const ListOption<DataType, OptionParser> &
>(other);
300 void print(raw_ostream &os);
304 void printHelp(
size_t indent,
size_t descIndent)
const;
311 std::vector<OptionBase *> options;
328 template <
typename T>
334 auto result = std::make_unique<T>();
335 if (
failed(result->parseFromString(options)))
357 template <
typename VectorT,
typename ElementT>
364 bool parse(Option &opt, StringRef argName, StringRef arg,
366 if (!arg.consume_front(
"[") || !arg.consume_back(
"]")) {
367 return opt.error(
"expected vector option to be wrapped with '[]'",
372 opt, argName, arg, elementParser,
373 [&](
const ElementT &value) { vector.push_back(value); }));
376 static void print(raw_ostream &os,
const VectorT &vector) {
379 [&](
const ElementT &value) {
388 outs() <<
" --" << opt.ArgStr;
389 outs() <<
"=<vector<" << elementParser.getValueName() <<
">>";
390 Option::printHelpStr(opt.HelpStr, globalWidth,
getOptionWidth(opt));
395 StringRef vectorExt(
"vector<>");
396 return elementParser.getOptionWidth(opt) + vectorExt.size();
404 template <
typename T>
408 parser(Option &opt) : detail::VectorParserBase<std::vector<T>, T>(opt) {}
410 template <
typename T,
unsigned N>
435 assert(hasValue() &&
"invalid option value");
448 if (!rhsOV.hasValue())
450 return compare(rhsOV.getValue());
454 void anchor()
override;
458 std::unique_ptr<mlir::OpPassManager> value;
471 struct ParsedPassManager {
476 assert(value &&
"parsed value was invalid");
480 std::unique_ptr<mlir::OpPassManager>
value;
487 bool parse(Option &, StringRef, StringRef arg, ParsedPassManager &value);
496 const OptVal &defaultValue,
size_t globalWidth)
const;
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.
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 depending on llvm::cl parser used.
PassOptions(PassOptions &&)=delete
LogicalResult parseFromString(StringRef options)
Parse options out as key=value pairs that can then be handed off to the llvm::cl command line passing...
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.
void print(raw_ostream &os)
Print the options held by this struct in a form that can be parsed via 'parseFromString'.
Include the generated interface declarations.
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.
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
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.
This class represents an efficient way to signal success or failure.