/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Dialect Declarations                                                       *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|* From: ROCDLOps.td                                                          *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

namespace mlir::ROCDL {

/// Dialect for wrapping LLVM AMDGPU backend intrinsics and attributes
/// The ROCDL dialect, like the other platform-specific LLVM dialects, serves
/// as the location of wrappers around the AMD-specific intrinsics and attributes
/// in LLVM.
/// 
/// This dialect, like other GPU lowering targets, also contains the infrastructure
/// used by the built-in compilation/offloading framework to compile AMD-specific
/// LLVM IR into binaries.
/// 
/// # Dialect inclusion criteria and guidelines
/// 
/// The operations in this dialect are 1:1 wrappers around their corresponding
/// LLVM intrinsics. Operations that do not correspond to intrinsics should not
/// be placed in this dialect.
/// 
/// The definition of a ROCDL op should match its LLVM counterpart. If the
/// argument and result types are fixed, they should be specified as type
/// constraints, including by overriding the default variadic type on LLVM
/// intrinsics by doing a `let results` in the operation definition.
/// 
/// As an exception, if an `immarg` intrinsic argument corresponds to a backend
/// enum, it should be represented in MLIR by an attribute that models that
/// enum.
/// 
/// LLVM attributes do not need to be replicated exactly if it wouldn't be
/// easy to do so, but pure operations and ones that read/write memory should
/// be annotated as such.
/// 
/// While LLVM intrinsics currently don't allow constraining the values an
/// `any_type` can take, it is acceptable (but not required) to impose such
/// constraints if they are known.
/// 
/// When an LLVM intrinsic uses an `immarg`, this corresponds to an attribute
/// in MLIR.
/// 
/// Human-readable assembly formats (those that, for example, explicitly indicate
/// parameter names) may be used, and are encouraged for intrinsics that have
/// complex argument schemes and don't have any higher-level wrapper (such as
/// in the `amdgpu` dialect).
/// 
/// While not all existing operations follow this convention, new operations should
/// generally provide argument and result types except in cases where they are
/// clearly redundant (such as with operations like `rocdl.fmed3`, which doesn't
/// need to reiterate the single type at issue multiple times). This convention
/// enhances the readability of low-level IR and prevents programmers from needing
/// to find non-local type information.
/// 
/// Dialect-defined discardable attributes (any attribute starting with `rocdl.`
/// that has special handling) need to correspond to AMD-specific attributes, metadata,
/// or other entities (such as calling conventions) in LLVM, or be needed for
/// GPU compilation management. Outside of the compilation infrastructure,
/// dialect-specific enums or attributes are extremely unlikely to be needed
/// and should be avoided.
/// 
/// Operation documentation should specify when the operation was introduced
/// (if relevant) and include usage examples. Operations should have
/// parser/printer tests in `mlir/test/Dialect/LLVMIR/rocdl.mlir` and
/// lowering tests in `mlir/test/Target/LLVMIR/rocdl.mlir`.
/// 
/// # General documentation (What does this op do?)
/// 
/// While rocdl ops sometimes carry their own documentation, there is no
/// expectation that such documentation will exist (or be kept up to date).
/// 
/// Since ROCDL operations correspond to LLVM intrinsics, the semantics and
/// behavior of these operations can be determined by investigating the
/// documentation for the corresponding intrinsic. This documentation
/// can be found in
/// - `llvm/docs/AMDGPUUsage.rst` and
/// - The comments of `llvm/include/llvm/IR/IntrinsicsAMDGPU.td`, which
///   is where details of the meaning of certain bitfields or of how an
///   intrinsic corresponds to hardware instructions are most likely to
///   be found.
/// 
/// Since many intrinsics are themselves minimal wrappers around hardware
/// instructions, these documentation sources often do not repeat hardware
/// documentation. If an intrinsic appears undocumented, information about
/// its behavior will often be available in published ISA descriptions or
/// (sometimes known as shader programming guides).
/// 
/// If an operation doesn't provide usage examples, it is likely that they
/// can be found in `mlir/test/Dialect/LLVMIR/rocdl.mlir` (op syntax and
/// verification) or `mlir/test/Target/LLVMIR/rocdl.mlir` (translation
/// to LLVM IR).
class ROCDLDialect : public ::mlir::Dialect {
  explicit ROCDLDialect(::mlir::MLIRContext *context);

  void initialize();
  friend class ::mlir::MLIRContext;
public:
  ~ROCDLDialect() override;
  static constexpr ::llvm::StringLiteral getDialectNamespace() {
    return ::llvm::StringLiteral("rocdl");
  }

