[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