MLIR  21.0.0git
PassOptions.h
Go to the documentation of this file.
1 //===- PassOptions.h - Pass Option Utilities --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains utilities for registering options with compiler passes and
10 // pipelines.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_PASS_PASSOPTIONS_H_
15 #define MLIR_PASS_PASSOPTIONS_H_
16 
17 #include "mlir/Support/LLVM.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"
22 #include <memory>
23 
24 namespace mlir {
25 class OpPassManager;
26 
27 namespace detail {
28 namespace pass_options {
29 /// Parse a string containing a list of comma-delimited elements, invoking the
30 /// given parser for each sub-element and passing them to the provided
31 /// element-append functor.
32 LogicalResult
33 parseCommaSeparatedList(llvm::cl::Option &opt, StringRef argName,
34  StringRef optionStr,
35  function_ref<LogicalResult(StringRef)> elementParseFn);
36 template <typename ElementParser, typename ElementAppendFn>
37 LogicalResult parseCommaSeparatedList(llvm::cl::Option &opt, StringRef argName,
38  StringRef optionStr,
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))
45  return failure();
46  appendFn(value);
47  return success();
48  });
49 }
50 
51 /// Trait used to detect if a type has a operator<< method.
52 template <typename T>
54  decltype(std::declval<raw_ostream &>() << std::declval<T>());
55 template <typename T>
56 using has_stream_operator = llvm::is_detected<has_stream_operator_trait, T>;
57 
58 /// Utility methods for printing option values.
59 template <typename ParserT>
60 static void printOptionValue(raw_ostream &os, const bool &value) {
61  os << (value ? StringRef("true") : StringRef("false"));
62 }
63 template <typename ParserT>
64 static void printOptionValue(raw_ostream &os, const std::string &str) {
65  // Check if the string needs to be escaped before writing it to the ostream.
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;
71  if (requiresEscape)
72  os << "{";
73  os << str;
74  if (requiresEscape)
75  os << "}";
76 }
77 template <typename ParserT, typename DataT>
78 static void printOptionValue(raw_ostream &os, const DataT &value) {
80  os << value;
81  else
82  // If the value can't be streamed, fallback to checking for a print in the
83  // parser.
84  ParserT::print(os, value);
85 }
86 } // namespace pass_options
87 
88 /// Base container class and manager for all pass options.
89 class PassOptions : protected llvm::cl::SubCommand {
90 private:
91  /// This is the type-erased option base class. This provides some additional
92  /// hooks into the options that are not available via llvm::cl::Option.
93  class OptionBase {
94  public:
95  virtual ~OptionBase() = default;
96 
97  /// Out of line virtual function to provide home for the class.
98  virtual void anchor();
99 
100  /// Print the name and value of this option to the given stream.
101  virtual void print(raw_ostream &os) = 0;
102 
103  /// Return the argument string of this option.
104  StringRef getArgStr() const { return getOption()->ArgStr; }
105 
106  /// Returns true if this option has any value assigned to it.
107  bool hasValue() const { return optHasValue; }
108 
109  protected:
110  /// Return the main option instance.
111  virtual const llvm::cl::Option *getOption() const = 0;
112 
113  /// Copy the value from the given option into this one.
114  virtual void copyValueFrom(const OptionBase &other) = 0;
115 
116  /// Flag indicating if this option has a value.
117  bool optHasValue = false;
118 
119  /// Allow access to private methods.
120  friend PassOptions;
121  };
122 
123  /// This is the parser that is used by pass options that use literal options.
124  /// This is a thin wrapper around the llvm::cl::parser, that exposes some
125  /// additional methods.
126  template <typename DataType>
127  struct GenericOptionParser : public llvm::cl::parser<DataType> {
129 
130  /// Returns an argument name that maps to the specified value.
131  std::optional<StringRef> findArgStrForValue(const DataType &value) {
132  for (auto &it : this->Values)
133  if (it.V.compare(value))
134  return it.Name;
135  return std::nullopt;
136  }
137  };
138 
139  /// This is the parser that is used by pass options that wrap PassOptions
140  /// instances. Like GenericOptionParser, this is a thin wrapper around
141  /// llvm::cl::basic_parser.
142  template <typename PassOptionsT>
143  struct PassOptionsParser : public llvm::cl::basic_parser<PassOptionsT> {
145  // Parse the options object by delegating to
146  // `PassOptionsT::parseFromString`.
147  bool parse(llvm::cl::Option &, StringRef, StringRef arg,
148  PassOptionsT &value) {
149  return failed(value.parseFromString(arg));
150  }
151 
152  // Print the options object by delegating to `PassOptionsT::print`.
153  static void print(llvm::raw_ostream &os, const PassOptionsT &value) {
154  value.print(os);
155  }
156  };
157 
158  /// Utility methods for printing option values.
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))
163  os << *argStr;
164  else
165  llvm_unreachable("unknown data value for option");
166  }
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);
170  }
171 
172 public:
173  /// The specific parser to use. This is necessary because we need to provide
174  /// additional methods for certain data type parsers.
175  template <typename DataType>
176  using OptionParser = std::conditional_t<
177  // If the data type is derived from PassOptions, use the
178  // PassOptionsParser.
179  std::is_base_of_v<PassOptions, DataType>, PassOptionsParser<DataType>,
180  // Otherwise, use GenericOptionParser where it is well formed, and fall
181  // back to llvm::cl::parser otherwise.
182  // TODO: We should upstream the methods in GenericOptionParser to avoid
183  // the need to do this.
184  std::conditional_t<std::is_base_of<llvm::cl::generic_parser_base,
186  GenericOptionParser<DataType>,
188 
189  /// This class represents a specific pass option, with a provided
190  /// data type.
191  template <typename DataType, typename OptionParser = OptionParser<DataType>>
192  class Option
193  : public llvm::cl::opt<DataType, /*ExternalStorage=*/false, OptionParser>,
194  public OptionBase {
195  public:
196  template <typename... Args>
197  Option(PassOptions &parent, StringRef arg, Args &&...args)
198  : llvm::cl::opt<DataType, /*ExternalStorage=*/false, OptionParser>(
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);
203 
204  // Set a callback to track if this option has a value.
205  this->setCallback([this](const auto &) { this->optHasValue = true; });
206  }
207  ~Option() override = default;
208  using llvm::cl::opt<DataType, /*ExternalStorage=*/false,
209  OptionParser>::operator=;
210  Option &operator=(const Option &other) {
211  *this = other.getValue();
212  return *this;
213  }
214 
215  private:
216  /// Return the main option instance.
217  const llvm::cl::Option *getOption() const final { return this; }
218 
219  /// Print the name and value of this option to the given stream.
220  void print(raw_ostream &os) final {
221  os << this->ArgStr << '=';
222  printValue(os, this->getParser(), this->getValue());
223  }
224 
225  /// Copy the value from the given option into this one.
226  void copyValueFrom(const OptionBase &other) final {
227  this->setValue(static_cast<const Option<DataType, OptionParser> &>(other)
228  .getValue());
229  optHasValue = other.optHasValue;
230  }
231  };
232 
233  /// This class represents a specific pass option that contains a list of
234  /// values of the provided data type. The elements within the textual form of
235  /// this option are parsed assuming they are comma-separated. Delimited
236  /// sub-ranges within individual elements of the list may contain commas that
237  /// are not treated as separators for the top-level list.
238  template <typename DataType, typename OptionParser = OptionParser<DataType>>
240  : public llvm::cl::list<DataType, /*StorageClass=*/bool, OptionParser>,
241  public OptionBase {
242  public:
243  template <typename... Args>
244  ListOption(PassOptions &parent, StringRef arg, Args &&...args)
245  : llvm::cl::list<DataType, /*StorageClass=*/bool, OptionParser>(
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");
253 
254  // Make the default explicitly "empty" if no default was given.
255  if (!this->isDefaultAssigned())
256  this->setInitialValues({});
257 
258  parent.options.push_back(this);
259  elementParser.initialize();
260  }
261  ~ListOption() override = default;
264  *this = ArrayRef<DataType>(other);
265  this->optHasValue = other.optHasValue;
266  return *this;
267  }
268 
269  bool handleOccurrence(unsigned pos, StringRef argName,
270  StringRef arg) override {
271  if (this->isDefaultAssigned()) {
272  this->clear();
273  this->overwriteDefault();
274  }
275  this->optHasValue = true;
277  *this, argName, arg, elementParser,
278  [&](const DataType &value) { this->addValue(value); }));
279  }
280 
281  /// Allow assigning from an ArrayRef.
283  ((std::vector<DataType> &)*this).assign(values.begin(), values.end());
284  optHasValue = true;
285  return *this;
286  }
287 
288  /// Allow accessing the data held by this option.
290  return static_cast<std::vector<DataType> &>(*this);
291  }
293  return static_cast<const std::vector<DataType> &>(*this);
294  }
295 
296  private:
297  /// Return the main option instance.
298  const llvm::cl::Option *getOption() const final { return this; }
299 
300  /// Print the name and value of this option to the given stream.
301  /// Note that there is currently a limitation with regards to
302  /// `ListOption<string>`: parsing 'option=""` will result in `option` being
303  /// set to the empty list, not to a size-1 list containing an empty string.
304  void print(raw_ostream &os) final {
305  // Don't print the list if the value is the default value.
306  if (this->isDefaultAssigned() &&
307  this->getDefault().size() == (**this).size()) {
308  unsigned i = 0;
309  for (unsigned e = (**this).size(); i < e; i++) {
310  if (!this->getDefault()[i].compare((**this)[i]))
311  break;
312  }
313  if (i == (**this).size())
314  return;
315  }
316 
317  os << this->ArgStr << "={";
318  auto printElementFn = [&](const DataType &value) {
319  printValue(os, this->getParser(), value);
320  };
321  llvm::interleave(*this, os, printElementFn, ",");
322  os << "}";
323  }
324 
325  /// Copy the value from the given option into this one.
326  void copyValueFrom(const OptionBase &other) final {
327  *this = static_cast<const ListOption<DataType, OptionParser> &>(other);
328  }
329 
330  /// The parser to use for parsing the list elements.
331  OptionParser elementParser;
332  };
333 
334  PassOptions() = default;
335  /// Delete the copy constructor to avoid copying the internal options map.
336  PassOptions(const PassOptions &) = delete;
337  PassOptions(PassOptions &&) = delete;
338 
339  /// Copy the option values from 'other' into 'this', where 'other' has the
340  /// same options as 'this'.
341  void copyOptionValuesFrom(const PassOptions &other);
342 
343  /// Parse options out as key=value pairs that can then be handed off to the
344  /// `llvm::cl` command line passing infrastructure. Everything is space
345  /// separated.
346  LogicalResult parseFromString(StringRef options,
347  raw_ostream &errorStream = llvm::errs());
348 
349  /// Print the options held by this struct in a form that can be parsed via
350  /// 'parseFromString'.
351  void print(raw_ostream &os) const;
352 
353  /// Print the help string for the options held by this struct. `descIndent` is
354  /// the indent that the descriptions should be aligned.
355  void printHelp(size_t indent, size_t descIndent) const;
356 
357  /// Return the maximum width required when printing the help string.
358  size_t getOptionWidth() const;
359 
360 private:
361  /// A list of all of the opaque options.
362  std::vector<OptionBase *> options;
363 };
364 } // namespace detail
365 
366 //===----------------------------------------------------------------------===//
367 // PassPipelineOptions
368 //===----------------------------------------------------------------------===//
369 
370 /// Subclasses of PassPipelineOptions provide a set of options that can be used
371 /// to initialize a pass pipeline. See PassPipelineRegistration for usage
372 /// details.
373 ///
374 /// Usage:
375 ///
376 /// struct MyPipelineOptions : PassPipelineOptions<MyPassOptions> {
377 /// ListOption<int> someListFlag{*this, "flag-name", llvm::cl::desc("...")};
378 /// };
379 template <typename T>
381 public:
382  /// Factory that parses the provided options and returns a unique_ptr to the
383  /// struct.
384  static std::unique_ptr<T> createFromString(StringRef options) {
385  auto result = std::make_unique<T>();
386  if (failed(result->parseFromString(options)))
387  return nullptr;
388  return result;
389  }
390 };
391 
392 /// A default empty option struct to be used for passes that do not need to take
393 /// any options.
394 struct EmptyPipelineOptions : public PassPipelineOptions<EmptyPipelineOptions> {
395 };
396 } // namespace mlir
397 
398 //===----------------------------------------------------------------------===//
399 // MLIR Options
400 //===----------------------------------------------------------------------===//
401 
402 namespace llvm {
403 namespace cl {
404 //===----------------------------------------------------------------------===//
405 // std::vector+SmallVector
406 //===----------------------------------------------------------------------===//
407 
408 namespace detail {
409 template <typename VectorT, typename ElementT>
410 class VectorParserBase : public basic_parser_impl {
411 public:
412  VectorParserBase(Option &opt) : basic_parser_impl(opt), elementParser(opt) {}
413 
414  using parser_data_type = VectorT;
415 
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 '[]'",
420  argName);
421  }
422 
424  opt, argName, arg, elementParser,
425  [&](const ElementT &value) { vector.push_back(value); }));
426  }
427 
428  static void print(raw_ostream &os, const VectorT &vector) {
429  llvm::interleave(
430  vector, os,
431  [&](const ElementT &value) {
433  llvm::cl::parser<ElementT>>(os, value);
434  },
435  ",");
436  }
437 
438  void printOptionInfo(const Option &opt, size_t globalWidth) const {
439  // Add the `vector<>` qualifier to the option info.
440  outs() << " --" << opt.ArgStr;
441  outs() << "=<vector<" << elementParser.getValueName() << ">>";
442  Option::printHelpStr(opt.HelpStr, globalWidth, getOptionWidth(opt));
443  }
444 
445  size_t getOptionWidth(const Option &opt) const {
446  // Add the `vector<>` qualifier to the option width.
447  StringRef vectorExt("vector<>");
448  return elementParser.getOptionWidth(opt) + vectorExt.size();
449  }
450 
451 private:
452  llvm::cl::parser<ElementT> elementParser;
453 };
454 } // namespace detail
455 
456 template <typename T>
457 class parser<std::vector<T>>
458  : public detail::VectorParserBase<std::vector<T>, T> {
459 public:
460  parser(Option &opt) : detail::VectorParserBase<std::vector<T>, T>(opt) {}
461 };
462 template <typename T, unsigned N>
463 class parser<SmallVector<T, N>>
464  : public detail::VectorParserBase<SmallVector<T, N>, T> {
465 public:
466  parser(Option &opt) : detail::VectorParserBase<SmallVector<T, N>, T>(opt) {}
467 };
468 
469 //===----------------------------------------------------------------------===//
470 // OpPassManager: OptionValue
471 //===----------------------------------------------------------------------===//
472 
473 template <>
474 struct OptionValue<mlir::OpPassManager> final : GenericOptionValue {
476 
482 
483  /// Returns if the current option has a value.
484  bool hasValue() const { return value.get(); }
485 
486  /// Returns the current value of the option.
488  assert(hasValue() && "invalid option value");
489  return *value;
490  }
491 
492  /// Set the value of the option.
493  void setValue(const mlir::OpPassManager &newValue);
494  void setValue(StringRef pipelineStr);
495 
496  /// Compare the option with the provided value.
497  bool compare(const mlir::OpPassManager &rhs) const;
498  bool compare(const GenericOptionValue &rhs) const override {
499  const auto &rhsOV =
500  static_cast<const OptionValue<mlir::OpPassManager> &>(rhs);
501  if (!rhsOV.hasValue())
502  return false;
503  return compare(rhsOV.getValue());
504  }
505 
506 private:
507  void anchor() override;
508 
509  /// The underlying pass manager. We use a unique_ptr to avoid the need for the
510  /// full type definition.
511  std::unique_ptr<mlir::OpPassManager> value;
512 };
513 
514 //===----------------------------------------------------------------------===//
515 // OpPassManager: Parser
516 //===----------------------------------------------------------------------===//
517 
518 extern template class basic_parser<mlir::OpPassManager>;
519 
520 template <>
522 public:
523  /// A utility struct used when parsing a pass manager that prevents the need
524  /// for a default constructor on OpPassManager.
525  struct ParsedPassManager {
527  ParsedPassManager(ParsedPassManager &&);
529  operator const mlir::OpPassManager &() const {
530  assert(value && "parsed value was invalid");
531  return *value;
532  }
533 
534  std::unique_ptr<mlir::OpPassManager> value;
535  };
536  using parser_data_type = ParsedPassManager;
538 
539  parser(Option &opt) : basic_parser(opt) {}
540 
541  bool parse(Option &, StringRef, StringRef arg, ParsedPassManager &value);
542 
543  /// Print an instance of the underling option value to the given stream.
544  static void print(raw_ostream &os, const mlir::OpPassManager &value);
545 
546  // Overload in subclass to provide a better default value.
547  StringRef getValueName() const override { return "pass-manager"; }
548 
549  void printOptionDiff(const Option &opt, mlir::OpPassManager &pm,
550  const OptVal &defaultValue, size_t globalWidth) const;
551 
552  // An out-of-line virtual method to provide a 'home' for this class.
553  void anchor() override;
554 };
555 
556 } // namespace cl
557 } // namespace llvm
558 
559 #endif // MLIR_PASS_PASSOPTIONS_H_
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
size_t getOptionWidth(const Option &opt) const
Definition: PassOptions.h:445
bool parse(Option &opt, StringRef argName, StringRef arg, parser_data_type &vector)
Definition: PassOptions.h:416
void printOptionInfo(const Option &opt, size_t globalWidth) const
Definition: PassOptions.h:438
static void print(raw_ostream &os, const VectorT &vector)
Definition: PassOptions.h:428
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
Definition: PassOptions.h:547
void printOptionDiff(const Option &opt, mlir::OpPassManager &pm, const OptVal &defaultValue, size_t globalWidth) const
bool parse(Option &, StringRef, StringRef arg, ParsedPassManager &value)
This class represents a pass manager that runs passes on either a specific operation type,...
Definition: PassManager.h:46
Subclasses of PassPipelineOptions provide a set of options that can be used to initialize a pass pipe...
Definition: PassOptions.h:380
static std::unique_ptr< T > createFromString(StringRef options)
Factory that parses the provided options and returns a unique_ptr to the struct.
Definition: PassOptions.h:384
This class represents a specific pass option that contains a list of values of the provided data type...
Definition: PassOptions.h:241
ListOption< DataType, OptionParser > & operator=(ArrayRef< DataType > values)
Allow assigning from an ArrayRef.
Definition: PassOptions.h:282
ListOption(PassOptions &parent, StringRef arg, Args &&...args)
Definition: PassOptions.h:244
ListOption< DataType, OptionParser > & operator=(const ListOption< DataType, OptionParser > &other)
Definition: PassOptions.h:263
MutableArrayRef< DataType > operator*()
Allow accessing the data held by this option.
Definition: PassOptions.h:289
ArrayRef< DataType > operator*() const
Definition: PassOptions.h:292
bool handleOccurrence(unsigned pos, StringRef argName, StringRef arg) override
Definition: PassOptions.h:269
This class represents a specific pass option, with a provided data type.
Definition: PassOptions.h:194
Option & operator=(const Option &other)
Definition: PassOptions.h:210
Option(PassOptions &parent, StringRef arg, Args &&...args)
Definition: PassOptions.h:197
Base container class and manager for all pass options.
Definition: PassOptions.h:89
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.
Definition: PassOptions.h:187
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
static void printOptionValue(raw_ostream &os, const bool &value)
Utility methods for printing option values.
Definition: PassOptions.h:60
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.
Definition: PassOptions.h:54
llvm::is_detected< has_stream_operator_trait, T > has_stream_operator
Definition: PassOptions.h:56
int compare(const Fraction &x, const Fraction &y)
Three-way comparison between two fractions.
Definition: Fraction.h:68
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Definition: Query.cpp:20
Include the generated interface declarations.
mlir::OpPassManager & getValue() const
Returns the current value of the option.
Definition: PassOptions.h:487
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
Definition: PassOptions.h:498
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.
Definition: PassOptions.h:484
std::unique_ptr< mlir::OpPassManager > value
Definition: PassOptions.h:534
A default empty option struct to be used for passes that do not need to take any options.
Definition: PassOptions.h:394