  /// Parse an attribute registered to this dialect.
  ::mlir::Attribute parseAttribute(::mlir::DialectAsmParser &parser,
                                   ::mlir::Type type) const override;

  /// Print an attribute registered to this dialect.
  void printAttribute(::mlir::Attribute attr,
                      ::mlir::DialectAsmPrinter &os) const override;

    /// Provides a hook for verifying dialect attributes attached to the given
    /// op.
    ::llvm::LogicalResult verifyOperationAttribute(
        ::mlir::Operation *op, ::mlir::NamedAttribute attribute) override;

    /// Helper to manage the discardable attribute `kernel`.
    class KernelAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.kernel";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit KernelAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::UnitAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::UnitAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::UnitAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::UnitAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::UnitAttr>(name));
       op->removeAttr(name);
     }
   };
   KernelAttrHelper getKernelAttrHelper() {
     return kernelAttrName;
   }
 private:
   KernelAttrHelper kernelAttrName;
 public:

    /// Helper to manage the discardable attribute `reqd_work_group_size`.
    class ReqdWorkGroupSizeAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.reqd_work_group_size";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit ReqdWorkGroupSizeAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::DenseI32ArrayAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::DenseI32ArrayAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::DenseI32ArrayAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::DenseI32ArrayAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::DenseI32ArrayAttr>(name));
       op->removeAttr(name);
     }
   };
   ReqdWorkGroupSizeAttrHelper getReqdWorkGroupSizeAttrHelper() {
     return reqdWorkGroupSizeAttrName;
   }
 private:
   ReqdWorkGroupSizeAttrHelper reqdWorkGroupSizeAttrName;
 public:

    /// Helper to manage the discardable attribute `flat_work_group_size`.
    class FlatWorkGroupSizeAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.flat_work_group_size";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit FlatWorkGroupSizeAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::StringAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::StringAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::StringAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::StringAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::StringAttr>(name));
       op->removeAttr(name);
     }
   };
   FlatWorkGroupSizeAttrHelper getFlatWorkGroupSizeAttrHelper() {
     return flatWorkGroupSizeAttrName;
   }
 private:
   FlatWorkGroupSizeAttrHelper flatWorkGroupSizeAttrName;
 public:

    /// Helper to manage the discardable attribute `max_flat_work_group_size`.
    class MaxFlatWorkGroupSizeAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.max_flat_work_group_size";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit MaxFlatWorkGroupSizeAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::IntegerAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::IntegerAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::IntegerAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::IntegerAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::IntegerAttr>(name));
       op->removeAttr(name);
     }
   };
   MaxFlatWorkGroupSizeAttrHelper getMaxFlatWorkGroupSizeAttrHelper() {
     return maxFlatWorkGroupSizeAttrName;
   }
 private:
   MaxFlatWorkGroupSizeAttrHelper maxFlatWorkGroupSizeAttrName;
 public:

    /// Helper to manage the discardable attribute `waves_per_eu`.
    class WavesPerEuAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.waves_per_eu";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit WavesPerEuAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::IntegerAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::IntegerAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::IntegerAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::IntegerAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::IntegerAttr>(name));
       op->removeAttr(name);
     }
   };
   WavesPerEuAttrHelper getWavesPerEuAttrHelper() {
     return wavesPerEuAttrName;
   }
 private:
   WavesPerEuAttrHelper wavesPerEuAttrName;
 public:

    /// Helper to manage the discardable attribute `unsafe_fp_atomics`.
    class UnsafeFpAtomicsAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.unsafe_fp_atomics";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit UnsafeFpAtomicsAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::BoolAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::BoolAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::BoolAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::BoolAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::BoolAttr>(name));
       op->removeAttr(name);
     }
   };
   UnsafeFpAtomicsAttrHelper getUnsafeFpAtomicsAttrHelper() {
     return unsafeFpAtomicsAttrName;
   }
 private:
   UnsafeFpAtomicsAttrHelper unsafeFpAtomicsAttrName;
 public:

    /// Helper to manage the discardable attribute `last_use`.
    class LastUseAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.last_use";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit LastUseAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::UnitAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::UnitAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::UnitAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::UnitAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::UnitAttr>(name));
       op->removeAttr(name);
     }
   };
   LastUseAttrHelper getLastUseAttrHelper() {
     return lastUseAttrName;
   }
 private:
   LastUseAttrHelper lastUseAttrName;
 public:

    /// Helper to manage the discardable attribute `no_remote_memory`.
    class NoRemoteMemoryAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.no_remote_memory";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit NoRemoteMemoryAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::UnitAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::UnitAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::UnitAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::UnitAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::UnitAttr>(name));
       op->removeAttr(name);
     }
   };
   NoRemoteMemoryAttrHelper getNoRemoteMemoryAttrHelper() {
     return noRemoteMemoryAttrName;
   }
 private:
   NoRemoteMemoryAttrHelper noRemoteMemoryAttrName;
 public:

    /// Helper to manage the discardable attribute `no_fine_grained_memory`.
    class NoFineGrainedMemoryAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.no_fine_grained_memory";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit NoFineGrainedMemoryAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::UnitAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::UnitAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::UnitAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::UnitAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::UnitAttr>(name));
       op->removeAttr(name);
     }
   };
   NoFineGrainedMemoryAttrHelper getNoFineGrainedMemoryAttrHelper() {
     return noFineGrainedMemoryAttrName;
   }
 private:
   NoFineGrainedMemoryAttrHelper noFineGrainedMemoryAttrName;
 public:

    /// Helper to manage the discardable attribute `ignore_denormal_mode`.
    class IgnoreDenormalModeAttrHelper {
      ::mlir::StringAttr name;
    public:
      static constexpr ::llvm::StringLiteral getNameStr() {
        return "rocdl.ignore_denormal_mode";
      }
      constexpr ::mlir::StringAttr getName() const {
        return name;
      }

      explicit IgnoreDenormalModeAttrHelper(::mlir::MLIRContext *ctx)
        : name(::mlir::StringAttr::get(ctx, getNameStr())) {}

     ::mlir::UnitAttr getAttr(::mlir::Operation *op) const {
       return op->getAttrOfType<::mlir::UnitAttr>(name);
     }
     void setAttr(::mlir::Operation *op, ::mlir::UnitAttr val) const {
       op->setAttr(name, val);
     }
     bool isAttrPresent(::mlir::Operation *op) const {
       return op->hasAttrOfType<::mlir::UnitAttr>(name);
     }
     void removeAttr(::mlir::Operation *op) const {
       assert(op->hasAttrOfType<::mlir::UnitAttr>(name));
       op->removeAttr(name);
     }
   };
   IgnoreDenormalModeAttrHelper getIgnoreDenormalModeAttrHelper() {
     return ignoreDenormalModeAttrName;
   }
 private:
   IgnoreDenormalModeAttrHelper ignoreDenormalModeAttrName;
 public:

    /// Get the name of the attribute used to annotate external kernel
    /// functions.
    static StringRef getKernelFuncAttrName() { return "rocdl.kernel"; }
    static constexpr ::llvm::StringLiteral getFlatWorkGroupSizeAttrName() {
      return ::llvm::StringLiteral("rocdl.flat_work_group_size");
    }
    static constexpr ::llvm::StringLiteral getReqdWorkGroupSizeAttrName() {
      return ::llvm::StringLiteral("rocdl.reqd_work_group_size");
    }
    /// MLIR's gpu-related infrastructure effectively assume uniform workgroup
    /// sizes, so this attribute defaults to "true" on `rocdl.kernel` functions.
    /// It is provided here to allow overriding this assumption.
    static constexpr ::llvm::StringLiteral getUniformWorkGroupSizeAttrName() {
      return ::llvm::StringLiteral("rocdl.uniform_work_group_size");
    }
    /// Get the LLVM module flag key for the AMDGPU buffer OOB mode.
    static constexpr ::llvm::StringLiteral
    getModuleFlagKeyBufferOOBModeName() {
      return ::llvm::StringLiteral("amdgpu.buffer.oob.mode");
    }
    /// Get the LLVM module flag key for the AMDGPU tbuffer OOB mode.
    static constexpr ::llvm::StringLiteral
    getModuleFlagKeyTBufferOOBModeName() {
      return ::llvm::StringLiteral("amdgpu.tbuffer.oob.mode");
    }
    /// The address space value that represents global memory.
    static constexpr unsigned kGlobalMemoryAddressSpace = 1;
    /// The address space value that represents shared memory.
    static constexpr unsigned kSharedMemoryAddressSpace = 3;
    /// The address space value that represents constant memory.
    static constexpr unsigned kConstantMemoryAddressSpace = 4;
    /// The address space value that represents private memory.
    static constexpr unsigned kPrivateMemoryAddressSpace = 5;
  };

} // namespace mlir::ROCDL
MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::ROCDL::ROCDLDialect)
