[flang-commits] [flang] [flang][acc] Implement MappableType interfaces for fir.box and fir.array (PR #122495)
via flang-commits
flang-commits at lists.llvm.org
Fri Jan 10 08:59:42 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-driver
@llvm/pr-subscribers-flang-fir-hlfir
Author: Razvan Lupusoru (razvanlupusoru)
<details>
<summary>Changes</summary>
The newly introduced MappableType interface in `acc` dialect was primarily intended to allow variables with non-materialized storage to be used in acc data clauses (previously everything was required to be `pointer-like`). One motivator for this was `fir.box` since it is possible to be passed to functions without a wrapping `fir.ref` and also it can be generated directly via operations like `fir.embox` - and unlike other variable representations in FIR, the underlying storage for it does not get materialized until LLVM codegen.
The new interface is being attached to both `fir.box` and `fir.array`. Strictly speaking, attaching to the latter is primarily for consistency since the MappableType interface requires implementation of utilities to compute byte size - and it made sense that a
`fir.box<fir.array<10xi32>>` and `fir.array<10xi32>` would have a consistently computable size. This decision may be revisited as MappableType interface evolves.
The new interface attachments are made in a new library named `FIROpenACCSupport`. The reason for this is to avoid circular dependencies since the implementation of this library is reusing code from lowering of OpenACC. More specifically, the types are defined in `FIRDialect` and `FortranLower` depends on it. Thus we cannot attach these interfaces in `FIRDialect`.
---
Patch is 24.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/122495.diff
17 Files Affected:
- (added) flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h (+43)
- (added) flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h (+22)
- (modified) flang/include/flang/Optimizer/Support/InitFIR.h (+2)
- (modified) flang/lib/Frontend/CMakeLists.txt (+1)
- (modified) flang/lib/Optimizer/CMakeLists.txt (+1)
- (modified) flang/lib/Optimizer/Dialect/CMakeLists.txt (+1-1)
- (added) flang/lib/Optimizer/OpenACC/CMakeLists.txt (+22)
- (added) flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp (+221)
- (added) flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp (+28)
- (added) flang/test/Fir/OpenACC/openacc-mappable.fir (+25)
- (modified) flang/test/lib/CMakeLists.txt (+1)
- (added) flang/test/lib/OpenACC/CMakeLists.txt (+21)
- (added) flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp (+85)
- (modified) flang/tools/fir-lsp-server/CMakeLists.txt (+1)
- (modified) flang/tools/fir-opt/CMakeLists.txt (+2)
- (modified) flang/tools/fir-opt/fir-opt.cpp (+2)
- (modified) flang/tools/tco/CMakeLists.txt (+1)
``````````diff
diff --git a/flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h b/flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h
new file mode 100644
index 00000000000000..c1bea32a22361d
--- /dev/null
+++ b/flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h
@@ -0,0 +1,43 @@
+//===- FIROpenACCTypeInterfaces.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains external dialect interfaces for FIR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FLANG_OPTIMIZER_OPENACC_FIROPENACCTYPEINTERFACES_H_
+#define FLANG_OPTIMIZER_OPENACC_FIROPENACCTYPEINTERFACES_H_
+
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+
+namespace fir::acc {
+
+template <typename T>
+struct OpenACCMappableModel
+ : public mlir::acc::MappableType::ExternalModel<OpenACCMappableModel<T>,
+ T> {
+ mlir::TypedValue<mlir::acc::PointerLikeType> getVarPtr(::mlir::Type type,
+ mlir::Value var) const;
+
+ std::optional<llvm::TypeSize>
+ getSizeInBytes(mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+ std::optional<int64_t>
+ getOffsetInBytes(mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+ llvm::SmallVector<mlir::Value>
+ generateAccBounds(mlir::Type type, mlir::Value var,
+ mlir::OpBuilder &builder) const;
+};
+
+} // namespace fir::acc
+
+#endif // FLANG_OPTIMIZER_OPENACC_FIROPENACCTYPEINTERFACES_H_
diff --git a/flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h b/flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h
new file mode 100644
index 00000000000000..efaddd72ebbf2b
--- /dev/null
+++ b/flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h
@@ -0,0 +1,22 @@
+//===- RegisterOpenACCExtensions.h - OpenACC Extension Registration --===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FLANG_OPTIMIZER_OPENACC_REGISTEROPENACCEXTENSIONS_H_
+#define FLANG_OPTIMIZER_OPENACC_REGISTEROPENACCEXTENSIONS_H_
+
+namespace mlir {
+class DialectRegistry;
+} // namespace mlir
+
+namespace fir::acc {
+
+void registerOpenACCExtensions(mlir::DialectRegistry ®istry);
+
+} // namespace fir::acc
+
+#endif // FLANG_OPTIMIZER_OPENACC_REGISTEROPENACCEXTENSIONS_H_
diff --git a/flang/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h
index 1c61c367199923..94995ac6136edd 100644
--- a/flang/include/flang/Optimizer/Support/InitFIR.h
+++ b/flang/include/flang/Optimizer/Support/InitFIR.h
@@ -17,6 +17,7 @@
#include "flang/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
+#include "flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h"
#include "mlir/Conversion/Passes.h"
#include "mlir/Dialect/Affine/Passes.h"
#include "mlir/Dialect/Complex/IR/Complex.h"
@@ -63,6 +64,7 @@ inline void addFIRExtensions(mlir::DialectRegistry ®istry,
addFIRInlinerExtension(registry);
addFIRToLLVMIRExtension(registry);
cuf::registerCUFDialectTranslation(registry);
+ fir::acc::registerOpenACCExtensions(registry);
}
inline void loadNonCodegenDialects(mlir::MLIRContext &context) {
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index e954800c3b88b0..f00566d7791575 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -38,6 +38,7 @@ add_flang_library(flangFrontend
HLFIRDialect
HLFIRTransforms
flangPasses
+ FIROpenACCSupport
FlangOpenMPTransforms
MLIRTransforms
MLIRBuiltinToLLVMIRTranslation
diff --git a/flang/lib/Optimizer/CMakeLists.txt b/flang/lib/Optimizer/CMakeLists.txt
index 5354d7181e6516..72aba51b858708 100644
--- a/flang/lib/Optimizer/CMakeLists.txt
+++ b/flang/lib/Optimizer/CMakeLists.txt
@@ -3,6 +3,7 @@ add_subdirectory(Builder)
add_subdirectory(CodeGen)
add_subdirectory(Dialect)
add_subdirectory(HLFIR)
+add_subdirectory(OpenACC)
add_subdirectory(OpenMP)
add_subdirectory(Passes)
add_subdirectory(Support)
diff --git a/flang/lib/Optimizer/Dialect/CMakeLists.txt b/flang/lib/Optimizer/Dialect/CMakeLists.txt
index a8235f841b879d..08caa15700d4ca 100644
--- a/flang/lib/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/lib/Optimizer/Dialect/CMakeLists.txt
@@ -6,8 +6,8 @@ add_flang_library(FIRDialect
FIRDialect.cpp
FIROps.cpp
FIRType.cpp
- FortranVariableInterface.cpp
FirAliasTagOpInterface.cpp
+ FortranVariableInterface.cpp
Inliner.cpp
DEPENDS
diff --git a/flang/lib/Optimizer/OpenACC/CMakeLists.txt b/flang/lib/Optimizer/OpenACC/CMakeLists.txt
new file mode 100644
index 00000000000000..ed673121353c16
--- /dev/null
+++ b/flang/lib/Optimizer/OpenACC/CMakeLists.txt
@@ -0,0 +1,22 @@
+get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
+
+add_flang_library(FIROpenACCSupport
+ FIROpenACCTypeInterfaces.cpp
+ RegisterOpenACCExtensions.cpp
+
+ DEPENDS
+ FIRBuilder
+ FIRDialect
+ FIRDialectSupport
+ FIRSupport
+ HLFIRDialect
+ MLIROpenACCDialect
+
+ LINK_LIBS
+ FIRBuilder
+ FIRDialect
+ FIRDialectSupport
+ FIRSupport
+ HLFIRDialect
+ MLIROpenACCDialect
+)
diff --git a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
new file mode 100644
index 00000000000000..ebcc54add0ed12
--- /dev/null
+++ b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
@@ -0,0 +1,221 @@
+//===-- FIROpenACCTypeInterfaces.cpp --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of external dialect interfaces for FIR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h"
+#include "flang/Lower/DirectivesCommon.h"
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/Support/FIRContext.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Support/LLVM.h"
+
+namespace fir::acc {
+
+static mlir::TypedValue<mlir::acc::PointerLikeType>
+getPtrFromVar(mlir::Value var) {
+ if (auto ptr =
+ mlir::dyn_cast<mlir::TypedValue<mlir::acc::PointerLikeType>>(var))
+ return ptr;
+
+ if (auto load = mlir::dyn_cast_if_present<fir::LoadOp>(var.getDefiningOp())) {
+ // All FIR reference types implement the PointerLikeType interface.
+ return mlir::cast<mlir::TypedValue<mlir::acc::PointerLikeType>>(
+ load.getMemref());
+ }
+
+ return {};
+}
+
+template <>
+mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<fir::SequenceType>::getVarPtr(mlir::Type type,
+ mlir::Value var) const {
+ return getPtrFromVar(var);
+}
+
+template <>
+mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<fir::BaseBoxType>::getVarPtr(mlir::Type type,
+ mlir::Value var) const {
+ return getPtrFromVar(var);
+}
+
+template <>
+std::optional<llvm::TypeSize>
+OpenACCMappableModel<fir::SequenceType>::getSizeInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const {
+ // TODO: Bounds operation affect the total size - add support to take them
+ // into account.
+ if (!accBounds.empty())
+ return {};
+
+ // Dynamic extents or unknown ranks generally do not have compile-time
+ // computable dimensions.
+ auto seqType = mlir::cast<fir::SequenceType>(type);
+ if (seqType.hasDynamicExtents() || seqType.hasUnknownShape())
+ return {};
+
+ // Without a defining op, cannot look up appropriate kindMapping for the
+ // current context.
+ if (!var.getDefiningOp())
+ return {};
+ auto kindMap = fir::getKindMapping(var.getDefiningOp());
+ auto sizeAndAlignment =
+ fir::getTypeSizeAndAlignment(var.getLoc(), type, dataLayout, kindMap);
+ if (!sizeAndAlignment.has_value())
+ return {};
+
+ return {llvm::TypeSize::getFixed(sizeAndAlignment->first)};
+}
+
+template <>
+std::optional<llvm::TypeSize>
+OpenACCMappableModel<fir::BaseBoxType>::getSizeInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const {
+ // If we have a box value instead of box reference, the intent is to
+ // get the size of the data not the box itself.
+ if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType())) {
+ if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(
+ fir::unwrapRefType(boxTy.getEleTy()))) {
+ return mappableTy.getSizeInBytes(var, accBounds, dataLayout);
+ }
+ }
+ // Size for boxes is not computable until it gets materialized.
+ return {};
+}
+
+template <>
+std::optional<int64_t>
+OpenACCMappableModel<fir::SequenceType>::getOffsetInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const {
+ // TODO: Bounds operation affect the offset- add support to take them
+ // into account.
+ if (!accBounds.empty())
+ return {};
+
+ // Dynamic extents (aka descriptor-based arrays) - may have a offset.
+ // For example, a negative stride may mean a negative offset to compute the
+ // start of array.
+ auto seqType = mlir::cast<fir::SequenceType>(type);
+ if (seqType.hasDynamicExtents() || seqType.hasUnknownShape())
+ return {};
+
+ // We have non-dynamic extents - but if for some reason the size is not
+ // computable - assume offset is not either. Otherwise, it is an offset of
+ // zero.
+ if (getSizeInBytes(type, var, accBounds, dataLayout).has_value()) {
+ return {0};
+ }
+ return {};
+}
+
+template <>
+std::optional<int64_t> OpenACCMappableModel<fir::BaseBoxType>::getOffsetInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const {
+ // If we have a box value instead of box reference, the intent is to
+ // get the offset of the data not the offset of the box itself.
+ if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType())) {
+ if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(
+ fir::unwrapRefType(boxTy.getEleTy()))) {
+ return mappableTy.getOffsetInBytes(var, accBounds, dataLayout);
+ }
+ }
+ // Until boxes get materialized, the offset is not evident because it is
+ // relative to the pointer being held.
+ return {};
+}
+
+template <>
+llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::SequenceType>::generateAccBounds(
+ mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const {
+ assert((mlir::isa<mlir::acc::PointerLikeType>(var.getType()) ||
+ mlir::isa<mlir::acc::MappableType>(var.getType())) &&
+ "must be pointer-like or mappable");
+
+ fir::FirOpBuilder firBuilder(builder, var.getDefiningOp());
+ auto seqType = mlir::cast<fir::SequenceType>(type);
+ mlir::Location loc = var.getLoc();
+
+ mlir::Value varPtr =
+ mlir::isa<mlir::acc::PointerLikeType>(var.getType())
+ ? var
+ : mlir::cast<mlir::acc::MappableType>(var.getType()).getVarPtr(var);
+
+ if (seqType.hasDynamicExtents() || seqType.hasUnknownShape()) {
+ if (auto boxAddr =
+ mlir::dyn_cast_if_present<fir::BoxAddrOp>(varPtr.getDefiningOp())) {
+ mlir::Value box = boxAddr.getVal();
+ auto res =
+ hlfir::translateToExtendedValue(loc, firBuilder, hlfir::Entity(box));
+ fir::ExtendedValue exv = res.first;
+ mlir::Value boxRef = box;
+ if (auto boxPtr = getPtrFromVar(box)) {
+ boxRef = boxPtr;
+ }
+ // TODO: Handle Fortran optional.
+ const mlir::Value isPresent;
+ Fortran::lower::AddrAndBoundsInfo info(box, boxRef, isPresent,
+ box.getType());
+ return Fortran::lower::genBoundsOpsFromBox<mlir::acc::DataBoundsOp,
+ mlir::acc::DataBoundsType>(
+ firBuilder, loc, exv, info);
+ }
+ assert(false && "array with unknown dimension expected to have descriptor");
+ return {};
+ }
+
+ // TODO: Detect assumed-size case.
+ const bool isAssumedSize = false;
+ auto valToCheck = varPtr;
+ if (auto boxAddr =
+ mlir::dyn_cast_if_present<fir::BoxAddrOp>(varPtr.getDefiningOp())) {
+ valToCheck = boxAddr.getVal();
+ }
+ auto res = hlfir::translateToExtendedValue(loc, firBuilder,
+ hlfir::Entity(valToCheck));
+ fir::ExtendedValue exv = res.first;
+ return Fortran::lower::genBaseBoundsOps<mlir::acc::DataBoundsOp,
+ mlir::acc::DataBoundsType>(
+ firBuilder, loc, exv,
+ /*isAssumedSize=*/isAssumedSize);
+}
+
+template <>
+llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::BaseBoxType>::generateAccBounds(
+ mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const {
+ // If we have a box value instead of box reference, the intent is to
+ // get the bounds of the data not the bounds of the box itself.
+ if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType())) {
+ if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(
+ fir::unwrapRefType(boxTy.getEleTy()))) {
+ mlir::Value data = builder.create<fir::BoxAddrOp>(var.getLoc(), var);
+ return mappableTy.generateAccBounds(data, builder);
+ }
+ }
+ // Box references are not arrays - thus generating acc.bounds does not make
+ // sense.
+ return {};
+}
+
+} // namespace fir::acc
diff --git a/flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp b/flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp
new file mode 100644
index 00000000000000..34ea122f6b997d
--- /dev/null
+++ b/flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp
@@ -0,0 +1,28 @@
+//===-- RegisterOpenACCExtensions.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Registration for OpenACC extensions as applied to FIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h"
+
+namespace fir::acc {
+void registerOpenACCExtensions(mlir::DialectRegistry ®istry) {
+ registry.addExtension(+[](mlir::MLIRContext *ctx,
+ fir::FIROpsDialect *dialect) {
+ fir::SequenceType::attachInterface<OpenACCMappableModel<fir::SequenceType>>(
+ *ctx);
+ fir::BoxType::attachInterface<OpenACCMappableModel<fir::BaseBoxType>>(*ctx);
+ });
+}
+
+} // namespace fir::acc
diff --git a/flang/test/Fir/OpenACC/openacc-mappable.fir b/flang/test/Fir/OpenACC/openacc-mappable.fir
new file mode 100644
index 00000000000000..438cb29b991c7d
--- /dev/null
+++ b/flang/test/Fir/OpenACC/openacc-mappable.fir
@@ -0,0 +1,25 @@
+// Use --mlir-disable-threading so that the diagnostic printing is serialized.
+// RUN: fir-opt %s -pass-pipeline='builtin.module(test-fir-openacc-interfaces)' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<f16 = dense<16> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, "dlti.endianness" = "little", "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"} {
+ func.func @_QPsub() {
+ %c2 = arith.constant 2 : index
+ %c10 = arith.constant 10 : index
+ %0 = fir.alloca !fir.array<10xf32> {bindc_name = "arr", uniq_name = "_QFsubEarr"}
+ %1 = fir.shape_shift %c2, %c10 : (index, index) -> !fir.shapeshift<1>
+ %2 = fir.declare %0(%1) {uniq_name = "_QFsubEarr"} : (!fir.ref<!fir.array<10xf32>>, !fir.shapeshift<1>) -> !fir.ref<!fir.array<10xf32>>
+ %3 = fir.embox %2(%1) : (!fir.ref<!fir.array<10xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xf32>>
+ %4 = fir.box_addr %3 : (!fir.box<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>>
+ %5 = acc.copyin var(%3 : !fir.box<!fir.array<10xf32>>) -> !fir.box<!fir.array<10xf32>> {name = "arr", structured = false}
+ %6 = acc.copyin varPtr(%4 : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "arr", structured = false}
+ acc.enter_data dataOperands(%5, %6 : !fir.box<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+ return
+ }
+}
+
+// CHECK: Visiting: %{{.*}} = acc.copyin var(%{{.*}} : !fir.box<!fir.array<10xf32>>) -> !fir.box<!fir.array<10xf32>> {name = "arr", structured = false}
+// CHECK: Mappable: !fir.box<!fir.array<10xf32>>
+// CHECK: Size: 40
+// CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "arr", structured = false}
+// CHECK: Mappable: !fir.array<10xf32>
+// CHECK: Size: 40
diff --git a/flang/test/lib/CMakeLists.txt b/flang/test/lib/CMakeLists.txt
index fc6ef10fab1f5a..96f4c9513b11a5 100644
--- a/flang/test/lib/CMakeLists.txt
+++ b/flang/test/lib/CMakeLists.txt
@@ -1 +1,2 @@
add_subdirectory(Analysis)
+add_subdirectory(OpenACC)
diff --git a/flang/test/lib/OpenACC/CMakeLists.txt b/flang/test/lib/OpenACC/CMakeLists.txt
new file mode 100644
index 00000000000000..54a81373d253fa
--- /dev/null
+++ b/flang/test/lib/OpenACC/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_flang_library(FIRTestOpenACCInterfaces
+ TestOpenACCInterfaces.cpp
+
+ DEPENDS
+ FIRDialect
+ FIRBuilder
+ FIROpenACCSupport
+ FIRSupport
+ FIRTransforms
+ MLIROpenACCDialect
+
+ LINK_LIBS
+ FIRDialect
+ FIRBuilder
+ FIROpenACCSupport
+ FIRSupport
+ MLIRIR
+ MLIROpenACCDialect
+ MLIRSupport
+ MLIRFuncDialect
+)
diff --git a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
new file mode 100644
index 00000000000000..a01396748f4c2c
--- /dev/null
+++ b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
@@ -0,0 +1,85 @@
+//===- TestOpenACCInterfaces.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--------------------------------...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/122495
More information about the flang-commits
mailing list