[Mlir-commits] [mlir] [acc] add RegionBranchTerminatorOpInterface to acc.terminator (PR #174165)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Jan 1 15:14:14 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-openacc
Author: Susan Tan (ス-ザン タン) (SusanTan)
<details>
<summary>Changes</summary>
This further helps with propagation in data flow analysis through acc regions
---
Full diff: https://github.com/llvm/llvm-project/pull/174165.diff
3 Files Affected:
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td (+4-1)
- (modified) mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp (+10)
- (modified) mlir/test/Dialect/OpenACC/region-branchop-interface.mlir (+4-39)
``````````diff
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
index 14902730ba165..2375104eadb85 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -2364,7 +2364,10 @@ def OpenACC_DataOp
let hasVerifier = 1;
}
-def OpenACC_TerminatorOp : OpenACC_Op<"terminator", [Pure, Terminator]> {
+def OpenACC_TerminatorOp
+ : OpenACC_Op<"terminator", [Pure, Terminator,
+ DeclareOpInterfaceMethods<
+ RegionBranchTerminatorOpInterface>]> {
let summary = "Generic terminator for OpenACC regions";
let description = [{
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 7f9f2a59f83be..bb8e6881d7d9d 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -463,6 +463,16 @@ void LoopOp::getSuccessorRegions(RegionBranchPoint point,
regions.push_back(RegionSuccessor(getOperation(), getResults()));
}
+//===----------------------------------------------------------------------===//
+// RegionBranchTerminatorOpInterface
+//===----------------------------------------------------------------------===//
+
+MutableOperandRange
+TerminatorOp::getMutableSuccessorOperands(RegionSuccessor /*point*/) {
+ // `acc.terminator` does not forward operands.
+ return MutableOperandRange(getOperation(), /*start=*/0, /*length=*/0);
+}
+
//===----------------------------------------------------------------------===//
// device_type support helpers
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/OpenACC/region-branchop-interface.mlir b/mlir/test/Dialect/OpenACC/region-branchop-interface.mlir
index 28789868fdef9..ea3bf6aec58ec 100644
--- a/mlir/test/Dialect/OpenACC/region-branchop-interface.mlir
+++ b/mlir/test/Dialect/OpenACC/region-branchop-interface.mlir
@@ -2,13 +2,6 @@
// Test that RegionBranchOpInterface implementations for OpenACC single-region
// ops behave reasonably under LastModifiedAnalysis.
-//
-// For acc.parallel / acc.serial, which only have value-based memory effects
-// coming from their bodies, the analysis can track the last writer precisely.
-// For other OpenACC region ops (e.g. acc.kernels, acc.data, acc.host_data),
-// which currently only report resource-only memory effects at the op level,
-// LastModifiedAnalysis cannot attribute a precise last writer and falls back
-// to "<unknown>" after the op for values not directly touched in the region.
// CHECK-LABEL: test_tag: acc_parallel_after:
@@ -63,23 +56,14 @@ func.func @last_mod_openacc_serial(%arg0: memref<f32>) -> memref<f32> {
// CHECK-NEXT: - pre
// CHECK-LABEL: test_tag: acc_kernels_after:
// CHECK: operand #0
-// CHECK-NEXT: - <unknown>
+// CHECK-NEXT: - pre
func.func @last_mod_openacc_kernels(%arg0: memref<f32>) -> memref<f32> {
%zero = arith.constant 0.0 : f32
-
- // Single store before the region.
memref.store %zero, %arg0[] {tag_name = "pre"} : memref<f32>
memref.load %arg0[] {tag = "acc_kernels_before"} : memref<f32>
-
- // The acc.kernels region does not touch %arg0.
acc.kernels {
- "test.openacc_dummy_op"() : () -> ()
acc.terminator
}
-
- // After acc.kernels, LastModifiedAnalysis cannot prove that "pre" still
- // dominates all paths and therefore reports the last modifier conservatively
- // as "<unknown>" for this load.
memref.load %arg0[] {tag = "acc_kernels_after"} : memref<f32>
return %arg0 : memref<f32>
}
@@ -91,24 +75,14 @@ func.func @last_mod_openacc_kernels(%arg0: memref<f32>) -> memref<f32> {
// CHECK-NEXT: - pre
// CHECK-LABEL: test_tag: acc_data_after:
// CHECK: operand #0
-// CHECK-NEXT: - <unknown>
+// CHECK-NEXT: - pre
func.func @last_mod_openacc_data(%arg0: memref<f32>, %mapped: memref<f32>) -> memref<f32> {
%zero = arith.constant 0.0 : f32
-
- // Single store to %arg0 before the region.
memref.store %zero, %arg0[] {tag_name = "pre"} : memref<f32>
memref.load %arg0[] {tag = "acc_data_before"} : memref<f32>
-
- // Map an unrelated buffer into device memory and run an acc.data region that
- // does not touch %arg0.
- %create = acc.create varPtr(%mapped : memref<f32>) varType(tensor<f32>) -> memref<f32>
- acc.data dataOperands(%create : memref<f32>) {
- "test.openacc_dummy_op"() : () -> ()
+ acc.data {
acc.terminator
- }
-
- // After acc.data, LastModifiedAnalysis cannot prove that "pre" still
- // dominates all paths for %arg0 and reports "<unknown>" for this load.
+ } attributes {defaultAttr = #acc<defaultvalue none>}
memref.load %arg0[] {tag = "acc_data_after"} : memref<f32>
return %arg0 : memref<f32>
}
@@ -123,21 +97,12 @@ func.func @last_mod_openacc_data(%arg0: memref<f32>, %mapped: memref<f32>) -> me
// CHECK-NEXT: - <unknown>
func.func @last_mod_openacc_host_data(%arg0: memref<f32>, %mapped: memref<f32>) -> memref<f32> {
%zero = arith.constant 0.0 : f32
-
- // Single store to %arg0 before the region.
memref.store %zero, %arg0[] {tag_name = "pre"} : memref<f32>
memref.load %arg0[] {tag = "acc_host_before"} : memref<f32>
-
- // Map %mapped into device memory and run an acc.host_data region that does
- // not touch %arg0.
%devptr = acc.use_device varPtr(%mapped : memref<f32>) varType(tensor<f32>) -> memref<f32>
acc.host_data dataOperands(%devptr : memref<f32>) {
- "test.openacc_dummy_op"() : () -> ()
acc.terminator
}
-
- // After acc.host_data, the analysis cannot prove "pre" still dominates and
- // reports "<unknown>" for the last writer on %arg0.
memref.load %arg0[] {tag = "acc_host_after"} : memref<f32>
return %arg0 : memref<f32>
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/174165
More information about the Mlir-commits
mailing list