[flang-commits] [flang] 262c23d - [flang] Introduce fir.class type

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Sun Oct 2 11:14:29 PDT 2022


Author: Valentin Clement
Date: 2022-10-02T20:13:51+02:00
New Revision: 262c23d2ca04dd4c680b20917c87e49949664390

URL: https://github.com/llvm/llvm-project/commit/262c23d2ca04dd4c680b20917c87e49949664390
DIFF: https://github.com/llvm/llvm-project/commit/262c23d2ca04dd4c680b20917c87e49949664390.diff

LOG: [flang] Introduce fir.class type

Introduce a new ClassType for polymorphic
entities. A fir.class type is similar to a fir.box type in
many ways and is also base on the BaseBoxType.

This patch is part of the implementation of the poltymorphic
entities.
https://github.com/llvm/llvm-project/blob/main/flang/docs/PolymorphicEntities.md

Depends on D134956

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D134957

Added: 
    

Modified: 
    flang/docs/PolymorphicEntities.md
    flang/include/flang/Optimizer/Dialect/FIRType.h
    flang/include/flang/Optimizer/Dialect/FIRTypes.td
    flang/lib/Optimizer/Dialect/FIRType.cpp
    flang/test/Fir/fir-types.fir
    flang/test/Fir/invalid-types.fir

Removed: 
    


################################################################################
diff  --git a/flang/docs/PolymorphicEntities.md b/flang/docs/PolymorphicEntities.md
index 711db6293bc96..362b899016ff1 100644
--- a/flang/docs/PolymorphicEntities.md
+++ b/flang/docs/PolymorphicEntities.md
@@ -83,7 +83,8 @@ func.func @foo(%p : !fir.class<!fir.type<_QTpoint{x:f32,y:f32}>>)
 
 ### Unlimited polymorphic entities `CLASS(*)`
 
-The unlimited polymorphic entity is represented as a class type with `*`.
+The unlimited polymorphic entity is represented as a class type with `none` as
+element type.
 
 **Fortran**
 ```fortran
@@ -95,7 +96,7 @@ end subroutine
 
 **FIR**
 ```c
