[Mlir-commits] [mlir] [mlir][acc] Add map flag for mappings that need no device copy of its descriptor (PR #232064)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Oct 14 12:47:20 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Vijay Kandiah (VijayKandiah)
<details>
<summary>Changes</summary>
Mapping a variable reached through a descriptor does two things: it supplies the data's bounds, and it realizes a device copy of the descriptor so device code can read its `base_addr`. A transform that has already read everything the region needs from the descriptor on the host wants only the first, and today there is no way to ask for it. The only way is to drop the mapping, which discards the bounds too.
`MapFlags::no_device_descriptor` (bit 25) separates them. Keep deriving the bounds from the descriptor, but create no device copy of it and attach nothing into its `base_addr`. `computeDataClauseMapFlags` raises the flag from a discardable unit attribute, `acc.no_device_descriptor`. Discardable is deliberate and losing the attribute costs only the suppressed copy, so a pass that does not know about it cannot make a program wrong.
---
Full diff: https://github.com/llvm/llvm-project/pull/232064.diff
4 Files Affected:
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACC.h (+7)
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCCGEnums.td (+3-1)
- (modified) mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp (+2)
- (modified) mlir/test/Conversion/OpenACCToLLVM/data-runtime.mlir (+22)
``````````diff
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
index a05d3d530358db..429928faabf604 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
@@ -215,6 +215,13 @@ static constexpr StringLiteral getFromDefaultClauseAttrName() {
return StringLiteral("acc.from_default");
}
+/// Name for a unit attribute on a data entry operation stating that nothing in
+/// the region reads the descriptor its variable is reached through, so the
+/// mapping still supplies the bounds but needs no device copy of the descriptor.
+static constexpr StringLiteral getNoDeviceDescriptorAttrName() {
+ return StringLiteral("acc.no_device_descriptor");
+}
+
/// Name for an attribute attached to a loop indicating the number of loops
/// collapsed to create that loop
static constexpr StringLiteral getCollapseCountAttrName() {
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGEnums.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGEnums.td
index 77d7850a943300..484d7b85c6749d 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGEnums.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGEnums.td
@@ -62,6 +62,8 @@ def OpenACC_MapFlagsDescriptor : I32BitEnumAttrCaseBit<"descriptor", 21>;
def OpenACC_MapFlagsReduction : I32BitEnumAttrCaseBit<"reduction", 22>;
def OpenACC_MapFlagsAttach : I32BitEnumAttrCaseBit<"attach", 23>;
def OpenACC_MapFlagsDetach : I32BitEnumAttrCaseBit<"detach", 24>;
+def OpenACC_MapFlagsNoDeviceDescriptor
+ : I32BitEnumAttrCaseBit<"no_device_descriptor", 25>;
def OpenACC_MapFlagsEnum : I32BitEnumAttr<
"MapFlags", "OpenACC offload map-type flags",
@@ -74,7 +76,7 @@ def OpenACC_MapFlagsEnum : I32BitEnumAttr<
OpenACC_MapFlagsDeviceResident, OpenACC_MapFlagsIfPresent,
OpenACC_MapFlagsPresent, OpenACC_MapFlagsDescriptor,
OpenACC_MapFlagsReduction, OpenACC_MapFlagsAttach,
- OpenACC_MapFlagsDetach]> {
+ OpenACC_MapFlagsDetach, OpenACC_MapFlagsNoDeviceDescriptor]> {
let separator = ",";
let cppNamespace = "::mlir::acc";
let genSpecializedAttr = 0;
diff --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp
index 2ab44e447adfb7..7c90f09e4b37b0 100644
--- a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp
@@ -741,6 +741,8 @@ MapFlags computeDataClauseMapFlags(Operation *entryOp, bool ptrAndObj) {
flags = flags | MapFlags::ptr_and_obj;
if (getImplicitFlag(entryOp))
flags = flags | MapFlags::implicit;
+ if (entryOp->hasDiscardableAttr(getNoDeviceDescriptorAttrName()))
+ flags = flags | MapFlags::no_device_descriptor;
if (bitEnumContainsAny(getEntryModifiers(entryOp), DataClauseModifier::zero))
flags = flags | MapFlags::init_zero;
diff --git a/mlir/test/Conversion/OpenACCToLLVM/data-runtime.mlir b/mlir/test/Conversion/OpenACCToLLVM/data-runtime.mlir
index 4b3952a250c9b8..70a8e1bd30c114 100644
--- a/mlir/test/Conversion/OpenACCToLLVM/data-runtime.mlir
+++ b/mlir/test/Conversion/OpenACCToLLVM/data-runtime.mlir
@@ -520,3 +520,25 @@ func.func @memref_bounded(%arg0: memref<?xf32>) {
acc.delete accPtr(%map : memref<?xf32>) dataClause(acc_copyin)
return
}
+
+// -----
+
+// acc.no_device_descriptor raises NO_DEVICE_DESCRIPTOR alongside the flags the
+// clause itself implies, and applies to the exit call as well.
+// CHECK-LABEL: llvm.func @no_device_descriptor
+// to | no_device_descriptor = 1 | 33554432.
+// CHECK: %[[FLAGS:.*]] = llvm.mlir.constant(33554433 : i64) : i64
+// CHECK: llvm.store %[[FLAGS]], %{{.*}} : i64, !llvm.ptr
+// CHECK: llvm.call @__tgt_acc_data_begin
+// CHECK: %[[FLAGS_END:.*]] = llvm.mlir.constant(33554433 : i64) : i64
+// CHECK: llvm.store %[[FLAGS_END]], %{{.*}} : i64, !llvm.ptr
+// CHECK: llvm.call @__tgt_acc_data_end
+func.func @no_device_descriptor(%arg0: !llvm.ptr) {
+ %map = acc.copyin varPtr(%arg0 : !llvm.ptr) varType(i32)
+ dataClause(acc_copyin) -> !llvm.ptr {acc.no_device_descriptor}
+ acc.data dataOperands(%map : !llvm.ptr) {
+ acc.terminator
+ }
+ acc.delete accPtr(%map : !llvm.ptr) dataClause(acc_copyin)
+ return
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/232064
More information about the Mlir-commits
mailing list