[flang] Update intrinsic types to unlimited polymorphic form

This patch updates the code added in D143888 to avoid
overwriting some part of the types when updating it
for unlimited polymorphic types.

Reviewed By: jeanPerier, PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D143995
This commit is contained in:
Valentin Clement 2023-02-15 10:20:21 +01:00
parent 11c3cead23
commit e1d95e99bc
No known key found for this signature in database
GPG Key ID: 086D54783C928776
4 changed files with 126 additions and 2 deletions

View File

@ -344,6 +344,27 @@ inline mlir::Type wrapInClassOrBoxType(mlir::Type eleTy,
return fir::BoxType::get(eleTy);
}
/// Return the elementType where intrinsic types are replaced with none for
/// unlimited polymorphic entities.
///
/// i32 -> none
/// !fir.array<2xf32> -> !fir.array<2xnone>
/// !fir.heap<!fir.array<2xf32>> -> !fir.heap<!fir.array<2xnone>>
inline mlir::Type updateTypeForUnlimitedPolymorphic(mlir::Type ty) {
if (auto seqTy = ty.dyn_cast<fir::SequenceType>())
return fir::SequenceType::get(
seqTy.getShape(), updateTypeForUnlimitedPolymorphic(seqTy.getEleTy()));
if (auto heapTy = ty.dyn_cast<fir::HeapType>())
return fir::HeapType::get(
updateTypeForUnlimitedPolymorphic(heapTy.getEleTy()));
if (auto pointerTy = ty.dyn_cast<fir::PointerType>())
return fir::PointerType::get(
updateTypeForUnlimitedPolymorphic(pointerTy.getEleTy()));
if (!ty.isa<mlir::NoneType, fir::RecordType>())
return mlir::NoneType::get(ty.getContext());
return ty;
}
/// Is `t` an address to fir.box or class type?
inline bool isBoxAddress(mlir::Type t) {
return fir::isa_ref_type(t) && fir::unwrapRefType(t).isa<fir::BaseBoxType>();

View File

@ -512,8 +512,7 @@ mlir::Value fir::FirOpBuilder::createBox(mlir::Location loc,
mlir::Type boxTy = fir::BoxType::get(elementType);
mlir::Value tdesc;
if (isPolymorphic) {
if (!elementType.isa<mlir::NoneType, fir::RecordType>())
elementType = mlir::NoneType::get(elementType.getContext());
elementType = fir::updateTypeForUnlimitedPolymorphic(elementType);
boxTy = fir::ClassType::get(elementType);
}

View File

@ -353,6 +353,40 @@ module polymorphic_test
! CHECK: %[[BOX_COMPLEX:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.complex<4>>) -> !fir.class<none>
! CHECK: fir.call @_QMpolymorphic_testPup_input(%[[BOX_COMPLEX]]) {{.*}} : (!fir.class<none>) -> ()
subroutine up_arr_input(a)
class(*), intent(in) :: a(2)
end subroutine
subroutine pass_trivial_arr_to_up()
character :: c(2)
integer :: i(2)
real :: r(2)
logical :: l(2)
complex :: cx(2)
call up_arr_input(c)
call up_arr_input(i)
call up_arr_input(r)
call up_arr_input(l)
call up_arr_input(cx)
end subroutine
! CHECK-LABEL: func.func @_QMpolymorphic_testPpass_trivial_arr_to_up() {
! CHECK: %[[BOX_CHAR:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_CHAR]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
! CHECK: %[[BOX_INT:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_INT]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
! CHECK: %[[BOX_REAL:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_REAL]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
! CHECK: %[[BOX_LOG:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_LOG]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
! CHECK: %[[BOX_COMPLEX:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.complex<4>>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_COMPLEX]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
subroutine assign_polymorphic_allocatable()
type(p1), target :: t(10,20)
class(p1), allocatable :: c(:,:)

View File

@ -146,3 +146,73 @@ TEST_F(FIRTypesTest, isBoxedRecordType) {
EXPECT_FALSE(fir::isBoxedRecordType(fir::BoxType::get(
fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)))));
}
TEST_F(FIRTypesTest, updateTypeForUnlimitedPolymorphic) {
// RecordType are not changed.
// !fir.tyep<T> -> !fir.type<T>
mlir::Type recTy = fir::RecordType::get(&context, "dt");
EXPECT_EQ(recTy, fir::updateTypeForUnlimitedPolymorphic(recTy));
// !fir.array<2x!fir.type<T>> -> !fir.array<2x!fir.type<T>>
mlir::Type arrRecTy = fir::SequenceType::get({2}, recTy);
EXPECT_EQ(arrRecTy, fir::updateTypeForUnlimitedPolymorphic(arrRecTy));
// !fir.heap<!fir.type<T>> -> !fir.heap<!fir.type<T>>
mlir::Type heapTy = fir::HeapType::get(recTy);
EXPECT_EQ(heapTy, fir::updateTypeForUnlimitedPolymorphic(heapTy));
// !fir.heap<!fir.array<2x!fir.type<T>>> ->
// !fir.heap<!fir.array<2x!fir.type<T>>>
mlir::Type heapArrTy = fir::HeapType::get(arrRecTy);
EXPECT_EQ(heapArrTy, fir::updateTypeForUnlimitedPolymorphic(heapArrTy));
// !fir.ptr<!fir.type<T>> -> !fir.ptr<!fir.type<T>>
mlir::Type ptrTy = fir::PointerType::get(recTy);
EXPECT_EQ(ptrTy, fir::updateTypeForUnlimitedPolymorphic(ptrTy));
// !fir.ptr<!fir.array<2x!fir.type<T>>> ->
// !fir.ptr<!fir.array<2x!fir.type<T>>>
mlir::Type ptrArrTy = fir::PointerType::get(arrRecTy);
EXPECT_EQ(ptrArrTy, fir::updateTypeForUnlimitedPolymorphic(ptrArrTy));
// When updating intrinsic types the array, pointer and heap types are kept.
// only the inner element type is changed to `none`.
mlir::Type none = mlir::NoneType::get(&context);
mlir::Type arrNone = fir::SequenceType::get({10}, none);
mlir::Type heapNone = fir::HeapType::get(none);
mlir::Type heapArrNone = fir::HeapType::get(arrNone);
mlir::Type ptrNone = fir::PointerType::get(none);
mlir::Type ptrArrNone = fir::PointerType::get(arrNone);
mlir::Type i32Ty = mlir::IntegerType::get(&context, 32);
mlir::Type f32Ty = mlir::FloatType::getF32(&context);
mlir::Type l1Ty = fir::LogicalType::get(&context, 1);
mlir::Type cplx4Ty = fir::ComplexType::get(&context, 4);
mlir::Type char1Ty = fir::CharacterType::get(&context, 1, 10);
llvm::SmallVector<mlir::Type> intrinsicTypes = {
i32Ty, f32Ty, l1Ty, cplx4Ty, char1Ty};
for (mlir::Type ty : intrinsicTypes) {
// `ty` -> none
EXPECT_EQ(none, fir::updateTypeForUnlimitedPolymorphic(ty));
// !fir.array<10xTY> -> !fir.array<10xnone>
mlir::Type arrTy = fir::SequenceType::get({10}, ty);
EXPECT_EQ(arrNone, fir::updateTypeForUnlimitedPolymorphic(arrTy));
// !fir.heap<TY> -> !fir.heap<none>
mlir::Type heapTy = fir::HeapType::get(ty);
EXPECT_EQ(heapNone, fir::updateTypeForUnlimitedPolymorphic(heapTy));
// !fir.heap<!fir.array<10xTY>> -> !fir.heap<!fir.array<10xnone>>
mlir::Type heapArrTy = fir::HeapType::get(arrTy);
EXPECT_EQ(heapArrNone, fir::updateTypeForUnlimitedPolymorphic(heapArrTy));
// !fir.ptr<TY> -> !fir.ptr<none>
mlir::Type ptrTy = fir::PointerType::get(ty);
EXPECT_EQ(ptrNone, fir::updateTypeForUnlimitedPolymorphic(ptrTy));
// !fir.ptr<!fir.array<10xTY>> -> !fir.ptr<!fir.array<10xnone>>
mlir::Type ptrArrTy = fir::PointerType::get(arrTy);
EXPECT_EQ(ptrArrNone, fir::updateTypeForUnlimitedPolymorphic(ptrArrTy));
}
}