13#include "llvm/Support/ErrorHandling.h"
20static constexpr uint64_t
kMaxDim = std::numeric_limits<uint32_t>::max();
27 unsigned width = IndexType::kInternalStorageBitWidth;
33enum class LaunchDims : uint32_t {
Block = 0, Grid = 1, Cluster = 2 };
51 llvm_unreachable(
"All dimension enum cases handled above");
54static uint64_t
zext(uint32_t arg) {
return static_cast<uint64_t
>(arg); }
56static std::optional<uint64_t>
60 case LaunchDims::Block:
61 bounds =
func.getKnownBlockSizeAttr();
63 case LaunchDims::Grid:
64 bounds =
func.getKnownGridSizeAttr();
66 case LaunchDims::Cluster:
67 bounds =
func.getKnownClusterSizeAttr();
72 if (bounds.size() <
static_cast<uint32_t
>(dim))
74 return zext(bounds[
static_cast<uint32_t
>(dim)]);
83 if (bounds.size() <
static_cast<uint32_t
>(dim))
85 return zext(bounds[
static_cast<uint32_t
>(dim)]);
90 Dimension dim = op.getDimension();
91 if (
auto launch = op->template getParentOfType<LaunchOp>()) {
94 case LaunchDims::Block:
95 bounds = launch.getBlockSizeOperandValues();
97 case LaunchDims::Grid:
98 bounds = launch.getGridSizeOperandValues();
100 case LaunchDims::Cluster:
101 if (launch.hasClusterSize()) {
102 auto clusterBounds = launch.getClusterSizeOperandValues();
104 bounds = *clusterBounds;
111 return value.getZExtValue();
114 if (
auto gpuFunc = op->template getParentOfType<GPUFuncOp>()) {
119 if (
auto func = op->template getParentOfType<FunctionOpInterface>()) {
122 case LaunchDims::Block:
123 attrName = GPUDialect::KnownBlockSizeAttrHelper::getNameStr();
125 case LaunchDims::Grid:
126 attrName = GPUDialect::KnownGridSizeAttrHelper::getNameStr();
128 case LaunchDims::Cluster:
129 attrName = GPUDialect::KnownClusterSizeAttrHelper::getNameStr();
134 return discardableAttr;
143 max = specified->getZExtValue();
150 return setResultRange(getResult(),
getIndexRange(*known, *known));
154 max = specified->getZExtValue();
162 max = specified->getZExtValue();
172 max = specified->getZExtValue();
178 std::optional<uint64_t> knownVal =
181 return setResultRange(getResult(),
getIndexRange(*knownVal, *knownVal));
185 max = specified->getZExtValue();
193 max = fromContext.value();
195 max = specified->getZExtValue();
203 return setResultRange(getResult(),
getIndexRange(*knownVal, *knownVal));
206 max = specified->getZExtValue();
214 max = fromContext.value();
216 max = specified->getZExtValue();
224 max = specified->getZExtValue();
232 max = specified->getZExtValue();
239 return setResultRange(getResult(),
242 uint64_t blockDimMax =
244 uint64_t gridDimMax =
246 setResultRange(getResult(),
254 max = specified->getZExtValue();
262 max = specified->getZExtValue();
270 if (argRange.
umin().getBitWidth() != IndexType::kInternalStorageBitWidth)
274 setResultRange(dimResult, dimRange);
277 setResultRange(idxResult, idxRange);
280 argRanges = argRanges.drop_front(getAsyncDependencies().size());
283 setRange(argRanges[0], gridDims.
x, blockIds.
x);
284 setRange(argRanges[1], gridDims.
y, blockIds.
y);
285 setRange(argRanges[2], gridDims.
z, blockIds.
z);
288 setRange(argRanges[3], blockDims.
x, threadIds.
x);
289 setRange(argRanges[4], blockDims.
y, threadIds.
y);
290 setRange(argRanges[5], blockDims.
z, threadIds.
z);
static std::optional< int64_t > getUpperBound(Value iv)
Gets the constant upper bound on an affine.for iv.
static Value valueByDim(KernelDim3 dims, Dimension dim)
If the operation op is in a context that is annotated with maximum launch dimensions (a launch op wit...
static constexpr uint64_t kMaxClusterDim
static constexpr uint64_t kMaxDim
static uint64_t zext(uint32_t arg)
static ConstantIntRanges getIndexRange(uint64_t umin, uint64_t umax)
static std::optional< uint64_t > getKnownLaunchAttr(GPUFuncOp func, LaunchDims dims, Dimension dim)
static constexpr uint64_t kMaxSubgroupSize
static std::optional< uint64_t > getKnownLaunchDim(Op op, LaunchDims type)
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
Block represents an ordered list of Operations.
A set of arbitrary-precision integers representing bounds on a given integer value.
static ConstantIntRanges fromUnsigned(const APInt &umin, const APInt &umax)
Create an ConstantIntRanges with the unsigned minimum and maximum equal to umin and umax and the sign...
ConstantIntRanges intersection(const ConstantIntRanges &other) const
Returns the intersection (computed separately for signed and unsigned bounds) of this range and other...
const APInt & umax() const
The maximum value of an integer when it is interpreted as unsigned.
const APInt & umin() const
The minimum value of an integer when it is interpreted as unsigned.
This provides public APIs that all operations should have.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
SmallVector< unsigned > getBlockSize(AffineMap dimToLvl)
Given the dimToLvl map, returns the block sizes in a vector.
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
detail::constant_int_value_binder m_ConstantInt(IntegerAttr::ValueType *bind_value)
Matches a constant holding a scalar/vector/tensor integer (splat) and writes the integer value to bin...
llvm::function_ref< void(Value, const ConstantIntRanges &)> SetIntRangeFn
The type of the setResultRanges callback provided to ops implementing InferIntRangeInterface.
detail::DenseArrayAttrImpl< int32_t > DenseI32ArrayAttr
Utility class for the GPU dialect to represent triples of Values accessible through ....