[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