forked from OSchip/llvm-project
[flang] Update to fir::isUnlimitedPolymorphicType and fir::isPolymorphicType functions
This patch update the fir::isUnlimitedPolymorphicType function to reflect the chosen design. It adds also a fir::isPolymorphicType function. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D135143
This commit is contained in:
parent
2f7fbf8376
commit
e50e19af00
|
@ -273,6 +273,10 @@ bool isPointerType(mlir::Type ty);
|
|||
/// Return true iff `ty` is the type of an ALLOCATABLE entity or value.
|
||||
bool isAllocatableType(mlir::Type ty);
|
||||
|
||||
/// Return true iff `ty` is the type of an polymorphic entity or
|
||||
/// value.
|
||||
bool isPolymorphicType(mlir::Type ty);
|
||||
|
||||
/// Return true iff `ty` is the type of an unlimited polymorphic entity or
|
||||
/// value.
|
||||
bool isUnlimitedPolymorphicType(mlir::Type ty);
|
||||
|
|
|
@ -262,12 +262,47 @@ bool isAllocatableType(mlir::Type ty) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isAssumedType(mlir::Type ty) {
|
||||
if (auto boxTy = ty.dyn_cast<fir::BoxType>()) {
|
||||
if (boxTy.getEleTy().isa<mlir::NoneType>())
|
||||
return true;
|
||||
if (auto seqTy = boxTy.getEleTy().dyn_cast<fir::SequenceType>())
|
||||
return seqTy.getEleTy().isa<mlir::NoneType>();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isPolymorphicType(mlir::Type ty) {
|
||||
if (auto refTy = fir::dyn_cast_ptrEleTy(ty))
|
||||
ty = refTy;
|
||||
// CLASS(*)
|
||||
if (ty.isa<fir::ClassType>())
|
||||
return true;
|
||||
// assumed type are polymorphic.
|
||||
return isAssumedType(ty);
|
||||
}
|
||||
|
||||
bool isUnlimitedPolymorphicType(mlir::Type ty) {
|
||||
if (auto refTy = fir::dyn_cast_ptrEleTy(ty))
|
||||
ty = refTy;
|
||||
if (auto clTy = ty.dyn_cast<fir::ClassType>())
|
||||
return clTy.getEleTy().isa<mlir::NoneType>();
|
||||
return false;
|
||||
// CLASS(*)
|
||||
if (auto clTy = ty.dyn_cast<fir::ClassType>()) {
|
||||
if (clTy.getEleTy().isa<mlir::NoneType>())
|
||||
return true;
|
||||
mlir::Type innerType =
|
||||
llvm::TypeSwitch<mlir::Type, mlir::Type>(clTy.getEleTy())
|
||||
.Case<fir::PointerType, fir::HeapType, fir::SequenceType>(
|
||||
[](auto ty) {
|
||||
mlir::Type eleTy = ty.getEleTy();
|
||||
if (auto seqTy = eleTy.dyn_cast<fir::SequenceType>())
|
||||
return seqTy.getEleTy();
|
||||
return eleTy;
|
||||
})
|
||||
.Default([](mlir::Type) { return mlir::Type{}; });
|
||||
return innerType.isa<mlir::NoneType>();
|
||||
}
|
||||
// TYPE(*)
|
||||
return isAssumedType(ty);
|
||||
}
|
||||
|
||||
bool isRecordWithAllocatableMember(mlir::Type ty) {
|
||||
|
|
|
@ -23,6 +23,7 @@ add_flang_unittest(FlangOptimizerTests
|
|||
Builder/Runtime/StopTest.cpp
|
||||
Builder/Runtime/TransformationalTest.cpp
|
||||
FIRContextTest.cpp
|
||||
FIRTypesTest.cpp
|
||||
InternalNamesTest.cpp
|
||||
KindMappingTest.cpp
|
||||
RTBuilder.cpp
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
//===- FIRTypesTest.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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "flang/Optimizer/Dialect/FIRType.h"
|
||||
#include "flang/Optimizer/Support/InitFIR.h"
|
||||
|
||||
struct FIRTypesTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() { fir::support::loadDialects(context); }
|
||||
|
||||
mlir::MLIRContext context;
|
||||
};
|
||||
|
||||
// Test fir::isPolymorphicType from flang/Optimizer/Dialect/FIRType.h.
|
||||
TEST_F(FIRTypesTest, isPolymorphicTypeTest) {
|
||||
mlir::Type noneTy = mlir::NoneType::get(&context);
|
||||
mlir::Type seqNoneTy =
|
||||
fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, noneTy);
|
||||
mlir::Type recTy = fir::RecordType::get(&context, "dt");
|
||||
mlir::Type seqRecTy =
|
||||
fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);
|
||||
|
||||
// CLASS(T)
|
||||
mlir::Type ty = fir::ClassType::get(recTy);
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
EXPECT_TRUE(fir::isPolymorphicType(fir::ReferenceType::get(ty)));
|
||||
|
||||
// CLASS(T), DIMENSION(10)
|
||||
ty = fir::ClassType::get(fir::SequenceType::get({10}, recTy));
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
|
||||
// CLASS(T), DIMENSION(:)
|
||||
ty = fir::ClassType::get(seqRecTy);
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
|
||||
// CLASS(T), ALLOCATABLE
|
||||
ty = fir::ClassType::get(fir::HeapType::get(recTy));
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
|
||||
// CLASS(T), ALLOCATABLE, DIMENSION(:)
|
||||
ty = fir::ClassType::get(fir::HeapType::get(seqRecTy));
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
|
||||
// CLASS(T), POINTER
|
||||
ty = fir::ClassType::get(fir::PointerType::get(recTy));
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
|
||||
// CLASS(T), POINTER, DIMENSIONS(:)
|
||||
ty = fir::ClassType::get(fir::PointerType::get(seqRecTy));
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
|
||||
// CLASS(*)
|
||||
ty = fir::ClassType::get(noneTy);
|
||||
EXPECT_TRUE(fir::isPolymorphicType(ty));
|
||||
EXPECT_TRUE(fir::isPolymorphicType(fir::ReferenceType::get(ty)));
|
||||
|
||||
// TYPE(*)
|
||||
EXPECT_TRUE(fir::isPolymorphicType(fir::BoxType::get(noneTy)));
|
||||
|
||||
// TYPE(*), DIMENSION(:)
|
||||
EXPECT_TRUE(fir::isPolymorphicType(fir::BoxType::get(seqNoneTy)));
|
||||
|
||||
// false tests
|
||||
EXPECT_FALSE(fir::isPolymorphicType(noneTy));
|
||||
EXPECT_FALSE(fir::isPolymorphicType(seqNoneTy));
|
||||
}
|
||||
|
||||
// Test fir::isUnlimitedPolymorphicType from flang/Optimizer/Dialect/FIRType.h.
|
||||
TEST_F(FIRTypesTest, isUnlimitedPolymorphicTypeTest) {
|
||||
mlir::Type noneTy = mlir::NoneType::get(&context);
|
||||
mlir::Type seqNoneTy =
|
||||
fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, noneTy);
|
||||
|
||||
// CLASS(*)
|
||||
mlir::Type ty = fir::ClassType::get(noneTy);
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(fir::ReferenceType::get(ty)));
|
||||
|
||||
// CLASS(*), DIMENSION(10)
|
||||
ty = fir::ClassType::get(fir::SequenceType::get({10}, noneTy));
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));
|
||||
|
||||
// CLASS(*), DIMENSION(:)
|
||||
ty = fir::ClassType::get(
|
||||
fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, noneTy));
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));
|
||||
|
||||
// CLASS(*), ALLOCATABLE
|
||||
ty = fir::ClassType::get(fir::HeapType::get(noneTy));
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));
|
||||
|
||||
// CLASS(*), ALLOCATABLE, DIMENSION(:)
|
||||
ty = fir::ClassType::get(fir::HeapType::get(seqNoneTy));
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));
|
||||
|
||||
// CLASS(*), POINTER
|
||||
ty = fir::ClassType::get(fir::PointerType::get(noneTy));
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));
|
||||
|
||||
// CLASS(*), POINTER, DIMENSIONS(:)
|
||||
ty = fir::ClassType::get(fir::PointerType::get(seqNoneTy));
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(ty));
|
||||
|
||||
// TYPE(*)
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(fir::BoxType::get(noneTy)));
|
||||
|
||||
// TYPE(*), DIMENSION(:)
|
||||
EXPECT_TRUE(fir::isUnlimitedPolymorphicType(fir::BoxType::get(seqNoneTy)));
|
||||
|
||||
// false tests
|
||||
EXPECT_FALSE(fir::isUnlimitedPolymorphicType(noneTy));
|
||||
EXPECT_FALSE(fir::isUnlimitedPolymorphicType(seqNoneTy));
|
||||
}
|
Loading…
Reference in New Issue