507 lines
19 KiB
C++
507 lines
19 KiB
C++
/*===- 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)
|