/* Autogenerated by mlir-tblgen; don't manually edit */

#ifdef GEN_PASS_DECL
// Generate declarations for all passes.
#define GEN_PASS_DECL_BOXEDPROCEDUREPASS
#define GEN_PASS_DECL_CODEGENREWRITE
#define GEN_PASS_DECL_FIRTOLLVMLOWERING
#define GEN_PASS_DECL_TARGETREWRITEPASS
#undef GEN_PASS_DECL
#endif // GEN_PASS_DECL

//===----------------------------------------------------------------------===//
// BoxedProcedurePass
//===----------------------------------------------------------------------===//
#ifdef GEN_PASS_DECL_BOXEDPROCEDUREPASS
struct BoxedProcedurePassOptions {
  bool useThunks = true;
};
std::unique_ptr<::mlir::Pass> createBoxedProcedurePass();
std::unique_ptr<::mlir::Pass> createBoxedProcedurePass(const BoxedProcedurePassOptions &options);
#undef GEN_PASS_DECL_BOXEDPROCEDUREPASS
#endif // GEN_PASS_DECL_BOXEDPROCEDUREPASS
#ifdef GEN_PASS_DEF_BOXEDPROCEDUREPASS

namespace impl {
  std::unique_ptr<::mlir::Pass> createBoxedProcedurePass();
} // namespace impl

namespace impl {
  std::unique_ptr<::mlir::Pass> createBoxedProcedurePass(const BoxedProcedurePassOptions &options);
} // namespace impl
namespace impl {

template <typename DerivedT>
class BoxedProcedurePassBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = BoxedProcedurePassBase;

  BoxedProcedurePassBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  BoxedProcedurePassBase(const BoxedProcedurePassBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  BoxedProcedurePassBase& operator=(const BoxedProcedurePassBase &) = delete;
  BoxedProcedurePassBase(BoxedProcedurePassBase &&) = delete;
  BoxedProcedurePassBase& operator=(BoxedProcedurePassBase &&) = delete;
  ~BoxedProcedurePassBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("boxed-procedure");
  }
  ::llvm::StringRef getArgument() const override { return "boxed-procedure"; }

  ::llvm::StringRef getDescription() const override { return ""; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("BoxedProcedurePass");
  }
  ::llvm::StringRef getName() const override { return "BoxedProcedurePass"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Return the dialect that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(BoxedProcedurePassBase<DerivedT>)

  BoxedProcedurePassBase(const BoxedProcedurePassOptions &options) : BoxedProcedurePassBase() {
    useThunks = options.useThunks;
  }
protected:
  ::mlir::Pass::Option<bool> useThunks{*this, "use-thunks", ::llvm::cl::desc("Convert procedure pointer abstractions to a single code pointer, deploying thunks wherever required."), ::llvm::cl::init(true)};
private:

  friend std::unique_ptr<::mlir::Pass> createBoxedProcedurePass() {
    return std::make_unique<DerivedT>();
  }

  friend std::unique_ptr<::mlir::Pass> createBoxedProcedurePass(const BoxedProcedurePassOptions &options) {
    return std::make_unique<DerivedT>(options);
  }
};
} // namespace impl

std::unique_ptr<::mlir::Pass> createBoxedProcedurePass() {
  return impl::createBoxedProcedurePass();
}

std::unique_ptr<::mlir::Pass> createBoxedProcedurePass(const BoxedProcedurePassOptions &options) {
  return impl::createBoxedProcedurePass(options);
}
#undef GEN_PASS_DEF_BOXEDPROCEDUREPASS
#endif // GEN_PASS_DEF_BOXEDPROCEDUREPASS

//===----------------------------------------------------------------------===//
// CodeGenRewrite
//===----------------------------------------------------------------------===//
#ifdef GEN_PASS_DECL_CODEGENREWRITE
struct CodeGenRewriteOptions {
  bool preserveDeclare = false;
};
std::unique_ptr<::mlir::Pass> createCodeGenRewrite();
std::unique_ptr<::mlir::Pass> createCodeGenRewrite(const CodeGenRewriteOptions &options);
#undef GEN_PASS_DECL_CODEGENREWRITE
#endif // GEN_PASS_DECL_CODEGENREWRITE
#ifdef GEN_PASS_DEF_CODEGENREWRITE