-func.func @bar(%x : !fir.class<*>)
+func.func @bar(%x : !fir.class<none>)
 ```
 
 ### Assumed-type `TYPE(*)`

diff  --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 304a5267bcdf1..390d4c3fc8d67 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -304,7 +304,7 @@ mlir::Type fromRealTypeID(mlir::MLIRContext *context, llvm::Type::TypeID typeID,
                           fir::KindTy kind);
 
 inline bool BaseBoxType::classof(mlir::Type type) {
-  return type.isa<fir::BoxType>();
+  return type.isa<fir::BoxType, fir::ClassType>();
 }
 
 } // namespace fir

diff  --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
index d5e47b4018d6d..5c60230393c29 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
@@ -138,6 +138,26 @@ def fir_CharacterType : FIR_Type<"Character", "char"> {
   }];
 }
 
+def fir_ClassType : FIR_Type<"Class", "class", [], "BaseBoxType"> {
+  let summary = "Class type";
+
+  let description = [{
+    Class type is used to model the Fortran CLASS instrinsic type. A class type
+    is equivalent to a fir.box type with a dynamic type.
+  }];
+
+  let parameters = (ins "mlir::Type":$eleTy);
+
+  let builders = [
+    TypeBuilderWithInferredContext<(ins "mlir::Type":$eleTy), [{
+      return $_get(eleTy.getContext(), eleTy);
+    }]>
+  ];
+
+  let genVerifyDecl = 1;
+  let assemblyFormat = "`<` $eleTy `>`";
+}
+
 def fir_ComplexType : FIR_Type<"Complex", "complex"> {
   let summary = "Complex type";
 

diff  --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 0a01a65ab1b4d..3c70627b17449 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -440,6 +440,19 @@ void fir::CharacterType::print(mlir::AsmPrinter &printer) const {
   printer << '>';
 }
 
+//===----------------------------------------------------------------------===//
+// ClassType
+//===----------------------------------------------------------------------===//
+
+mlir::LogicalResult
+fir::ClassType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
+                       mlir::Type eleTy) {
+  if (eleTy.isa<fir::RecordType, fir::SequenceType, fir::HeapType,
+                fir::PointerType, mlir::NoneType>())
+    return mlir::success();
+  return emitError() << "invalid element type\n";
+}
+
 //===----------------------------------------------------------------------===//
 // ComplexType
 //===----------------------------------------------------------------------===//
@@ -930,7 +943,8 @@ mlir::Type fir::fromRealTypeID(mlir::MLIRContext *context,
 
 mlir::Type BaseBoxType::getEleTy() const {
   return llvm::TypeSwitch<fir::BaseBoxType, mlir::Type>(*this)
-      .Case<fir::BoxType>([](auto type) { return type.getEleTy(); });
+      .Case<fir::BoxType, fir::ClassType>(
+          [](auto type) { return type.getEleTy(); });
 }
 
 //===----------------------------------------------------------------------===//
@@ -938,11 +952,11 @@ mlir::Type BaseBoxType::getEleTy() const {
 //===----------------------------------------------------------------------===//
 
 void FIROpsDialect::registerTypes() {
-  addTypes<BoxType, BoxCharType, BoxProcType, CharacterType, fir::ComplexType,
-           FieldType, HeapType, fir::IntegerType, LenType, LogicalType,
-           LLVMPointerType, PointerType, RealType, RecordType, ReferenceType,
-           SequenceType, ShapeType, ShapeShiftType, ShiftType, SliceType,
-           TypeDescType, fir::VectorType>();
+  addTypes<BoxType, BoxCharType, BoxProcType, CharacterType, ClassType,
+           fir::ComplexType, FieldType, HeapType, fir::IntegerType, LenType,
+           LogicalType, LLVMPointerType, PointerType, RealType, RecordType,
+           ReferenceType, SequenceType, ShapeType, ShapeShiftType, ShiftType,
+           SliceType, TypeDescType, fir::VectorType>();
   fir::ReferenceType::attachInterface<PointerLikeModel<fir::ReferenceType>>(
       *getContext());
 

diff  --git a/flang/test/Fir/fir-types.fir b/flang/test/Fir/fir-types.fir
index 861477b6bbc8e..7f9c079f1451f 100644
--- a/flang/test/Fir/fir-types.fir
+++ b/flang/test/Fir/fir-types.fir
@@ -1,6 +1,6 @@
 // Test the FIR types
 // Parse types and check that we can reparse what we print.
-// RUN: fir-opt %s | fir-opt | FileCheck %s
+// RUN: fir-opt --split-input-file %s | fir-opt --split-input-file | FileCheck %s
 
 // Fortran Intrinsic types
 // CHECK-LABEL: func private @it1() -> !fir.int<4>
@@ -18,6 +18,8 @@ func.func private @it5() -> !fir.char<1>
 func.func private @it6() -> !fir.char<2,10>
 func.func private @it7() -> !fir.char<4,?>
 
+// -----
+
 // Fortran Derived types (records)
 // CHECK-LABEL: func private @dvd1() -> !fir.type<derived1>
 // CHECK-LABEL: func private @dvd2() -> !fir.type<derived2(p:i32)>
@@ -34,6 +36,8 @@ func.func private @dvd5() -> !fir.type<derived5(p1:i8,p2:i8,p3:i8,p4:i8,p5:i8){f
 func.func private @dvd6() -> !fir.type<derived6{f:!fir.ptr<!fir.type<derived6>>}>
 func.func private @dvd7() -> !fir.type<derived_with_field_name_same_as_integer_type{i32:f32}>
 
+// -----
+
 // FIR array types
 // CHECK-LABEL: func private @arr1() -> !fir.array<10xf32>
 // CHECK-LABEL: func private @arr2() -> !fir.array<10x10xf32>
@@ -50,6 +54,8 @@ func.func private @arr5() -> !fir.array<?x?xf32>
 func.func private @arr6() -> !fir.array<*:f32>
 func.func private @arr7() -> !fir.array<1x2x?x4x5x6x7x8x9xf32>
 
+// -----
+
 // FIR pointer-like types
 // CHECK-LABEL: func private @mem1() -> !fir.ref<i32>
 // CHECK-LABEL: func private @mem2() -> !fir.ptr<i32>
@@ -64,6 +70,8 @@ func.func private @mem4() -> !fir.ref<() -> ()>
 func.func private @mem5() -> !fir.llvm_ptr<!fir.ref<f32>>
 func.func private @mem6() -> !fir.llvm_ptr<i8>
 
+// -----
+
 // FIR box types (descriptors)
 // CHECK-LABEL: func private @box1() -> !fir.box<!fir.array<?xf32>>
 // CHECK-LABEL: func private @box2() -> !fir.boxchar<2>
@@ -76,6 +84,8 @@ func.func private @box3() -> !fir.boxproc<(i32, i32) -> i64>
 func.func private @box4() -> !fir.box<none>
 func.func private @box5() -> !fir.box<!fir.type<derived3{f:f32}>>
 
+// -----
+
 // FIR misc. types
 // CHECK-LABEL: func private @oth1() -> !fir.shape<1>
 // CHECK-LABEL: func private @oth2() -> !fir.field
@@ -88,6 +98,28 @@ func.func private @oth3() -> !fir.tdesc<!fir.type<derived7{f1:f32,f2:f32}>>
 func.func private @oth4() -> !fir.shapeshift<15>
 func.func private @oth5() -> !fir.slice<8>
 
+// -----
+
 // FIR vector
 // CHECK-LABEL: func private @vecty(i1) -> !fir.vector<10:i32>
 func.func private @vecty(i1) -> !fir.vector<10:i32>
+
+// -----
+
+// FIR Class type
+// CHECK-LABEL: class1() -> !fir.class<!fir.type<c1{p:i32}>>
+// CHECK-LABEL: class2() -> !fir.class<!fir.array<?x!fir.type<c1{p:i32}>>>
+// CHECK-LABEL: class3() -> !fir.class<!fir.heap<!fir.type<c1{p:i32}>>>
+// CHECK-LABEL: class4() -> !fir.class<!fir.ptr<!fir.type<c1{p:i32}>>>
+// CHECK-LABEL: class5() -> !fir.class<none>
+// CHECK-LABEL: class6() -> !fir.class<!fir.array<?xnone>>
+// CHECK-LABEL: class7() -> !fir.class<!fir.heap<none>>
+// CHECK-LABEL: class8() -> !fir.class<!fir.ptr<none>>
+func.func private @class1() -> !fir.class<!fir.type<c1{p:i32}>>
+func.func private @class2() -> !fir.class<!fir.array<?x!fir.type<c1{p:i32}>>>
+func.func private @class3() -> !fir.class<!fir.heap<!fir.type<c1{p:i32}>>>
+func.func private @class4() -> !fir.class<!fir.ptr<!fir.type<c1{p:i32}>>>
+func.func private @class5() -> !fir.class<none>
+func.func private @class6() -> !fir.class<!fir.array<?xnone>>
+func.func private @class7() -> !fir.class<!fir.heap<none>>
+func.func private @class8() -> !fir.class<!fir.ptr<none>>

diff  --git a/flang/test/Fir/invalid-types.fir b/flang/test/Fir/invalid-types.fir
index afd23b6954bea..1ab506a880634 100644
--- a/flang/test/Fir/invalid-types.fir
+++ b/flang/test/Fir/invalid-types.fir
@@ -162,3 +162,8 @@ func.func private @oth3() -> !fir.vector<10>
 
 // expected-error at +1 {{expected non-function type}}
 func.func private @oth3() -> !fir.vector<10:>
+
+// -----
+
+// expected-error at +1 {{invalid element type}}
+func.func private @upe() -> !fir.class<!fir.logical<1>>


        


More information about the flang-commits mailing list