[flang-commits] [flang] 205187c - [openacc][flang] full support to handle allocatable/pointer runtime declare-action calls in ACCDeclareActionConversion (#188055)
via flang-commits
flang-commits at lists.llvm.org
Mon Mar 23 12:50:46 PDT 2026
Author: Susan Tan (ス-ザン タン)
Date: 2026-03-23T19:50:40Z
New Revision: 205187c5cfe318109deb215583edd5434f69c487
URL: https://github.com/llvm/llvm-project/commit/205187c5cfe318109deb215583edd5434f69c487
DIFF: https://github.com/llvm/llvm-project/commit/205187c5cfe318109deb215583edd5434f69c487.diff
LOG: [openacc][flang] full support to handle allocatable/pointer runtime declare-action calls in ACCDeclareActionConversion (#188055)
Supported before: `fir.store`, `fir.box_addr`, and `fir.call` only for
PointerAllocate/PointerDeallocate.
Added now: fir.call support for PointerAllocateSource,
PointerDeallocatePolymorphic, AllocatableAllocate,
AllocatableAllocateSource, AllocatableDeallocate,
AllocatableDeallocatePolymorphic (found in
flang/include/flang/Runtime/allocatable.h).
Added:
Modified:
flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
flang/test/Fir/OpenACC/declare-action-conversion.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp b/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
index 45fff88036b66..0973e18f7241f 100644
--- a/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
+++ b/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
@@ -64,8 +64,10 @@
#include "mlir/IR/Operation.h"
#include "mlir/IR/Value.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Debug.h"
+#include <cassert>
#define DEBUG_TYPE "acc-declare-action-conversion"
@@ -81,10 +83,35 @@ using namespace mlir;
namespace {
// Fortran runtime symbol names for pointer allocate/deallocate.
-static constexpr llvm::StringRef pointerAllocateName =
+static constexpr llvm::StringLiteral pointerAllocateName =
RTNAME_STRING(PointerAllocate);
-static constexpr llvm::StringRef pointerDeallocateName =
+static constexpr llvm::StringLiteral pointerAllocateSourceName =
+ RTNAME_STRING(PointerAllocateSource);
+static constexpr llvm::StringLiteral pointerDeallocateName =
RTNAME_STRING(PointerDeallocate);
+static constexpr llvm::StringLiteral pointerDeallocatePolymorphicName =
+ RTNAME_STRING(PointerDeallocatePolymorphic);
+static constexpr llvm::StringLiteral allocatableAllocateName =
+ RTNAME_STRING(AllocatableAllocate);
+static constexpr llvm::StringLiteral allocatableAllocateSourceName =
+ RTNAME_STRING(AllocatableAllocateSource);
+static constexpr llvm::StringLiteral allocatableDeallocateName =
+ RTNAME_STRING(AllocatableDeallocate);
+static constexpr llvm::StringLiteral allocatableDeallocatePolymorphicName =
+ RTNAME_STRING(AllocatableDeallocatePolymorphic);
+
+static bool isSupportedDeclareActionRuntime(llvm::StringRef funcName) {
+ return llvm::StringSwitch<bool>(funcName)
+ .Case(pointerAllocateName, true)
+ .Case(pointerAllocateSourceName, true)
+ .Case(pointerDeallocateName, true)
+ .Case(pointerDeallocatePolymorphicName, true)
+ .Case(allocatableAllocateName, true)
+ .Case(allocatableAllocateSourceName, true)
+ .Case(allocatableDeallocateName, true)
+ .Case(allocatableDeallocatePolymorphicName, true)
+ .Default(false);
+}
class ACCDeclareActionConversion
: public fir::acc::impl::ACCDeclareActionConversionBase<
@@ -152,16 +179,19 @@ class ACCDeclareActionConversion
if (auto callee = call.getCalleeAttr()) {
StringRef funcName =
callee.getLeafReference().getValue();
- if (funcName == pointerAllocateName ||
- funcName == pointerDeallocateName) {
- auto args = call.getArgs();
- if (args.empty())
- return {};
- Value boxRef = args[0];
- if (!fir::isBoxAddress(boxRef.getType()))
- return {};
- return boxRef;
- }
+ const bool isSupported =
+ isSupportedDeclareActionRuntime(funcName);
+ assert(isSupported && "unexpected fir.call callee for "
+ "acc.declare_action");
+ if (!isSupported)
+ return {};
+ auto args = call.getArgs();
+ if (args.empty())
+ return {};
+ Value boxRef = args[0];
+ if (!fir::isBoxAddress(boxRef.getType()))
+ return {};
+ return boxRef;
}
return {};
})
diff --git a/flang/test/Fir/OpenACC/declare-action-conversion.fir b/flang/test/Fir/OpenACC/declare-action-conversion.fir
index b7f4ce9648ca9..fe54dae0f5fb3 100644
--- a/flang/test/Fir/OpenACC/declare-action-conversion.fir
+++ b/flang/test/Fir/OpenACC/declare-action-conversion.fir
@@ -97,3 +97,77 @@ module {
// CHECK: fir.store
// CHECK: fir.call @_QMmmFsubEarr_acc_declare_update_desc_post_alloc(%[[DECLARE]])
}
+
+// -----
+
+// Test declare_action on additional runtime calls supported by the pass.
+module {
+ func.func private @_QFdeclareAp_acc_declare_post_alloc_source(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) {
+ return
+ }
+ func.func private @_QFdeclareAp_acc_declare_post_dealloc_poly(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) {
+ return
+ }
+ func.func private @_QFdeclareAa_acc_declare_post_alloc(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+ return
+ }
+ func.func private @_QFdeclareAa_acc_declare_post_alloc_source(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+ return
+ }
+ func.func private @_QFdeclareAa_acc_declare_post_dealloc(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+ return
+ }
+ func.func private @_QFdeclareAa_acc_declare_post_dealloc_poly(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+ return
+ }
+
+ func.func @_QPsupported_runtime_calls() {
+ %pbox = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {uniq_name = "_QFdeclareEap"}
+ %pdecl = fir.declare %pbox {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFdeclareEap"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ %pcvt = fir.convert %pdecl : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+
+ %abox = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {uniq_name = "_QFdeclareEaa"}
+ %adecl = fir.declare %abox {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFdeclareEaa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %acvt = fir.convert %adecl : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+
+ %f = arith.constant false
+ %absent = fir.absent !fir.box<none>
+ %s_i8 = fir.zero_bits !fir.ref<i8>
+ %none_ref = fir.zero_bits !fir.ref<none>
+ %c4_i32 = arith.constant 4 : i32
+
+ fir.call @_FortranAPointerAllocateSource(%pcvt, %absent, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postAlloc = @_QFdeclareAp_acc_declare_post_alloc_source>} : (!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ fir.call @_FortranAPointerDeallocatePolymorphic(%pcvt, %none_ref, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postDealloc = @_QFdeclareAp_acc_declare_post_dealloc_poly>} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+
+ fir.call @_FortranAAllocatableAllocate(%acvt, %none_ref, %f, %absent, %s_i8, %c4_i32, %none_ref) {acc.declare_action = #acc.declare_action<postAlloc = @_QFdeclareAa_acc_declare_post_alloc>} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32, !fir.ref<none>) -> i32
+ fir.call @_FortranAAllocatableAllocateSource(%acvt, %absent, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postAlloc = @_QFdeclareAa_acc_declare_post_alloc_source>} : (!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ fir.call @_FortranAAllocatableDeallocate(%acvt, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postDealloc = @_QFdeclareAa_acc_declare_post_dealloc>} : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ fir.call @_FortranAAllocatableDeallocatePolymorphic(%acvt, %none_ref, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postDealloc = @_QFdeclareAa_acc_declare_post_dealloc_poly>} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ return
+ }
+
+// CHECK-LABEL: func.func @_QPsupported_runtime_calls
+// CHECK: %[[PDECL:.*]] = fir.declare %{{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+// CHECK: %[[PCVT:.*]] = fir.convert %[[PDECL]] : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[ADECL:.*]] = fir.declare %{{.*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: %[[ACVT:.*]] = fir.convert %[[ADECL]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: fir.call @_FortranAPointerAllocateSource(%[[PCVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAp_acc_declare_post_alloc_source(%[[PDECL]])
+// CHECK: fir.call @_FortranAPointerDeallocatePolymorphic(%[[PCVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAp_acc_declare_post_dealloc_poly(%[[PDECL]])
+// CHECK: fir.call @_FortranAAllocatableAllocate(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_alloc(%[[ADECL]])
+// CHECK: fir.call @_FortranAAllocatableAllocateSource(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_alloc_source(%[[ADECL]])
+// CHECK: fir.call @_FortranAAllocatableDeallocate(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_dealloc(%[[ADECL]])
+// CHECK: fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_dealloc_poly(%[[ADECL]])
+
+ func.func private @_FortranAPointerAllocateSource(!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ func.func private @_FortranAPointerDeallocatePolymorphic(!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ func.func private @_FortranAAllocatableAllocate(!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32, !fir.ref<none>) -> i32
+ func.func private @_FortranAAllocatableAllocateSource(!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ func.func private @_FortranAAllocatableDeallocate(!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+ func.func private @_FortranAAllocatableDeallocatePolymorphic(!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+}
More information about the flang-commits
mailing list