namespace impl {
  std::unique_ptr<::mlir::Pass> createCodeGenRewrite();
} // namespace impl

namespace impl {
  std::unique_ptr<::mlir::Pass> createCodeGenRewrite(const CodeGenRewriteOptions &options);
} // namespace impl
namespace impl {

template <typename DerivedT>
class CodeGenRewriteBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = CodeGenRewriteBase;

  CodeGenRewriteBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  CodeGenRewriteBase(const CodeGenRewriteBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  CodeGenRewriteBase& operator=(const CodeGenRewriteBase &) = delete;
  CodeGenRewriteBase(CodeGenRewriteBase &&) = delete;
  CodeGenRewriteBase& operator=(CodeGenRewriteBase &&) = delete;
  ~CodeGenRewriteBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("cg-rewrite");
  }
  ::llvm::StringRef getArgument() const override { return "cg-rewrite"; }

  ::llvm::StringRef getDescription() const override { return "Rewrite some FIR ops into their code-gen forms."; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("CodeGenRewrite");
  }
  ::llvm::StringRef getName() const override { return "CodeGenRewrite"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Return the dialect that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    registry.insert<fir::FIROpsDialect>();
    registry.insert<fir::FIRCodeGenDialect>();
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(CodeGenRewriteBase<DerivedT>)

  CodeGenRewriteBase(const CodeGenRewriteOptions &options) : CodeGenRewriteBase() {
    preserveDeclare = options.preserveDeclare;
  }
protected:
  ::mlir::Pass::Option<bool> preserveDeclare{*this, "preserve-declare", ::llvm::cl::desc("Preserve DeclareOp during pre codegen re-write."), ::llvm::cl::init(false)};
  ::mlir::Pass::Statistic numDCE{this, "num-dce'd", "Number of operations eliminated"};
private:

  friend std::unique_ptr<::mlir::Pass> createCodeGenRewrite() {
    return std::make_unique<DerivedT>();
  }

  friend std::unique_ptr<::mlir::Pass> createCodeGenRewrite(const CodeGenRewriteOptions &options) {
    return std::make_unique<DerivedT>(options);
  }
};
} // namespace impl

std::unique_ptr<::mlir::Pass> createCodeGenRewrite() {
  return impl::createCodeGenRewrite();
}

std::unique_ptr<::mlir::Pass> createCodeGenRewrite(const CodeGenRewriteOptions &options) {
  return impl::createCodeGenRewrite(options);
}
#undef GEN_PASS_DEF_CODEGENREWRITE
#endif // GEN_PASS_DEF_CODEGENREWRITE

//===----------------------------------------------------------------------===//
// FIRToLLVMLowering
//===----------------------------------------------------------------------===//
#ifdef GEN_PASS_DECL_FIRTOLLVMLOWERING
struct FIRToLLVMLoweringOptions {
  std::string forcedTargetTriple;
  std::string forcedDataLayout;
  std::string forcedTargetCPU;
  std::string forcedTuneCPU;
  std::string forcedTargetFeatures;
  bool applyTBAA = false;
};
#undef GEN_PASS_DECL_FIRTOLLVMLOWERING
#endif // GEN_PASS_DECL_FIRTOLLVMLOWERING
#ifdef GEN_PASS_DEF_FIRTOLLVMLOWERING
namespace impl {

template <typename DerivedT>
class FIRToLLVMLoweringBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = FIRToLLVMLoweringBase;

  FIRToLLVMLoweringBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  FIRToLLVMLoweringBase(const FIRToLLVMLoweringBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  FIRToLLVMLoweringBase& operator=(const FIRToLLVMLoweringBase &) = delete;
  FIRToLLVMLoweringBase(FIRToLLVMLoweringBase &&) = delete;
  FIRToLLVMLoweringBase& operator=(FIRToLLVMLoweringBase &&) = delete;
  ~FIRToLLVMLoweringBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("fir-to-llvm-ir");
  }
  ::llvm::StringRef getArgument() const override { return "fir-to-llvm-ir"; }

