-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[flang][acc] Update FIR ref, heap, and pointer to be MappableType #147834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The MappableType OpenACC type interface is a richer interface that allows OpenACC dialect to be capable to better interact with a source dialect, FIR in this case. fir.box and fir.class types already implemented this interface. Now the same is being done with the other FIR types that represent variables. One additional notable change is that fir.array no longer implements this interface. This is because MappableType is primarily intended for variables - and FIR variables of this type have storage associated and thus there's a pointer-like type (fir.ref/heap/pointer) that holds the array type. The end goal of promoting these FIR types to MappableType is that we will soon implement ability to generate recipes outside of the frontend via this interface.
@llvm/pr-subscribers-mlir-openacc @llvm/pr-subscribers-flang-fir-hlfir Author: Razvan Lupusoru (razvanlupusoru) ChangesThe MappableType OpenACC type interface is a richer interface that allows OpenACC dialect to be capable to better interact with a source dialect, FIR in this case. fir.box and fir.class types already implemented this interface. Now the same is being done with the other FIR types that represent variables. One additional notable change is that fir.array no longer implements this interface. This is because MappableType is primarily intended for variables - and FIR variables of this type have storage associated and thus there's a pointer-like type (fir.ref/heap/pointer) that holds the array type. The end goal of promoting these FIR types to MappableType is that we will soon implement ability to generate recipes outside of the frontend via this interface. Patch is 35.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/147834.diff 9 Files Affected:
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index e56d7f7ed9b6f..387b0c67952a7 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -164,14 +164,13 @@ createDataEntryOp(fir::FirOpBuilder &builder, mlir::Location loc,
op.setStructured(structured);
op.setImplicit(implicit);
op.setDataClause(dataClause);
- if (auto mappableTy =
- mlir::dyn_cast<mlir::acc::MappableType>(baseAddr.getType())) {
- op.setVarType(baseAddr.getType());
+ if (auto pointerLikeTy =
+ mlir::dyn_cast<mlir::acc::PointerLikeType>(baseAddr.getType())) {
+ op.setVarType(pointerLikeTy.getElementType());
} else {
- assert(mlir::isa<mlir::acc::PointerLikeType>(baseAddr.getType()) &&
- "expected pointer-like");
- op.setVarType(mlir::cast<mlir::acc::PointerLikeType>(baseAddr.getType())
- .getElementType());
+ assert(mlir::isa<mlir::acc::MappableType>(baseAddr.getType()) &&
+ "expected mappable");
+ op.setVarType(baseAddr.getType());
}
op->setAttr(Op::getOperandSegmentSizeAttr(),
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 2ff1d6d945ba3..4a9579cfde37c 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -1533,7 +1533,9 @@ std::optional<std::pair<uint64_t, unsigned short>>
fir::getTypeSizeAndAlignment(mlir::Location loc, mlir::Type ty,
const mlir::DataLayout &dl,
const fir::KindMapping &kindMap) {
- if (mlir::isa<mlir::IntegerType, mlir::FloatType, mlir::ComplexType>(ty)) {
+ if (ty.isIntOrIndexOrFloat() ||
+ mlir::isa<mlir::ComplexType, mlir::VectorType,
+ mlir::DataLayoutTypeInterface>(ty)) {
llvm::TypeSize size = dl.getTypeSize(ty);
unsigned short alignment = dl.getTypeABIAlignment(ty);
return std::pair{size, alignment};
diff --git a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
index 317a41a2129c3..0767733f53728 100644
--- a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
@@ -29,8 +29,9 @@
namespace fir::acc {
-static mlir::TypedValue<mlir::acc::PointerLikeType>
-getPtrFromVar(mlir::Value var) {
+template <typename Ty>
+mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<Ty>::getVarPtr(mlir::Type type, mlir::Value var) const {
if (auto ptr =
mlir::dyn_cast<mlir::TypedValue<mlir::acc::PointerLikeType>>(var))
return ptr;
@@ -44,34 +45,51 @@ getPtrFromVar(mlir::Value var) {
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>
+template mlir::TypedValue<mlir::acc::PointerLikeType>
OpenACCMappableModel<fir::BaseBoxType>::getVarPtr(mlir::Type type,
- mlir::Value var) const {
- return getPtrFromVar(var);
-}
+ mlir::Value var) const;
-template <>
-std::optional<llvm::TypeSize>
-OpenACCMappableModel<fir::SequenceType>::getSizeInBytes(
+template mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<fir::ReferenceType>::getVarPtr(mlir::Type type,
+ mlir::Value var) const;
+
+template mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<fir::HeapType>::getVarPtr(mlir::Type type,
+ mlir::Value var) const;
+
+template mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<fir::PointerType>::getVarPtr(mlir::Type type,
+ mlir::Value var) const;
+
+template <typename Ty>
+std::optional<llvm::TypeSize> OpenACCMappableModel<Ty>::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
+ // TODO: Bounds operation affect the size - add support to take them
// into account.
if (!accBounds.empty())
return {};
+ // Class-type is either a polymorphic or unlimited polymorphic. In the latter
+ // case, the size is not computable. But in the former it should be - however,
+ // fir::getTypeSizeAndAlignment does not support polymorphic types.
+ if (mlir::isa<fir::ClassType>(type)) {
+ return {};
+ }
+
+ // When requesting the size of a box entity or a reference, the intent
+ // is to get the size of the data that it is referring to.
+ mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(type);
+ assert(eleTy && "expect to be able to unwrap the element type");
+
+ // If the type enclosed is a mappable type, then have it provide the size.
+ if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(eleTy))
+ return mappableTy.getSizeInBytes(var, accBounds, dataLayout);
+
// 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())
+ auto seqType = mlir::dyn_cast<fir::SequenceType>(eleTy);
+ if (seqType && (seqType.hasDynamicExtents() || seqType.hasUnknownShape()))
return {};
// Attempt to find an operation that a lookup for KindMapping can be done
@@ -85,99 +103,113 @@ OpenACCMappableModel<fir::SequenceType>::getSizeInBytes(
auto kindMap = fir::getKindMapping(kindMapSrcOp);
auto sizeAndAlignment =
- fir::getTypeSizeAndAlignment(var.getLoc(), type, dataLayout, kindMap);
+ fir::getTypeSizeAndAlignment(var.getLoc(), eleTy, dataLayout, kindMap);
if (!sizeAndAlignment.has_value())
return {};
return {llvm::TypeSize::getFixed(sizeAndAlignment->first)};
}
-template <>
-std::optional<llvm::TypeSize>
+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 {};
-}
+ const mlir::DataLayout &dataLayout) const;
-template <>
-std::optional<int64_t>
-OpenACCMappableModel<fir::SequenceType>::getOffsetInBytes(
+template std::optional<llvm::TypeSize>
+OpenACCMappableModel<fir::ReferenceType>::getSizeInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+template std::optional<llvm::TypeSize>
+OpenACCMappableModel<fir::HeapType>::getSizeInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+template std::optional<llvm::TypeSize>
+OpenACCMappableModel<fir::PointerType>::getSizeInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+template <typename Ty>
+std::optional<int64_t> OpenACCMappableModel<Ty>::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
+ // TODO: Bounds operation affect the offset - add support to take them
// into account.
if (!accBounds.empty())
return {};
+ // Class-type does not behave like a normal box because it does not hold an
+ // element type. Thus special handle it here.
+ if (mlir::isa<fir::ClassType>(type)) {
+ // The pointer to the class-type is always at the start address.
+ return {0};
+ }
+
+ mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(type);
+ assert(eleTy && "expect to be able to unwrap the element type");
+
+ // If the type enclosed is a mappable type, then have it provide the offset.
+ if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(eleTy))
+ return mappableTy.getOffsetInBytes(var, accBounds, dataLayout);
+
// 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())
+ auto seqType = mlir::dyn_cast<fir::SequenceType>(eleTy);
+ if (seqType && (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 the size is computable and since there are no bounds or dynamic extents,
+ // then the offset relative to pointer must be zero.
if (getSizeInBytes(type, var, accBounds, dataLayout).has_value()) {
return {0};
}
+
+ // The offset is not evident because it is relative to the pointer being held.
+ // And we don't have any further details about this type.
return {};
}
-template <>
-std::optional<int64_t> OpenACCMappableModel<fir::BaseBoxType>::getOffsetInBytes(
+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 {};
-}
+ const mlir::DataLayout &dataLayout) const;
-template <>
-llvm::SmallVector<mlir::Value>
-OpenACCMappableModel<fir::SequenceType>::generateAccBounds(
- mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const {
+template std::optional<int64_t>
+OpenACCMappableModel<fir::ReferenceType>::getOffsetInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+template std::optional<int64_t>
+OpenACCMappableModel<fir::HeapType>::getOffsetInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+template std::optional<int64_t>
+OpenACCMappableModel<fir::PointerType>::getOffsetInBytes(
+ mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+ const mlir::DataLayout &dataLayout) const;
+
+static llvm::SmallVector<mlir::Value>
+generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
+ mlir::OpBuilder &builder) {
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::dyn_cast_if_present<fir::BoxAddrOp>(var.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)) {
+ if (auto boxPtr = mlir::cast<mlir::acc::MappableType>(box.getType())
+ .getVarPtr(box)) {
boxRef = boxPtr;
}
// TODO: Handle Fortran optional.
@@ -189,7 +221,7 @@ OpenACCMappableModel<fir::SequenceType>::generateAccBounds(
firBuilder, loc, exv, info);
}
- if (mlir::isa<hlfir::DeclareOp, fir::DeclareOp>(varPtr.getDefiningOp())) {
+ if (mlir::isa<hlfir::DeclareOp, fir::DeclareOp>(var.getDefiningOp())) {
mlir::Value zero =
firBuilder.createIntegerConstant(loc, builder.getIndexType(), 0);
mlir::Value one =
@@ -197,10 +229,10 @@ OpenACCMappableModel<fir::SequenceType>::generateAccBounds(
mlir::Value shape;
if (auto declareOp =
- mlir::dyn_cast_if_present<fir::DeclareOp>(varPtr.getDefiningOp()))
+ mlir::dyn_cast_if_present<fir::DeclareOp>(var.getDefiningOp()))
shape = declareOp.getShape();
else if (auto declareOp = mlir::dyn_cast_if_present<hlfir::DeclareOp>(
- varPtr.getDefiningOp()))
+ var.getDefiningOp()))
shape = declareOp.getShape();
const bool strideIncludeLowerExtent = true;
@@ -265,9 +297,9 @@ OpenACCMappableModel<fir::SequenceType>::generateAccBounds(
// TODO: Detect assumed-size case.
const bool isAssumedSize = false;
- auto valToCheck = varPtr;
+ auto valToCheck = var;
if (auto boxAddr =
- mlir::dyn_cast_if_present<fir::BoxAddrOp>(varPtr.getDefiningOp())) {
+ mlir::dyn_cast_if_present<fir::BoxAddrOp>(var.getDefiningOp())) {
valToCheck = boxAddr.getVal();
}
auto res = hlfir::translateToExtendedValue(loc, firBuilder,
@@ -279,86 +311,34 @@ OpenACCMappableModel<fir::SequenceType>::generateAccBounds(
/*isAssumedSize=*/isAssumedSize);
}
-template <>
+template <typename Ty>
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);
- }
+OpenACCMappableModel<Ty>::generateAccBounds(mlir::Type type, mlir::Value var,
+ mlir::OpBuilder &builder) const {
+ // acc bounds only make sense for arrays - thus look for sequence type.
+ mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(type);
+ if (auto seqTy = mlir::dyn_cast_if_present<fir::SequenceType>(eleTy)) {
+ return generateSeqTyAccBounds(seqTy, var, builder);
}
- // Box references are not arrays - thus generating acc.bounds does not make
- // sense.
- return {};
-}
-
-static bool isScalarLike(mlir::Type type) {
- return fir::isa_trivial(type) || fir::isa_ref_type(type);
-}
-
-static bool isArrayLike(mlir::Type type) {
- return mlir::isa<fir::SequenceType>(type);
-}
-static bool isCompositeLike(mlir::Type type) {
- // class(*) is not a composite type since it does not have a determined type.
- if (fir::isUnlimitedPolymorphicType(type))
- return false;
-
- return mlir::isa<fir::RecordType, fir::ClassType, mlir::TupleType>(type);
-}
-
-template <>
-mlir::acc::VariableTypeCategory
-OpenACCMappableModel<fir::SequenceType>::getTypeCategory(
- mlir::Type type, mlir::Value var) const {
- return mlir::acc::VariableTypeCategory::array;
+ return {};
}
-template <>
-mlir::acc::VariableTypeCategory
-OpenACCMappableModel<fir::BaseBoxType>::getTypeCategory(mlir::Type type,
- mlir::Value var) const {
- // Class-type does not behave like a normal box because it does not hold an
- // element type. Thus special handle it here.
- if (mlir::isa<fir::ClassType>(type)) {
- // class(*) is not a composite type since it does not have a determined
- // type.
- if (fir::isUnlimitedPolymorphicType(type))
- return mlir::acc::VariableTypeCategory::uncategorized;
- return mlir::acc::VariableTypeCategory::composite;
- }
-
- mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(type);
- assert(eleTy && "expect to be able to unwrap the element type");
+template llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::BaseBoxType>::generateAccBounds(
+ mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const;
- // If the type enclosed by the box is a mappable type, then have it
- // provide the type category.
- if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(eleTy))
- return mappableTy.getTypeCategory(var);
+template llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::ReferenceType>::generateAccBounds(
+ mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const;
- // For all arrays, despite whether they are allocatable, pointer, assumed,
- // etc, we'd like to categorize them as "array".
- if (isArrayLike(eleTy))
- return mlir::acc::VariableTypeCategory::array;
-
- // We got here because we don't have an array nor a mappable type. At this
- // point, we know we have a type that fits the "aggregate" definition since it
- // is a type with a descriptor. Try to refine it by checking if it matches the
- // "composite" definition.
- if (isCompositeLike(eleTy))
- return mlir::acc::VariableTypeCategory::composite;
+template llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::HeapType>::generateAccBounds(
+ mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const;
- // Even if we have a scalar type - simply because it is wrapped in a box
- // we want to categorize it as "nonscalar". Anything else would've been
- // non-scalar anyway.
- return mlir::acc::VariableTypeCategory::nonscalar;
-}
+template llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::PointerType>::generateAccBounds(
+ mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const;
static mlir::Value
getBaseRef(mlir::TypedValue<mlir::acc::PointerLikeType> varPtr) {
@@ -389,33 +369,44 @@ getBaseRef(mlir::TypedValue<mlir::acc::PointerLikeType> varPtr) {
return baseRef;
}
-static mlir::acc::VariableTypeCategory
-categorizePointee(mlir::Type pointer,
- mlir::TypedValue<mlir::acc::PointerLikeType> varPtr,
- mlir::Type varType) {
- // FIR uses operations to compute interior pointers.
- // So for example, an array element or composite field access to a float
- // value would both be represented as !fir.ref<f32>. We do not want to treat
- // such a reference as a scalar. Thus unwrap interior pointer calculations.
- auto baseRef = getBaseRef(varPtr);
+static bool isScalarLike(mlir::Type type) {
+ return fir::isa_trivial(type) || fir::isa_ref_type(type);
+}
- if (auto mappableTy =
- mlir::dyn_cast<mlir::acc::MappableType>(baseRef.getType()))
- return mappableTy.getTypeCategory(baseRef);
+static bool isArrayLike(mlir::Type type) {
+ return mlir::isa<fir::SequenceType>(type);
+}
- // It must be a pointer-like type since it is not a MappableType.
- auto ptrLikeTy = mlir::cast<mlir::acc::PointerLikeType>(baseRef.getType());
- mlir::Type eleTy = ptrLikeTy.getElementType();
+static bool isCompositeLike(mlir::Type type) {
+ // class(*) is not a composite type since it does not have a determined type.
+ if (fir::isUnlimitedPolymorphicType(type))
+ return false;
- if (auto mappableEleTy = mlir::dyn_cast<mlir::acc::MappableType>(eleTy))
- return mappableEleTy.getTypeCategory(varPtr);
+ return mlir::isa<fir::RecordTy...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice change! LGTM.
I just had a comment on unlimited polymorphic entity but I'm not sure it is applicable.
The MappableType OpenACC type interface is a richer interface that allows OpenACC dialect to be capable to better interact with a source dialect, FIR in this case. fir.box and fir.class types already implemented this interface. Now the same is being done with the other FIR types that represent variables.
One additional notable change is that fir.array no longer implements this interface. This is because MappableType is primarily intended for variables - and FIR variables of this type have storage associated and thus there's a pointer-like type (fir.ref/heap/pointer) that holds the array type.
The end goal of promoting these FIR types to MappableType is that we will soon implement ability to generate recipes outside of the frontend via this interface.