135 lines
6.8 KiB
C++
135 lines
6.8 KiB
C++
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|
|
|* *|
|
|
|* Dialect Declarations *|
|
|
|* *|
|
|
|* Automatically generated file, do not edit! *|
|
|
|* From: AMDGPU.td *|
|
|
|* *|
|
|
\*===----------------------------------------------------------------------===*/
|
|
|
|
namespace mlir::amdgpu {
|
|
|
|
/// The `AMDGPU` dialect provides wrappers around AMD-specific functionality
|
|
/// and LLVM intrinsics. These wrappers should be used in conjunction with
|
|
/// more generic dialects, such as `gpu` and `vector`, when generating LLVM IR
|
|
/// that will eventually be executed on AMD hardware.
|
|
///
|
|
/// # What goes here?
|
|
/// In many cases, AMD GPU functionality can be accessed either though generic
|
|
/// operations (such as those in the `gpu`, `vector`, or `math`) or through
|
|
/// the `rocdl` dialect's intrinsic wrappers. However, there are instances where
|
|
/// AMD-specific functionally benefits from a wrapper around the underlying
|
|
/// LLVM intrinsics.
|
|
///
|
|
/// In general terms, operations or types should be added to this dialect when they
|
|
/// wrap some AMD-specific functionality in a way that makes it work better with the
|
|
/// MLIR ecosystem and its types or when those buitins would be needlessly
|
|
/// complex to work with (such as if they features magic constants at the LLVM level).
|
|
///
|
|
/// An additional set of operations that belong in this dialect are those that
|
|
/// have chipset-specific differences that can be abstracted over in a useful way.
|
|
///
|
|
/// To give some concrete examples:
|
|
///
|
|
/// - `amdgpu.mfma` and `amdgpu.wmma` exist in order to make a large set of
|
|
/// intrinsics more compatible with the MLIR type system (such as by allowing
|
|
/// 8-bit float vectors to be passed as `vector<N x f8E4M3FN>` or
|
|
/// `vector<N x f8E4M2>` instead of as packed 32-bit integers whose element type
|
|
/// is controlled by separate operator-level constants. These operations also
|
|
/// allow the same `amdgpu.mfma` operation to be used regardless of the target
|
|
/// chip.
|
|
/// - `amdgpu.swizzle_bitmode` provides a wrapper around the `ds.swizzle` intrinsic,
|
|
/// allowing a wider range of types (such as `vector<2xf16>`) to be used natively
|
|
/// and eliminating the need to pack the and, or, and xor components using opaque
|
|
/// shifts.
|
|
/// - Operations like `amdgpu.gather_to_lds` provide `memref`-ized wrappers around
|
|
/// intrinsics that take a pointer, and are nontrivial enough to justify inclusion
|
|
/// in this dialect.
|
|
///
|
|
///
|
|
/// Note that simple intrinsics like `rocdl.sin` or `rocdl.s.barrier` should not
|
|
/// receive wrapper operations, as nothing is gained from the duplicate operation.
|
|
/// As a rule of thumb, if an operation's rewrite in AMDGPUToROCDL would be only
|
|
/// a `replaceOpWithNewOp` call, no AMDGPU dialect operation is needed.
|
|
///
|
|
/// # Design guidelines
|
|
///
|
|
/// Operations should leverage MLIR's "standard" types where possible. MLIR has
|
|
/// a more extensible type system than LLVM (especially in the area of small floats)
|
|
/// and those types should be used to create more ergonomic wrappers. In particular,
|
|
/// intrinsics that take pointers should have wrappers in this dialect that take
|
|
/// `memref` arguments and indices.
|
|
///
|
|
/// Operations should use properties or attributes in cases where the underlying
|
|
/// intrinsic uses `immarg`s (except in cases where that attribute can be represented
|
|
/// in the type system).
|
|
///
|
|
/// If it is possible to generalize the types of an operation, it should be done.
|
|
/// For example, the underlying operations for permutations and swizzles always
|
|
/// take 32-bit operands. Their AMDGPU wrappers can take any type, and will apply
|
|
/// padding and expansion to multiple instructions as needed. This makes these
|
|
/// operations easier to target because it hides the bitcasts and extracts
|
|
/// until the final lowering.
|
|
///
|
|
/// When the underlying operation uses magic constants, those should be presented
|
|
/// in a more programmer-friendly fashion, such as through enums or though
|
|
/// using separate arguments that are later combined. (For example, see the
|
|
/// design of the `amdgpu.dpp` and `amdgpu.fat_raw_buffer_cast` operations.)
|
|
/// However, in the case where an immediate argument corresponds directly to an
|
|
/// enum in the backend compiler, that enum should be in the ROCDL dialect
|
|
/// instead.
|
|
///
|
|
/// If sufficiently similar functionality on multiple hardware generations can be
|
|
/// encapsulated into a single operation, it should be done. The lowering to
|
|
/// intrinsics should either throw an error when an unsupported capability is
|
|
/// used or ignore it. Which of these is two failure modes is more appropriate
|
|
/// depends on the nature of the feature, but errors are a safe default choice.
|
|
///
|
|
/// # Documentation guidelines
|
|
///
|
|
/// AMDGPU dialect operations should document how any abstractions they introduce
|
|
/// translate to LLVM intrinsics or hardware operations.
|
|
///
|
|
/// While documenting the semantics of the underlying operations is not required,
|
|
/// is preferred to provide an overview of the operation's functionality,
|
|
/// especially in cases where the documentation is widely distributed. Someone
|
|
/// looking at an AMDGPU dialect operation should be able to generally understand
|
|
/// what it does and have found the keywords they'll need for more detail.
|
|
///
|
|
/// Operation documentation should include usage examples.
|
|
///
|
|
/// Note that this dialect uses LLVM's gfx numbers to refer to individual
|
|
/// architectures/chipsets and not product names or codenames.
|
|
class AMDGPUDialect : public ::mlir::Dialect {
|
|
explicit AMDGPUDialect(::mlir::MLIRContext *context);
|
|
|
|
void initialize();
|
|
friend class ::mlir::MLIRContext;
|
|
public:
|
|
~AMDGPUDialect() override;
|
|
static constexpr ::llvm::StringLiteral getDialectNamespace() {
|
|
return ::llvm::StringLiteral("amdgpu");
|
|
}
|
|
|
|
/// 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;
|
|
|
|
/// Parse a type registered to this dialect.
|
|
::mlir::Type parseType(::mlir::DialectAsmParser &parser) const override;
|
|
|
|
/// Print a type registered to this dialect.
|
|
void printType(::mlir::Type type,
|
|
::mlir::DialectAsmPrinter &os) const override;
|
|
|
|
void registerAttributes();
|
|
void registerTypes();
|
|
};
|
|
|
|
} // namespace mlir::amdgpu
|
|
MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::amdgpu::AMDGPUDialect)
|