  ::llvm::StringRef getDescription() const override { return "Convert FIR dialect to LLVM-IR dialect"; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("FIRToLLVMLowering");
  }
  ::llvm::StringRef getName() const override { return "FIRToLLVMLowering"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Return the dialect that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    registry.insert<mlir::LLVM::LLVMDialect>();
    registry.insert<mlir::DLTIDialect>();
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(FIRToLLVMLoweringBase<DerivedT>)

  FIRToLLVMLoweringBase(const FIRToLLVMLoweringOptions &options) : FIRToLLVMLoweringBase() {
    forcedTargetTriple = options.forcedTargetTriple;
    forcedDataLayout = options.forcedDataLayout;
    forcedTargetCPU = options.forcedTargetCPU;
    forcedTuneCPU = options.forcedTuneCPU;
    forcedTargetFeatures = options.forcedTargetFeatures;
    applyTBAA = options.applyTBAA;
  }
protected:
  ::mlir::Pass::Option<std::string> forcedTargetTriple{*this, "target", ::llvm::cl::desc("Override module's target triple.")};
  ::mlir::Pass::Option<std::string> forcedDataLayout{*this, "datalayout", ::llvm::cl::desc("Override module's data layout.")};
  ::mlir::Pass::Option<std::string> forcedTargetCPU{*this, "target-cpu", ::llvm::cl::desc("Override module's target CPU.")};
  ::mlir::Pass::Option<std::string> forcedTuneCPU{*this, "tune-cpu", ::llvm::cl::desc("Override module's tune CPU.")};
  ::mlir::Pass::Option<std::string> forcedTargetFeatures{*this, "target-features", ::llvm::cl::desc("Override module's target features.")};
  ::mlir::Pass::Option<bool> applyTBAA{*this, "apply-tbaa", ::llvm::cl::desc("Attach TBAA tags to memory accessing operations."), ::llvm::cl::init(false)};
private:
};
} // namespace impl
#undef GEN_PASS_DEF_FIRTOLLVMLOWERING
#endif // GEN_PASS_DEF_FIRTOLLVMLOWERING

//===----------------------------------------------------------------------===//
// TargetRewritePass
//===----------------------------------------------------------------------===//
#ifdef GEN_PASS_DECL_TARGETREWRITEPASS
struct TargetRewritePassOptions {
  std::string forcedTargetTriple;
  std::string forcedTargetCPU;
  std::string forcedTuneCPU;
  std::string forcedTargetFeatures;
  bool noCharacterConversion = false;
  bool noComplexConversion = false;
  bool noStructConversion = false;
};
std::unique_ptr<::mlir::Pass> createTargetRewritePass();
std::unique_ptr<::mlir::Pass> createTargetRewritePass(const TargetRewritePassOptions &options);
#undef GEN_PASS_DECL_TARGETREWRITEPASS
#endif // GEN_PASS_DECL_TARGETREWRITEPASS
#ifdef GEN_PASS_DEF_TARGETREWRITEPASS

namespace impl {
  std::unique_ptr<::mlir::Pass> createTargetRewritePass();
} // namespace impl

namespace impl {
  std::unique_ptr<::mlir::Pass> createTargetRewritePass(const TargetRewritePassOptions &options);
} // namespace impl
namespace impl {

template <typename DerivedT>
class TargetRewritePassBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = TargetRewritePassBase;

  TargetRewritePassBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  TargetRewritePassBase(const TargetRewritePassBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  TargetRewritePassBase& operator=(const TargetRewritePassBase &) = delete;
  TargetRewritePassBase(TargetRewritePassBase &&) = delete;
  TargetRewritePassBase& operator=(TargetRewritePassBase &&) = delete;
  ~TargetRewritePassBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("target-rewrite");
  }
  ::llvm::StringRef getArgument() const override { return "target-rewrite"; }

  ::llvm::StringRef getDescription() const override { return "Rewrite some FIR dialect into target specific forms."; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("TargetRewritePass");
  }
  ::llvm::StringRef getName() const override { return "TargetRewritePass"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Return the dialect that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    registry.insert<fir::FIROpsDialect>();
    registry.insert<mlir::func::FuncDialect>();
    registry.insert<mlir::DLTIDialect>();
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TargetRewritePassBase<DerivedT>)

