[flang-commits] [flang] abefd87 - [flang] Delegate pointer association to class(*) pointer to the runtime
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Wed Nov 30 09:58:07 PST 2022
Author: Valentin Clement
Date: 2022-11-30T18:57:57+01:00
New Revision: abefd87e706a47303905edcff031a22edf880921
URL: https://github.com/llvm/llvm-project/commit/abefd87e706a47303905edcff031a22edf880921
DIFF: https://github.com/llvm/llvm-project/commit/abefd87e706a47303905edcff031a22edf880921.diff
LOG: [flang] Delegate pointer association to class(*) pointer to the runtime
Pointer association with an unlimited polymorphic pointer on the lhs
requires more than just updating the base_addr. Delegate the association to
the runtime function `PointerAssociation`.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D139019
Added:
Modified:
flang/include/flang/Lower/Runtime.h
flang/include/flang/Optimizer/Dialect/FIRType.h
flang/lib/Lower/Bridge.cpp
flang/lib/Lower/Runtime.cpp
flang/lib/Optimizer/Dialect/FIROps.cpp
flang/lib/Optimizer/Dialect/FIRType.cpp
flang/test/Lower/polymorphic.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h
index 11eedf8972525..87d5b5b7670c6 100644
--- a/flang/include/flang/Lower/Runtime.h
+++ b/flang/include/flang/Lower/Runtime.h
@@ -69,6 +69,9 @@ void genPauseStatement(AbstractConverter &, const parser::PauseStmt &);
mlir::Value genAssociated(fir::FirOpBuilder &, mlir::Location,
mlir::Value pointer, mlir::Value target);
+void genPointerAssociate(fir::FirOpBuilder &, mlir::Location,
+ mlir::Value pointer, mlir::Value target);
+
mlir::Value genCpuTime(fir::FirOpBuilder &, mlir::Location);
void genDateAndTime(fir::FirOpBuilder &, mlir::Location,
llvm::Optional<fir::CharBoxValue> date,
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 0928e8522838d..ae50d08970edd 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -280,6 +280,12 @@ bool isAllocatableType(mlir::Type ty);
/// e.g. !fir.box<!fir.type<derived>>
bool isBoxedRecordType(mlir::Type ty);
+/// Return true iff `ty` is a !fir.ref<!fir.box<T>> type.
+bool isRefBoxType(mlir::Type ty);
+
+/// Return true iff `ty` is !fir.box<none> type.
+bool isOpaqueDescType(mlir::Type ty);
+
/// Return true iff `ty` is the type of an polymorphic entity or
/// value.
bool isPolymorphicType(mlir::Type ty);
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 93255c6fbc229..c98d83808d3ef 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -2710,6 +2710,19 @@ class FirConverter : public Fortran::lower::AbstractConverter {
[&](const Fortran::evaluate::Assignment::BoundsSpec &lbExprs) {
if (Fortran::evaluate::IsProcedure(assign.rhs))
TODO(loc, "procedure pointer assignment");
+
+ std::optional<Fortran::evaluate::DynamicType> lhsType =
+ assign.lhs.GetType();
+ // Delegate pointer association to unlimited polymorphic pointer
+ // to the runtime. element size, type code, attribute and of
+ // course base_addr might need to be updated.
+ if (lhsType && lhsType->IsUnlimitedPolymorphic()) {
+ mlir::Value lhs = genExprMutableBox(loc, assign.lhs).getAddr();
+ mlir::Value rhs = genExprMutableBox(loc, assign.rhs).getAddr();
+ Fortran::lower::genPointerAssociate(*builder, loc, lhs, rhs);
+ return;
+ }
+
llvm::SmallVector<mlir::Value> lbounds;
for (const Fortran::evaluate::ExtentExpr &lbExpr : lbExprs)
lbounds.push_back(
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index 6322e5460a53b..ef93d4db10312 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -188,6 +188,17 @@ mlir::Value Fortran::lower::genAssociated(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
+void Fortran::lower::genPointerAssociate(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ mlir::Value pointer,
+ mlir::Value target) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(PointerAssociate)>(loc, builder);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, func.getFunctionType(), pointer, target);
+ builder.create<fir::CallOp>(loc, func, args).getResult(0);
+}
+
mlir::Value Fortran::lower::genCpuTime(fir::FirOpBuilder &builder,
mlir::Location loc) {
mlir::func::FuncOp func =
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 409b64b9825bb..0adeb6bc086ce 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -938,8 +938,10 @@ mlir::LogicalResult fir::ConvertOp::verify() {
(inType.isa<fir::BoxProcType>() && outType.isa<fir::BoxProcType>()) ||
(fir::isa_complex(inType) && fir::isa_complex(outType)) ||
(fir::isBoxedRecordType(inType) && fir::isPolymorphicType(outType)) ||
- (fir::isPolymorphicType(inType) && fir::isPolymorphicType(outType)))
+ (fir::isPolymorphicType(inType) && fir::isPolymorphicType(outType)) ||
+ (fir::isRefBoxType(inType) && fir::isOpaqueDescType(outType)))
return mlir::success();
+ llvm::errs() << inType << " / " << outType << "\n";
return emitOpError("invalid type conversion");
}
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 89a806c0474aa..a2906e8a5bc0c 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -274,6 +274,19 @@ bool isBoxedRecordType(mlir::Type ty) {
return false;
}
+bool isRefBoxType(mlir::Type ty) {
+ if (auto refTy = ty.dyn_cast<fir::ReferenceType>())
+ return refTy.getEleTy().isa<fir::BaseBoxType>();
+ return false;
+}
+
+bool isOpaqueDescType(mlir::Type ty) {
+ if (auto boxTy = ty.dyn_cast<fir::BoxType>())
+ if (boxTy.getEleTy().isa<mlir::NoneType>())
+ return true;
+ return false;
+}
+
static bool isAssumedType(mlir::Type ty) {
if (auto boxTy = ty.dyn_cast<fir::BoxType>()) {
if (boxTy.getEleTy().isa<mlir::NoneType>())
diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90
index b97cc46495f9a..662aca9933aae 100644
--- a/flang/test/Lower/polymorphic.f90
+++ b/flang/test/Lower/polymorphic.f90
@@ -130,24 +130,20 @@ subroutine call_up_ret()
! CHECK-LABEL: func.func @_QMpolymorphic_testPcall_up_ret() {
! CHECK: %{{.*}} = fir.call @_QMpolymorphic_testPup_ret() {{.*}} : () -> !fir.class<!fir.ptr<!fir.array<?xnone>>>
- subroutine rebox_f32_to_none(r)
+ subroutine associate_up_pointer(r)
class(r1) :: r
class(*), pointer :: p(:)
p => r%rp
end subroutine
-! CHECK-LABEL: func.func @_QMpolymorphic_testPrebox_f32_to_none(
+! CHECK-LABEL: func.func @_QMpolymorphic_testPassociate_up_pointer(
! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTr1{rp:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> {fir.bindc_name = "r"}) {
-! CHECK: %[[P:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.array<?xnone>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFrebox_f32_to_noneEp"}
+! CHECK: %[[P:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.array<?xnone>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFassociate_up_pointerEp"}
! CHECK: %[[FIELD_RP:.*]] = fir.field_index rp, !fir.type<_QMpolymorphic_testTr1{rp:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
! CHECK: %[[COORD_RP:.*]] = fir.coordinate_of %[[ARG0]], %[[FIELD_RP]] : (!fir.class<!fir.type<_QMpolymorphic_testTr1{rp:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[LOADED_RP:.*]] = fir.load %[[COORD_RP]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[RP_DIMS:.*]]:3 = fir.box_dims %[[LOADED_RP]], %[[C0]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
-! CHECK: %[[SHIFT:.*]] = fir.shift %[[RP_DIMS]]#0 : (index) -> !fir.shift<1>
-! CHECK: %[[REBOX_TO_BOX:.*]] = fir.rebox %[[LOADED_RP]](%[[SHIFT]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK: %[[REBOX_TO_UP:.*]] = fir.rebox %[[REBOX_TO_BOX]] : (!fir.box<!fir.array<?xf32>>) -> !fir.class<!fir.ptr<!fir.array<?xnone>>>
-! CHECK: fir.store %[[REBOX_TO_UP]] to %[[P]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?xnone>>>>
+! CHECK: %[[CONV_P:.*]] = fir.convert %[[P]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?xnone>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %[[CONV_RP:.*]] = fir.convert %[[COORD_RP]] : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.box<none>
+! CHECK: %{{.*}} = fir.call @_FortranAPointerAssociate(%[[CONV_P]], %[[CONV_RP]]) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>) -> none
! CHECK: return
! Test that the fir.dispatch operation is created with the correct pass object
More information about the flang-commits
mailing list