Commit 936fc55b authored by Eugene Zhulenev's avatar Eugene Zhulenev Committed by River Riddle
Browse files

[MLIR] Add custom option parser type to PassOption

Summary: Pass custom DataType parser to pass options, similar to llvm::cl::opt class.

Differential Revision: https://reviews.llvm.org/D75794
parent 57a2eaf3
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -66,23 +66,26 @@ public:
  //===--------------------------------------------------------------------===//

  /// This class represents a specific pass option, with a provided data type.
  template <typename DataType>
  struct Option : public detail::PassOptions::Option<DataType> {
  template <typename DataType,
            typename OptionParser = detail::PassOptions::OptionParser<DataType>>
  struct Option : public detail::PassOptions::Option<DataType, OptionParser> {
    template <typename... Args>
    Option(Pass &parent, StringRef arg, Args &&... args)
        : detail::PassOptions::Option<DataType>(parent.passOptions, arg,
                                                std::forward<Args>(args)...) {}
    using detail::PassOptions::Option<DataType>::operator=;
        : detail::PassOptions::Option<DataType, OptionParser>(
              parent.passOptions, arg, std::forward<Args>(args)...) {}
    using detail::PassOptions::Option<DataType, OptionParser>::operator=;
  };
  /// This class represents a specific pass option that contains a list of
  /// values of the provided data type.
  template <typename DataType>
  struct ListOption : public detail::PassOptions::ListOption<DataType> {
  template <typename DataType,
            typename OptionParser = detail::PassOptions::OptionParser<DataType>>
  struct ListOption
      : public detail::PassOptions::ListOption<DataType, OptionParser> {
    template <typename... Args>
    ListOption(Pass &parent, StringRef arg, Args &&... args)
        : detail::PassOptions::ListOption<DataType>(
        : detail::PassOptions::ListOption<DataType, OptionParser>(
              parent.passOptions, arg, std::forward<Args>(args)...) {}
    using detail::PassOptions::ListOption<DataType>::operator=;
    using detail::PassOptions::ListOption<DataType, OptionParser>::operator=;
  };

  /// Attempt to initialize the options of this pass from the given string.
+30 −30
Original line number Diff line number Diff line
@@ -69,18 +69,6 @@ private:
    }
  };

  /// The specific parser to use depending on llvm::cl parser used. This is only
  /// necessary because we need to provide additional methods for certain data
  /// type parsers.
  /// TODO(riverriddle) We should upstream the methods in GenericOptionParser to
  /// avoid the need to do this.
  template <typename DataType>
  using OptionParser =
      std::conditional_t<std::is_base_of<llvm::cl::generic_parser_base,
                                         llvm::cl::parser<DataType>>::value,
                         GenericOptionParser<DataType>,
                         llvm::cl::parser<DataType>>;

  /// Utility methods for printing option values.
  template <typename DataT>
  static void printValue(raw_ostream &os, GenericOptionParser<DataT> &parser,
@@ -100,23 +88,34 @@ private:
  }

public:
  /// This class represents a specific pass option, with a provided data type.
  /// The specific parser to use depending on llvm::cl parser used. This is only
  /// necessary because we need to provide additional methods for certain data
  /// type parsers.
  /// TODO(riverriddle) We should upstream the methods in GenericOptionParser to
  /// avoid the need to do this.
  template <typename DataType>
  class Option : public llvm::cl::opt<DataType, /*ExternalStorage=*/false,
                                      OptionParser<DataType>>,
  using OptionParser =
      std::conditional_t<std::is_base_of<llvm::cl::generic_parser_base,
                                         llvm::cl::parser<DataType>>::value,
                         GenericOptionParser<DataType>,
                         llvm::cl::parser<DataType>>;

  /// This class represents a specific pass option, with a provided data type.
  template <typename DataType, typename OptionParser = OptionParser<DataType>>
  class Option
      : public llvm::cl::opt<DataType, /*ExternalStorage=*/false, OptionParser>,
        public OptionBase {
  public:
    template <typename... Args>
    Option(PassOptions &parent, StringRef arg, Args &&... args)
        : llvm::cl::opt<DataType, /*ExternalStorage=*/false,
                        OptionParser<DataType>>(arg, llvm::cl::sub(parent),
                                                std::forward<Args>(args)...) {
        : llvm::cl::opt<DataType, /*ExternalStorage=*/false, OptionParser>(
              arg, llvm::cl::sub(parent), std::forward<Args>(args)...) {
      assert(!this->isPositional() && !this->isSink() &&
             "sink and positional options are not supported");
      parent.options.push_back(this);
    }
    using llvm::cl::opt<DataType, /*ExternalStorage=*/false,
                        OptionParser<DataType>>::operator=;
                        OptionParser>::operator=;
    ~Option() override = default;

  private:
@@ -131,22 +130,22 @@ public:

    /// Copy the value from the given option into this one.
    void copyValueFrom(const OptionBase &other) final {
      this->setValue(static_cast<const Option<DataType> &>(other).getValue());
      this->setValue(static_cast<const Option<DataType, OptionParser> &>(other)
                         .getValue());
    }
  };

  /// This class represents a specific pass option that contains a list of
  /// values of the provided data type.
  template <typename DataType>
  class ListOption : public llvm::cl::list<DataType, /*StorageClass=*/bool,
                                           OptionParser<DataType>>,
  template <typename DataType, typename OptionParser = OptionParser<DataType>>
  class ListOption
      : public llvm::cl::list<DataType, /*StorageClass=*/bool, OptionParser>,
        public OptionBase {
  public:
    template <typename... Args>
    ListOption(PassOptions &parent, StringRef arg, Args &&... args)
        : llvm::cl::list<DataType, /*StorageClass=*/bool,
                         OptionParser<DataType>>(arg, llvm::cl::sub(parent),
                                                 std::forward<Args>(args)...) {
        : llvm::cl::list<DataType, /*StorageClass=*/bool, OptionParser>(
              arg, llvm::cl::sub(parent), std::forward<Args>(args)...) {
      assert(!this->isPositional() && !this->isSink() &&
             "sink and positional options are not supported");
      parent.options.push_back(this);
@@ -154,7 +153,7 @@ public:
    ~ListOption() override = default;

    /// Allow assigning from an ArrayRef.
    ListOption<DataType> &operator=(ArrayRef<DataType> values) {
    ListOption<DataType, OptionParser> &operator=(ArrayRef<DataType> values) {
      (*this)->assign(values.begin(), values.end());
      return *this;
    }
@@ -177,7 +176,8 @@ public:
    /// Copy the value from the given option into this one.
    void copyValueFrom(const OptionBase &other) final {
      (*this) = ArrayRef<DataType>(
          (ListOption<DataType> &)(const_cast<OptionBase &>(other)));
          (ListOption<DataType, OptionParser> &)(const_cast<OptionBase &>(
              other)));
    }
  };