  TargetRewritePassBase(const TargetRewritePassOptions &options) : TargetRewritePassBase() {
    forcedTargetTriple = options.forcedTargetTriple;
    forcedTargetCPU = options.forcedTargetCPU;
    forcedTuneCPU = options.forcedTuneCPU;
    forcedTargetFeatures = options.forcedTargetFeatures;
    noCharacterConversion = options.noCharacterConversion;
    noComplexConversion = options.noComplexConversion;
    noStructConversion = options.noStructConversion;
  }
protected:
  ::mlir::Pass::Option<std::string> forcedTargetTriple{*this, "target", ::llvm::cl::desc("Override module's target triple.")};
  ::mlir::Pass::Option<std::string> forcedTargetCPU{*this, "target-cpu", ::llvm::cl::desc("Override module's target CPU.")};
  ::mlir::Pass::Option<std::string> forcedTuneCPU{*this, "tune-cpu", ::llvm::cl::desc("Override module's tune CPU.")};
  ::mlir::Pass::Option<std::string> forcedTargetFeatures{*this, "target-features", ::llvm::cl::desc("Override module's target features.")};
  ::mlir::Pass::Option<bool> noCharacterConversion{*this, "no-character-conversion", ::llvm::cl::desc("Disable target-specific conversion of CHARACTER."), ::llvm::cl::init(false)};
  ::mlir::Pass::Option<bool> noComplexConversion{*this, "no-complex-conversion", ::llvm::cl::desc("Disable target-specific conversion of COMPLEX."), ::llvm::cl::init(false)};
  ::mlir::Pass::Option<bool> noStructConversion{*this, "no-struct-conversion", ::llvm::cl::desc("Disable target-specific conversion of derived type value."), ::llvm::cl::init(false)};
private:

  friend std::unique_ptr<::mlir::Pass> createTargetRewritePass() {
    return std::make_unique<DerivedT>();
  }

  friend std::unique_ptr<::mlir::Pass> createTargetRewritePass(const TargetRewritePassOptions &options) {
    return std::make_unique<DerivedT>(options);
  }
};
} // namespace impl

std::unique_ptr<::mlir::Pass> createTargetRewritePass() {
  return impl::createTargetRewritePass();
}

std::unique_ptr<::mlir::Pass> createTargetRewritePass(const TargetRewritePassOptions &options) {
  return impl::createTargetRewritePass(options);
}
#undef GEN_PASS_DEF_TARGETREWRITEPASS
#endif // GEN_PASS_DEF_TARGETREWRITEPASS
#ifdef GEN_PASS_REGISTRATION

//===----------------------------------------------------------------------===//
// BoxedProcedurePass Registration
//===----------------------------------------------------------------------===//

inline void registerBoxedProcedurePass() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return createBoxedProcedurePass();
  });
}

// Old registration code, kept for temporary backwards compatibility.
inline void registerBoxedProcedurePassPass() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return createBoxedProcedurePass();
  });
}

//===----------------------------------------------------------------------===//
// CodeGenRewrite Registration
//===----------------------------------------------------------------------===//

inline void registerCodeGenRewrite() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return createCodeGenRewrite();
  });
}

// Old registration code, kept for temporary backwards compatibility.
inline void registerCodeGenRewritePass() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return createCodeGenRewrite();
  });
}

//===----------------------------------------------------------------------===//
// FIRToLLVMLowering Registration
//===----------------------------------------------------------------------===//

inline void registerFIRToLLVMLowering() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return ::fir::createFIRToLLVMPass();
  });
}

// Old registration code, kept for temporary backwards compatibility.
inline void registerFIRToLLVMLoweringPass() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return ::fir::createFIRToLLVMPass();
  });
}

//===----------------------------------------------------------------------===//
// TargetRewritePass Registration
//===----------------------------------------------------------------------===//

inline void registerTargetRewritePass() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return createTargetRewritePass();
  });
}

// Old registration code, kept for temporary backwards compatibility.
inline void registerTargetRewritePassPass() {
  ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
    return createTargetRewritePass();
  });
}

//===----------------------------------------------------------------------===//
// OptCodeGen Registration
//===----------------------------------------------------------------------===//

