MLIR 23.0.0git
IndexIntrinsicsOpLowering.cpp
Go to the documentation of this file.
1//===- IndexIntrinsicsOpLowering.cpp - GPU Index Op Lowering --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
13
14using namespace mlir;
15using namespace mlir::gpu::index_lowering;
16
18 Operation *op, gpu::Dimension dim, std::optional<uint32_t> opUpperBound,
19 IndexKind indexKind, IntrType intrType, unsigned bitWidth) {
20 // Order of priority for bounds:
21 // 1. The upper_bound attribute
22 // 2. Inherent attributes on a surrounding gpu.func
23 // 3. Discardable attributes on a surrounding function of any kind
24 // The below code handles these in reverse order so that more important
25 // sources overwrite less important ones.
26 DenseI32ArrayAttr funcBounds = nullptr;
27 if (auto funcOp = op->getParentOfType<FunctionOpInterface>()) {
28 switch (indexKind) {
29 case IndexKind::Block: {
30 auto blockHelper =
31 gpu::GPUDialect::KnownBlockSizeAttrHelper(op->getContext());
32 if (blockHelper.isAttrPresent(funcOp))
33 funcBounds = blockHelper.getAttr(funcOp);
34 break;
35 }
36 case IndexKind::Grid: {
37 auto gridHelper =
38 gpu::GPUDialect::KnownGridSizeAttrHelper(op->getContext());
39 if (gridHelper.isAttrPresent(funcOp))
40 funcBounds = gridHelper.getAttr(funcOp);
41 break;
42 }
43 case IndexKind::Cluster: {
44 auto clusterHelper =
45 gpu::GPUDialect::KnownClusterSizeAttrHelper(op->getContext());
46 if (clusterHelper.isAttrPresent(funcOp))
47 funcBounds = clusterHelper.getAttr(funcOp);
48 break;
49 }
51 break;
52 }
53 }
54 if (auto gpuFunc = op->getParentOfType<gpu::GPUFuncOp>()) {
55 switch (indexKind) {
57 funcBounds = gpuFunc.getKnownBlockSizeAttr();
58 break;
59 case IndexKind::Grid:
60 funcBounds = gpuFunc.getKnownGridSizeAttr();
61 break;
63 funcBounds = gpuFunc.getKnownClusterSizeAttr();
64 break;
66 break;
67 }
68 }
69 std::optional<uint32_t> upperBound;
70 if (funcBounds)
71 upperBound = funcBounds.asArrayRef()[static_cast<uint32_t>(dim)];
72 if (opUpperBound)
73 upperBound = *opUpperBound;
74
75 if (!upperBound || intrType == IntrType::None)
76 return nullptr;
77
78 uint32_t min = (intrType == IntrType::Dim ? 1u : 0u);
79 uint32_t max =
80 llvm::SaturatingAdd(*upperBound, (intrType == IntrType::Id ? 0u : 1u));
81 return LLVM::ConstantRangeAttr::get(op->getContext(), bitWidth, min, max);
82}
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition Operation.h:259
MLIRContext * getContext()
Return the context this operation is associated with.
Definition Operation.h:237
LLVM::ConstantRangeAttr getIndexOpRange(Operation *op, gpu::Dimension dim, std::optional< uint32_t > opUpperBound, IndexKind indexKind, IntrType intrType, unsigned bitWidth)
Returns a ConstantRangeAttr for a GPU index op, or nullptr if no bounds are found.
Include the generated interface declarations.
detail::DenseArrayAttrImpl< int32_t > DenseI32ArrayAttr