FLANG

FIRType.h
1 //===-- Optimizer/Dialect/FIRType.h -- FIR types ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef OPTIMIZER_DIALECT_FIRTYPE_H
10 #define OPTIMIZER_DIALECT_FIRTYPE_H
11
12 #include "mlir/IR/Attributes.h"
13 #include "mlir/IR/Types.h"
14 #include "llvm/ADT/SmallVector.h"
15
16 namespace llvm {
17 class raw_ostream;
18 class StringRef;
19 template <typename>
20 class ArrayRef;
21 class hash_code;
22 } // namespace llvm
23
24 namespace mlir {
25 class DialectAsmParser;
26 class DialectAsmPrinter;
27 class ComplexType;
28 class FloatType;
29 } // namespace mlir
30
31 namespace fir {
32
33 class FIROpsDialect;
34
35 using KindTy = int;
36
37 namespace detail {
38 struct BoxTypeStorage;
39 struct BoxCharTypeStorage;
40 struct BoxProcTypeStorage;
41 struct CharacterTypeStorage;
42 struct CplxTypeStorage;
43 struct DimsTypeStorage;
44 struct FieldTypeStorage;
45 struct HeapTypeStorage;
46 struct IntTypeStorage;
47 struct LenTypeStorage;
48 struct LogicalTypeStorage;
49 struct PointerTypeStorage;
50 struct RealTypeStorage;
51 struct RecordTypeStorage;
52 struct ReferenceTypeStorage;
53 struct SequenceTypeStorage;
54 struct TypeDescTypeStorage;
55 } // namespace detail
56
58 enum TypeKind {
59 // The enum starts at the range reserved for this dialect.
60 FIR_TYPE = mlir::Type::FIRST_FIR_TYPE,
61 FIR_BOX, // (static) descriptor
62 FIR_BOXCHAR, // CHARACTER pointer and length
63 FIR_BOXPROC, // procedure with host association
64 FIR_CHARACTER, // intrinsic type
65 FIR_COMPLEX, // intrinsic type
66 FIR_DERIVED, // derived
67 FIR_DIMS,
68 FIR_FIELD,
69 FIR_HEAP,
70 FIR_INT, // intrinsic type
71 FIR_LEN,
72 FIR_LOGICAL, // intrinsic type
73 FIR_POINTER, // POINTER attr
74 FIR_REAL, // intrinsic type
75 FIR_REFERENCE,
76 FIR_SEQUENCE, // DIMENSION attr
77 FIR_TYPEDESC,
78 };
79
80 // These isa_ routines follow the precedent of llvm::isa_or_null<>
81
83 bool isa_fir_type(mlir::Type t);
84
86 bool isa_std_type(mlir::Type t);
87
89 bool isa_fir_or_std_type(mlir::Type t);
90
92 bool isa_ref_type(mlir::Type t);
93
95 bool isa_passbyref_type(mlir::Type t);
96
98 bool isa_box_type(mlir::Type t);
99
103 inline bool conformsWithPassByRef(mlir::Type t) {
104 return isa_ref_type(t) || isa_box_type(t);
105 }
106
108 bool isa_aggregate(mlir::Type t);
109
112 mlir::Type dyn_cast_ptrEleTy(mlir::Type t);
113
115 template <typename A, unsigned Id>
116 struct IntrinsicTypeMixin {
117 static constexpr bool kindof(unsigned kind) { return kind == getId(); }
118 static constexpr unsigned getId() { return Id; }
119 };
120
121 // Intrinsic types
122
126 class CharacterType
127 : public mlir::Type::TypeBase<CharacterType, mlir::Type,
128 detail::CharacterTypeStorage>,
129 public IntrinsicTypeMixin<CharacterType, TypeKind::FIR_CHARACTER> {
130 public:
131 using Base::Base;
132 static CharacterType get(mlir::MLIRContext *ctxt, KindTy kind);
133 KindTy getFKind() const;
134 };
135
139 class CplxType : public mlir::Type::TypeBase<CplxType, mlir::Type,
140 detail::CplxTypeStorage>,
141 public IntrinsicTypeMixin<CplxType, TypeKind::FIR_COMPLEX> {
142 public:
143 using Base::Base;
144 static CplxType get(mlir::MLIRContext *ctxt, KindTy kind);
145
147 mlir::Type getElementType() const;
148
149 KindTy getFKind() const;
150 };
151
154 class IntType
155 : public mlir::Type::TypeBase<IntType, mlir::Type, detail::IntTypeStorage>,
156 public IntrinsicTypeMixin<IntType, TypeKind::FIR_INT> {
157 public:
158 using Base::Base;
159 static IntType get(mlir::MLIRContext *ctxt, KindTy kind);
160 KindTy getFKind() const;
161 };
162
165 class LogicalType
166 : public mlir::Type::TypeBase<LogicalType, mlir::Type,
167 detail::LogicalTypeStorage>,
168 public IntrinsicTypeMixin<LogicalType, TypeKind::FIR_LOGICAL> {
169 public:
170 using Base::Base;
171 static LogicalType get(mlir::MLIRContext *ctxt, KindTy kind);
172 KindTy getFKind() const;
173 };
174
177 class RealType : public mlir::Type::TypeBase<RealType, mlir::Type,
178 detail::RealTypeStorage>,
179 public IntrinsicTypeMixin<RealType, TypeKind::FIR_REAL> {
180 public:
181 using Base::Base;
182 static RealType get(mlir::MLIRContext *ctxt, KindTy kind);
183 KindTy getFKind() const;
184 };
185
186 // FIR support types
187
192 class BoxType
193 : public mlir::Type::TypeBase<BoxType, mlir::Type, detail::BoxTypeStorage> {
194 public:
195 using Base::Base;
196 static BoxType get(mlir::Type eleTy, mlir::AffineMapAttr map = {});
197 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_BOX; }
198 mlir::Type getEleTy() const;
199 mlir::AffineMapAttr getLayoutMap() const;
200
201 static mlir::LogicalResult
202 verifyConstructionInvariants(mlir::Location, mlir::Type eleTy,
203 mlir::AffineMapAttr map);
204 };
205
209 class BoxCharType : public mlir::Type::TypeBase<BoxCharType, mlir::Type,
210 detail::BoxCharTypeStorage> {
211 public:
212 using Base::Base;
213 static BoxCharType get(mlir::MLIRContext *ctxt, KindTy kind);
214 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_BOXCHAR; }
215 CharacterType getEleTy() const;
216 };
217
221 class BoxProcType : public mlir::Type::TypeBase<BoxProcType, mlir::Type,
222 detail::BoxProcTypeStorage> {
223 public:
224 using Base::Base;
225 static BoxProcType get(mlir::Type eleTy);
226 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_BOXPROC; }
227 mlir::Type getEleTy() const;
228
229 static mlir::LogicalResult verifyConstructionInvariants(mlir::Location,
230 mlir::Type eleTy);
231 };
232
237 class DimsType : public mlir::Type::TypeBase<DimsType, mlir::Type,
238 detail::DimsTypeStorage> {
239 public:
240 using Base::Base;
241 static DimsType get(mlir::MLIRContext *ctx, unsigned rank);
242 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_DIMS; }
243
245 unsigned getRank() const;
246 };
247
251 class FieldType : public mlir::Type::TypeBase<FieldType, mlir::Type,
252 detail::FieldTypeStorage> {
253 public:
254 using Base::Base;
255 static FieldType get(mlir::MLIRContext *ctxt);
256 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_FIELD; }
257 };
258
263 class HeapType : public mlir::Type::TypeBase<HeapType, mlir::Type,
264 detail::HeapTypeStorage> {
265 public:
266 using Base::Base;
267 static HeapType get(mlir::Type elementType);
268 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_HEAP; }
269
270 mlir::Type getEleTy() const;
271
272 static mlir::LogicalResult verifyConstructionInvariants(mlir::Location,
273 mlir::Type eleTy);
274 };
275
279 class LenType
280 : public mlir::Type::TypeBase<LenType, mlir::Type, detail::LenTypeStorage> {
281 public:
282 using Base::Base;
283 static LenType get(mlir::MLIRContext *ctxt);
284 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_LEN; }
285 };
286
290 class PointerType : public mlir::Type::TypeBase<PointerType, mlir::Type,
291 detail::PointerTypeStorage> {
292 public:
293 using Base::Base;
294 static PointerType get(mlir::Type elementType);
295 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_POINTER; }
296
297 mlir::Type getEleTy() const;
298
299 static mlir::LogicalResult verifyConstructionInvariants(mlir::Location,
300 mlir::Type eleTy);
301 };
302
304 class ReferenceType
305 : public mlir::Type::TypeBase<ReferenceType, mlir::Type,
306 detail::ReferenceTypeStorage> {
307 public:
308 using Base::Base;
309 static ReferenceType get(mlir::Type elementType);
310 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_REFERENCE; }
311
312 mlir::Type getEleTy() const;
313
314 static mlir::LogicalResult verifyConstructionInvariants(mlir::Location,
315 mlir::Type eleTy);
316 };
317
323 class SequenceType : public mlir::Type::TypeBase<SequenceType, mlir::Type,
324 detail::SequenceTypeStorage> {
325 public:
326 using Base::Base;
327 using Extent = int64_t;
328 using Shape = llvm::SmallVector<Extent, 8>;
329
331 static SequenceType get(const Shape &shape, mlir::Type elementType,
332 mlir::AffineMapAttr map = {});
333
335 mlir::Type getEleTy() const;
336
339 Shape getShape() const;
340
341 mlir::AffineMapAttr getLayoutMap() const;
342
344 unsigned getDimension() const { return getShape().size(); }
345
347 unsigned getConstantRows() const;
348
350 bool hasConstantShape() const { return getConstantRows() == getDimension(); }
351
353 bool hasUnknownShape() const { return getShape().empty(); }
354
359 bool hasConstantInterior() const;
360
362 static constexpr Extent getUnknownExtent() { return -1; }
363
364 static bool kindof(unsigned kind) { return kind == TypeKind::FIR_SEQUENCE; }
365
366 static mlir::LogicalResult
367 verifyConstructionInvariants(mlir::Location loc, const Shape &shape,
368 mlir::Type eleTy, mlir::AffineMapAttr map);
369 };
370
371 bool operator==(const SequenceType::Shape &, const SequenceType::Shape &);
372 llvm::hash_code hash_value(const SequenceType::Extent &);
373 llvm::hash_code hash_value(const SequenceType::Shape &);
374
377 class TypeDescType : public mlir::Type::TypeBase<TypeDescType, mlir::Type,
378 detail::TypeDescTypeStorage> {
379 public:
380 using Base::Base;
381 static TypeDescType get(mlir::Type ofType);
382 static constexpr bool kindof(unsigned kind) {
383 return kind == TypeKind::FIR_TYPEDESC;
384 }
385 mlir::Type getOfTy() const;
386
387 static mlir::LogicalResult verifyConstructionInvariants(mlir::Location,
388 mlir::Type ofType);
389 };
390
391 // Derived types
392
396 class RecordType : public mlir::Type::TypeBase<RecordType, mlir::Type,
397 detail::RecordTypeStorage> {
398 public:
399 using Base::Base;
400 using TypePair = std::pair<std::string, mlir::Type>;
401 using TypeList = std::vector<TypePair>;
402
403 llvm::StringRef getName();
404 TypeList getTypeList();
405 TypeList getLenParamList();
406
407 mlir::Type getType(llvm::StringRef ident);
408 mlir::Type getType(unsigned index) {
409 assert(index < getNumFields());
410 return getTypeList()[index].second;
411 }
412 unsigned getNumFields() { return getTypeList().size(); }
413 unsigned getNumLenParams() { return getLenParamList().size(); }
414
415 static RecordType get(mlir::MLIRContext *ctxt, llvm::StringRef name);
416 void finalize(llvm::ArrayRef<TypePair> lenPList,
417 llvm::ArrayRef<TypePair> typeList);
418 static constexpr bool kindof(unsigned kind) { return kind == getId(); }
419 static constexpr unsigned getId() { return TypeKind::FIR_DERIVED; }
420
421 detail::RecordTypeStorage const *uniqueKey() const;
422
423 static mlir::LogicalResult verifyConstructionInvariants(mlir::Location,
424 llvm::StringRef name);
425 };
426
427 mlir::Type parseFirType(FIROpsDialect *, mlir::DialectAsmParser &parser);
428
429 void printFirType(FIROpsDialect *, mlir::Type ty, mlir::DialectAsmPrinter &p);
430
433 void verifyIntegralType(mlir::Type type);
434
436 inline bool isa_real(mlir::Type t) {
437 return t.isa<fir::RealType>() || t.isa<mlir::FloatType>();
438 }
439
441 inline bool isa_integer(mlir::Type t) {
442 return t.isa<mlir::IndexType>() || t.isa<mlir::IntegerType>() ||
443 t.isa<fir::IntType>();
444 }
445
447 inline bool isa_complex(mlir::Type t) {
448 return t.isa<fir::CplxType>() || t.isa<mlir::ComplexType>();
449 }
450
451 } // namespace fir
452
453 #endif // OPTIMIZER_DIALECT_FIRTYPE_H
fir::IntType
Definition: FIRType.h:154
fir::SequenceType::getConstantRows
unsigned getConstantRows() const
Number of rows of constant extent.
Definition: FIRType.cpp:1072
fir::RecordType::get
static RecordType get(mlir::MLIRContext *ctxt, llvm::StringRef name)
Definition: FIRType.cpp:1138
fir::RealType
Definition: FIRType.h:177
mlir
Definition: ConvertType.h:25
fir::FIROpsDialect
FIR dialect.
Definition: FIRDialect.h:19
fir::SequenceType::hasConstantShape
bool hasConstantShape() const
Is the shape of the sequence constant?
Definition: FIRType.h:350
fir::ReferenceType
The type of a reference to an entity in memory.
Definition: FIRType.h:304
fir::SequenceType::getEleTy
mlir::Type getEleTy() const
The element type of this sequence.
Definition: FIRType.cpp:1060
fir::SequenceType::getUnknownExtent
static constexpr Extent getUnknownExtent()
The value -1 represents an unknown extent for a dimension.
Definition: FIRType.h:362
fir::DimsType::getRank
unsigned getRank() const
returns -1 if the rank is unknown
Definition: FIRType.cpp:882
fir::IntrinsicTypeMixin
Boilerplate mixin template.
Definition: FIRType.h:116
fir::TypeDescType::get
static TypeDescType get(mlir::Type ofType)
Definition: FIRType.cpp:1180
fir::SequenceType::hasConstantInterior
bool hasConstantInterior() const
Definition: FIRType.cpp:1086
fir::HeapType
Definition: FIRType.h:263
fir::PointerType
Definition: FIRType.h:290
fir::BoxType
Definition: FIRType.h:192
fir::FieldType
Definition: FIRType.h:251
fir::BoxProcType
Definition: FIRType.h:221
fir::DimsType
Definition: FIRType.h:237
fir::SequenceType::hasUnknownShape
bool hasUnknownShape() const
Does the sequence have unknown shape? (array<* x T>)
Definition: FIRType.h:353
fir::SequenceType::getDimension
unsigned getDimension() const
The number of dimensions of the sequence.
Definition: FIRType.h:344
fir::RecordType
Definition: FIRType.h:396
fir::SequenceType::getShape
Shape getShape() const
Definition: FIRType.cpp:1068
llvm::ArrayRef
Definition: FIRType.h:20
fir::CharacterType
Definition: FIRType.h:126
fir::CplxType
Definition: FIRType.h:139
fir::LenType
Definition: FIRType.h:279
fir::BoxCharType
Definition: FIRType.h:209
fir::SequenceType
Definition: FIRType.h:323
fir::detail::RecordTypeStorage
Derived type storage.
Definition: FIRType.cpp:747
fir::TypeDescType
Definition: FIRType.h:377
fir::LogicalType
Definition: FIRType.h:165
fir::SequenceType::get
static SequenceType get(const Shape &shape, mlir::Type elementType, mlir::AffineMapAttr map={})
Return a sequence type with the specified shape and element type.
Definition: FIRType.cpp:1054
fir::CplxType::getElementType
mlir::Type getElementType() const
Get the corresponding fir.real<k> type.
Definition: FIRType.cpp:918