inline void registerOptCodeGenPasses() {
  registerBoxedProcedurePass();
  registerCodeGenRewrite();
  registerFIRToLLVMLowering();
  registerTargetRewritePass();
}
#undef GEN_PASS_REGISTRATION
#endif // GEN_PASS_REGISTRATION
// Deprecated. Please use the new per-pass macros.
#ifdef GEN_PASS_CLASSES

template <typename DerivedT>
class BoxedProcedurePassBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = BoxedProcedurePassBase;

  BoxedProcedurePassBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  BoxedProcedurePassBase(const BoxedProcedurePassBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  BoxedProcedurePassBase& operator=(const BoxedProcedurePassBase &) = delete;
  BoxedProcedurePassBase(BoxedProcedurePassBase &&) = delete;
  BoxedProcedurePassBase& operator=(BoxedProcedurePassBase &&) = delete;
  ~BoxedProcedurePassBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("boxed-procedure");
  }
  ::llvm::StringRef getArgument() const override { return "boxed-procedure"; }

  ::llvm::StringRef getDescription() const override { return ""; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("BoxedProcedurePass");
  }
  ::llvm::StringRef getName() const override { return "BoxedProcedurePass"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Register the dialects that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(BoxedProcedurePassBase<DerivedT>)

protected:
  ::mlir::Pass::Option<bool> useThunks{*this, "use-thunks", ::llvm::cl::desc("Convert procedure pointer abstractions to a single code pointer, deploying thunks wherever required."), ::llvm::cl::init(true)};
};

template <typename DerivedT>
class CodeGenRewriteBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = CodeGenRewriteBase;

  CodeGenRewriteBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  CodeGenRewriteBase(const CodeGenRewriteBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  CodeGenRewriteBase& operator=(const CodeGenRewriteBase &) = delete;
  CodeGenRewriteBase(CodeGenRewriteBase &&) = delete;
  CodeGenRewriteBase& operator=(CodeGenRewriteBase &&) = delete;
  ~CodeGenRewriteBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("cg-rewrite");
  }
  ::llvm::StringRef getArgument() const override { return "cg-rewrite"; }

  ::llvm::StringRef getDescription() const override { return "Rewrite some FIR ops into their code-gen forms."; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("CodeGenRewrite");
  }
  ::llvm::StringRef getName() const override { return "CodeGenRewrite"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Register the dialects that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    registry.insert<fir::FIROpsDialect>();
    registry.insert<fir::FIRCodeGenDialect>();
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(CodeGenRewriteBase<DerivedT>)

protected:
  ::mlir::Pass::Option<bool> preserveDeclare{*this, "preserve-declare", ::llvm::cl::desc("Preserve DeclareOp during pre codegen re-write."), ::llvm::cl::init(false)};
  ::mlir::Pass::Statistic numDCE{this, "num-dce'd", "Number of operations eliminated"};
};

template <typename DerivedT>
class FIRToLLVMLoweringBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = FIRToLLVMLoweringBase;

  FIRToLLVMLoweringBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  FIRToLLVMLoweringBase(const FIRToLLVMLoweringBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  FIRToLLVMLoweringBase& operator=(const FIRToLLVMLoweringBase &) = delete;
  FIRToLLVMLoweringBase(FIRToLLVMLoweringBase &&) = delete;
  FIRToLLVMLoweringBase& operator=(FIRToLLVMLoweringBase &&) = delete;
  ~FIRToLLVMLoweringBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("fir-to-llvm-ir");
  }
  ::llvm::StringRef getArgument() const override { return "fir-to-llvm-ir"; }

  ::llvm::StringRef getDescription() const override { return "Convert FIR dialect to LLVM-IR dialect"; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("FIRToLLVMLowering");
  }
  ::llvm::StringRef getName() const override { return "FIRToLLVMLowering"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Register the dialects that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    registry.insert<mlir::LLVM::LLVMDialect>();
    registry.insert<mlir::DLTIDialect>();
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(FIRToLLVMLoweringBase<DerivedT>)

protected:
  ::mlir::Pass::Option<std::string> forcedTargetTriple{*this, "target", ::llvm::cl::desc("Override module's target triple.")};
  ::mlir::Pass::Option<std::string> forcedDataLayout{*this, "datalayout", ::llvm::cl::desc("Override module's data layout.")};
  ::mlir::Pass::Option<std::string> forcedTargetCPU{*this, "target-cpu", ::llvm::cl::desc("Override module's target CPU.")};
  ::mlir::Pass::Option<std::string> forcedTuneCPU{*this, "tune-cpu", ::llvm::cl::desc("Override module's tune CPU.")};
  ::mlir::Pass::Option<std::string> forcedTargetFeatures{*this, "target-features", ::llvm::cl::desc("Override module's target features.")};
  ::mlir::Pass::Option<bool> applyTBAA{*this, "apply-tbaa", ::llvm::cl::desc("Attach TBAA tags to memory accessing operations."), ::llvm::cl::init(false)};
};

