[flang-commits] [flang] e50e19a - [flang] Update to fir::isUnlimitedPolymorphicType and fir::isPolymorphicType functions
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Wed Oct 5 01:05:21 PDT 2022
Author: Valentin Clement
Date: 2022-10-05T10:05:11+02:00
New Revision: e50e19af00378e753378525cc8567cf01b2fd477
URL: https://github.com/llvm/llvm-project/commit/e50e19af00378e753378525cc8567cf01b2fd477
DIFF: https://github.com/llvm/llvm-project/commit/e50e19af00378e753378525cc8567cf01b2fd477.diff
LOG: [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
Added:
flang/unittests/Optimizer/FIRTypesTest.cpp
Modified:
flang/include/flang/Optimizer/Dialect/FIRType.h
flang/lib/Optimizer/Dialect/FIRType.cpp
flang/unittests/Optimizer/CMakeLists.txt
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 5246071422f7b..b2f0c6b018c46 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -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);
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 01f3f1263720b..40ebf3760ea3f 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -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) {
diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt
index 856ed069ac6e8..9f8483d8a1195 100644
--- a/flang/unittests/Optimizer/CMakeLists.txt
+++ b/flang/unittests/Optimizer/CMakeLists.txt
@@ -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
diff --git a/flang/unittests/Optimizer/FIRTypesTest.cpp b/flang/unittests/Optimizer/FIRTypesTest.cpp
new file mode 100644
index 0000000000000..1a81c2ff426f7
--- /dev/null
+++ b/flang/unittests/Optimizer/FIRTypesTest.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));
+}
More information about the flang-commits
mailing list