[flang-commits] [flang] 4fbaefa - [flang][hlfir] Implemented addressing an element of a polymorphic array.
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Tue Jun 6 10:26:17 PDT 2023
Author: Slava Zakharin
Date: 2023-06-06T10:26:02-07:00
New Revision: 4fbaefa246844bd2329712c9dbd20893d4d8f467
URL: https://github.com/llvm/llvm-project/commit/4fbaefa246844bd2329712c9dbd20893d4d8f467
DIFF: https://github.com/llvm/llvm-project/commit/4fbaefa246844bd2329712c9dbd20893d4d8f467.diff
LOG: [flang][hlfir] Implemented addressing an element of a polymorphic array.
The changes convert hlfir.designate to fir.array_coor/fir.embox
to represent a subscripted element of a polymorphic array.
The type information is conveyed via the fir.embox's source_box.
Reviewed By: tblah
Differential Revision: https://reviews.llvm.org/D152200
Added:
Modified:
flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
flang/test/HLFIR/designate-codegen.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index 4964ef9de8dc1..22ad5371543c9 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -373,6 +373,31 @@ class DeclareOpConversion : public mlir::OpRewritePattern<hlfir::DeclareOp> {
class DesignateOpConversion
: public mlir::OpRewritePattern<hlfir::DesignateOp> {
+ // Helper method to generate the coordinate of the first element
+ // of an array section. It is also called for cases of non-section
+ // array element addressing.
+ static mlir::Value genSubscriptBeginAddr(
+ fir::FirOpBuilder &builder, mlir::Location loc,
+ hlfir::DesignateOp designate, mlir::Type baseEleTy, mlir::Value base,
+ mlir::Value shape,
+ const llvm::SmallVector<mlir::Value> &firBaseTypeParameters) {
+ assert(!designate.getIndices().empty());
+ llvm::SmallVector<mlir::Value> firstElementIndices;
+ auto indices = designate.getIndices();
+ int i = 0;
+ for (auto isTriplet : designate.getIsTripletAttr().asArrayRef()) {
+ // Coordinate of the first element are the index and triplets lower
+ // bounds
+ firstElementIndices.push_back(indices[i]);
+ i = i + (isTriplet ? 3 : 1);
+ }
+ mlir::Type arrayCoorType = fir::ReferenceType::get(baseEleTy);
+ base = builder.create<fir::ArrayCoorOp>(
+ loc, arrayCoorType, base, shape,
+ /*slice=*/mlir::Value{}, firstElementIndices, firBaseTypeParameters);
+ return base;
+ }
+
public:
explicit DesignateOpConversion(mlir::MLIRContext *ctx)
: OpRewritePattern{ctx} {}
@@ -436,9 +461,20 @@ class DesignateOpConversion
if (designateResultType.isa<fir::BaseBoxType>()) {
// Generate embox or rebox.
- if (!fir::unwrapPassByRefType(designateResultType)
- .isa<fir::SequenceType>())
- TODO(loc, "addressing polymorphic arrays");
+ mlir::Type eleTy = fir::unwrapPassByRefType(designateResultType);
+ bool isScalarDesignator = !eleTy.isa<fir::SequenceType>();
+ mlir::Value sourceBox;
+ if (isScalarDesignator) {
+ // The base box will be used for emboxing the scalar element.
+ sourceBox = base;
+ // Generate the coordinate of the element.
+ base = genSubscriptBeginAddr(builder, loc, designate, baseEleTy, base,
+ shape, firBaseTypeParameters);
+ shape = nullptr;
+ // Type information will be taken from the source box,
+ // so the type parameters are not needed.
+ firBaseTypeParameters.clear();
+ }
llvm::SmallVector<mlir::Value> triples;
llvm::SmallVector<mlir::Value> sliceFields;
mlir::Type idxTy = builder.getIndexType();
@@ -462,7 +498,7 @@ class DesignateOpConversion
builder.create<mlir::arith::SubIOp>(loc, iIdx, lbIdx));
}
}
- } else {
+ } else if (!isScalarDesignator) {
// Otherwise, this is an array section with triplets.
auto undef = builder.create<fir::UndefOp>(loc, idxTy);
unsigned i = 0;
@@ -506,8 +542,9 @@ class DesignateOpConversion
resultBox =
builder.create<fir::ReboxOp>(loc, resultType, base, shape, slice);
else
- resultBox = builder.create<fir::EmboxOp>(loc, resultType, base, shape,
- slice, firBaseTypeParameters);
+ resultBox =
+ builder.create<fir::EmboxOp>(loc, resultType, base, shape, slice,
+ firBaseTypeParameters, sourceBox);
rewriter.replaceOp(designate, resultBox);
return mlir::success();
}
@@ -525,19 +562,8 @@ class DesignateOpConversion
// - scalar%array_comp(indices) [substring|complex_part]
// This may be a ranked contiguous array section in which case
// The first element address is being computed.
- llvm::SmallVector<mlir::Value> firstElementIndices;
- auto indices = designate.getIndices();
- int i = 0;
- for (auto isTriplet : designate.getIsTripletAttr().asArrayRef()) {
- // Coordinate of the first element are the index and triplets lower
- // bounds
- firstElementIndices.push_back(indices[i]);
- i = i + (isTriplet ? 3 : 1);
- }
- mlir::Type arrayCoorType = fir::ReferenceType::get(baseEleTy);
- base = builder.create<fir::ArrayCoorOp>(
- loc, arrayCoorType, base, shape,
- /*slice=*/mlir::Value{}, firstElementIndices, firBaseTypeParameters);
+ base = genSubscriptBeginAddr(builder, loc, designate, baseEleTy, base,
+ shape, firBaseTypeParameters);
}
// Scalar substring (potentially on the previously built array element or
diff --git a/flang/test/HLFIR/designate-codegen.fir b/flang/test/HLFIR/designate-codegen.fir
index 3a5bd70978b13..745416ff9dcc4 100644
--- a/flang/test/HLFIR/designate-codegen.fir
+++ b/flang/test/HLFIR/designate-codegen.fir
@@ -191,3 +191,19 @@ func.func @char_array_section_cst_len(%arg0: !fir.box<!fir.array<?x!fir.char<1,5
// CHECK: %[[VAL_12:.*]] = fir.undefined index
// CHECK: %[[VAL_13:.*]] = fir.slice %[[VAL_6]], %[[VAL_8]]#1, %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
// CHECK: %[[VAL_14:.*]] = fir.rebox %[[VAL_4]] {{\[}}%[[VAL_13]]] : (!fir.box<!fir.array<?x!fir.char<1,5>>>, !fir.slice<1>) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
+
+func.func @test_polymorphic_array_elt(%arg0: !fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>> {fir.bindc_name = "x"}) {
+ %0:2 = hlfir.declare %arg0 {uniq_name = "_QFtest1Ex"} : (!fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>) -> (!fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>, !fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>)
+ %c7 = arith.constant 7 : index
+ %1 = hlfir.designate %0#0 (%c7) : (!fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>, index) -> !fir.class<!fir.type<_QMtypesTt1>>
+ return
+}
+// CHECK-LABEL: func.func @test_polymorphic_array_elt(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "_QFtest1Ex"} : (!fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>) -> !fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>
+// CHECK: %[[VAL_2:.*]] = fir.rebox %[[VAL_1]] : (!fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>) -> !fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>
+// CHECK: %[[VAL_3:.*]] = arith.constant 7 : index
+// CHECK: %[[VAL_4:.*]] = fir.array_coor %[[VAL_1]] %[[VAL_3]] : (!fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>, index) -> !fir.ref<!fir.type<_QMtypesTt1>>
+// CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_4]] source_box %[[VAL_1]] : (!fir.ref<!fir.type<_QMtypesTt1>>, !fir.class<!fir.array<?x!fir.type<_QMtypesTt1>>>) -> !fir.class<!fir.type<_QMtypesTt1>>
+// CHECK: return
+// CHECK: }
More information about the flang-commits
mailing list