template <typename DerivedT>
class TargetRewritePassBase : public ::mlir::OperationPass<mlir::ModuleOp> {
public:
  using Base = TargetRewritePassBase;

  TargetRewritePassBase() : ::mlir::OperationPass<mlir::ModuleOp>(::mlir::TypeID::get<DerivedT>()) {}
  TargetRewritePassBase(const TargetRewritePassBase &other) : ::mlir::OperationPass<mlir::ModuleOp>(other) {}
  TargetRewritePassBase& operator=(const TargetRewritePassBase &) = delete;
  TargetRewritePassBase(TargetRewritePassBase &&) = delete;
  TargetRewritePassBase& operator=(TargetRewritePassBase &&) = delete;
  ~TargetRewritePassBase() = default;

  /// Returns the command-line argument attached to this pass.
  static constexpr ::llvm::StringLiteral getArgumentName() {
    return ::llvm::StringLiteral("target-rewrite");
  }
  ::llvm::StringRef getArgument() const override { return "target-rewrite"; }

  ::llvm::StringRef getDescription() const override { return "Rewrite some FIR dialect into target specific forms."; }

  /// Returns the derived pass name.
  static constexpr ::llvm::StringLiteral getPassName() {
    return ::llvm::StringLiteral("TargetRewritePass");
  }
  ::llvm::StringRef getName() const override { return "TargetRewritePass"; }

  /// Support isa/dyn_cast functionality for the derived pass class.
  static bool classof(const ::mlir::Pass *pass) {
    return pass->getTypeID() == ::mlir::TypeID::get<DerivedT>();
  }

  /// A clone method to create a copy of this pass.
  std::unique_ptr<::mlir::Pass> clonePass() const override {
    return std::make_unique<DerivedT>(*static_cast<const DerivedT *>(this));
  }

  /// Register the dialects that must be loaded in the context before this pass.
  void getDependentDialects(::mlir::DialectRegistry &registry) const override {
    registry.insert<fir::FIROpsDialect>();
    registry.insert<mlir::func::FuncDialect>();
    registry.insert<mlir::DLTIDialect>();
  }

  /// Explicitly declare the TypeID for this class. We declare an explicit private
  /// instantiation because Pass classes should only be visible by the current
  /// library.
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TargetRewritePassBase<DerivedT>)

protected:
  ::mlir::Pass::Option<std::string> forcedTargetTriple{*this, "target", ::llvm::cl::desc("Override module's target triple.")};
  ::mlir::Pass::Option<std::string> forcedTargetCPU{*this, "target-cpu", ::llvm::cl::desc("Override module's target CPU.")};
  ::mlir::Pass::Option<std::string> forcedTuneCPU{*this, "tune-cpu", ::llvm::cl::desc("Override module's tune CPU.")};
  ::mlir::Pass::Option<std::string> forcedTargetFeatures{*this, "target-features", ::llvm::cl::desc("Override module's target features.")};
  ::mlir::Pass::Option<bool> noCharacterConversion{*this, "no-character-conversion", ::llvm::cl::desc("Disable target-specific conversion of CHARACTER."), ::llvm::cl::init(false)};
  ::mlir::Pass::Option<bool> noComplexConversion{*this, "no-complex-conversion", ::llvm::cl::desc("Disable target-specific conversion of COMPLEX."), ::llvm::cl::init(false)};
  ::mlir::Pass::Option<bool> noStructConversion{*this, "no-struct-conversion", ::llvm::cl::desc("Disable target-specific conversion of derived type value."), ::llvm::cl::init(false)};
};
#undef GEN_PASS_CLASSES
#endif // GEN_PASS_CLASSES
