1//===- FIRTypes.td - FIR types -----------------------------*- tablegen -*-===// 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// This file declares the FIR dialect types. 10// 11//===----------------------------------------------------------------------===// 12 13#ifndef FIR_DIALECT_FIR_TYPES 14#define FIR_DIALECT_FIR_TYPES 15 16include "flang/Optimizer/Dialect/FIRDialect.td" 17 18//===----------------------------------------------------------------------===// 19// FIR Types 20//===----------------------------------------------------------------------===// 21 22class FIR_Type<string name, string typeMnemonic> : TypeDef<fir_Dialect, name> { 23 let mnemonic = typeMnemonic; 24} 25 26def fir_Type : Type<CPred<"fir::isa_fir_or_std_type($_self)">, 27 "FIR dialect type">; 28 29def fir_BoxCharType : FIR_Type<"BoxChar", "boxchar"> { 30 let summary = "CHARACTER type descriptor."; 31 32 let description = [{ 33 The type of a pair that describes a CHARACTER variable. Specifically, a 34 CHARACTER consists of a reference to a buffer (the string value) and a LEN 35 type parameter (the runtime length of the buffer). 36 }]; 37 38 let parameters = (ins "KindTy":$kind); 39 40 let genAccessors = 1; 41 42 let extraClassDeclaration = [{ 43 using KindTy = unsigned; 44 45 // a !fir.boxchar<k> always wraps a !fir.char<k, ?> 46 CharacterType getElementType(mlir::MLIRContext *context) const; 47 48 CharacterType getEleTy() const; 49 }]; 50} 51 52def fir_BoxProcType : FIR_Type<"BoxProc", "boxproc"> { 53 let summary = ""; 54 55 let description = [{ 56 The type of a pair that describes a PROCEDURE reference. Pointers to 57 internal procedures must carry an additional reference to the host's 58 variables that are referenced. 59 }]; 60 61 let parameters = (ins "mlir::Type":$eleTy); 62 63 let genVerifyDecl = 1; 64} 65 66def fir_BoxType : FIR_Type<"Box", "box"> { 67 let summary = "The type of a Fortran descriptor"; 68 69 let description = [{ 70 Descriptors are tuples of information that describe an entity being passed 71 from a calling context. This information might include (but is not limited 72 to) whether the entity is an array, its size, or what type it has. 73 }]; 74 75 let parameters = (ins "mlir::Type":$eleTy, "mlir::AffineMapAttr":$map); 76 77 let skipDefaultBuilders = 1; 78 79 let builders = [ 80 TypeBuilderWithInferredContext<(ins 81 "mlir::Type":$eleTy, 82 CArg<"mlir::AffineMapAttr", "{}">:$map), [{ 83 return Base::get(eleTy.getContext(), eleTy, map); 84 }]>, 85 ]; 86 87 let extraClassDeclaration = [{ 88 mlir::Type getElementType() const { return getEleTy(); } 89 mlir::AffineMapAttr getLayoutMap() const { return getMap(); } 90 }]; 91 92 let genVerifyDecl = 1; 93} 94 95def fir_CharacterType : FIR_Type<"Character", "char"> { 96 let summary = "FIR character type"; 97 98 let description = [{ 99 Model of the Fortran CHARACTER intrinsic type, including the KIND type 100 parameter. The model optionally includes a LEN type parameter. A 101 CharacterType is thus the type of both a single character value and a 102 character with a LEN parameter. 103 }]; 104 105 let parameters = (ins "KindTy":$FKind, "CharacterType::LenType":$len); 106 107 let extraClassDeclaration = [{ 108 using KindTy = unsigned; 109 using LenType = std::int64_t; 110 111 /// Return unknown length Character type. e.g., CHARACTER(LEN=n). 112 static CharacterType getUnknownLen(mlir::MLIRContext *ctxt, KindTy kind) { 113 return get(ctxt, kind, unknownLen()); 114 } 115 116 /// Return length 1 Character type. e.g., CHARACTER(LEN=1). 117 static CharacterType getSingleton(mlir::MLIRContext *ctxt, KindTy kind) { 118 return get(ctxt, kind, singleton()); 119 } 120 121 /// Character is a singleton and has a LEN of 1. 122 static constexpr LenType singleton() { return 1; } 123 124 /// Character has a LEN value which is not a compile-time known constant. 125 static constexpr LenType unknownLen() { return -1; } 126 127 /// Character LEN is a runtime value. 128 bool hasDynamicLen() { return getLen() == unknownLen(); } 129 130 /// Character LEN is a compile-time cpnstant value. 131 bool hasConstantLen() { return !hasDynamicLen(); } 132 }]; 133} 134 135def fir_ComplexType : FIR_Type<"Complex", "complex"> { 136 let summary = "Complex type"; 137 138 let description = [{ 139 Model of a Fortran COMPLEX intrinsic type, including the KIND type 140 parameter. COMPLEX is a floating point type with a real and imaginary 141 member. 142 }]; 143 144 let parameters = (ins "KindTy":$fKind); 145 146 let extraClassDeclaration = [{ 147 using KindTy = unsigned; 148 149 mlir::Type getElementType() const; 150 }]; 151} 152 153def fir_FieldType : FIR_Type<"Field", "field"> { 154 let summary = "A field (in a RecordType) argument's type"; 155 156 let description = [{ 157 The type of a field name. Implementations may defer the layout of a Fortran 158 derived type until runtime. This implies that the runtime must be able to 159 determine the offset of fields within the entity. 160 }]; 161} 162 163def fir_HeapType : FIR_Type<"Heap", "heap"> { 164 let summary = "Reference to an ALLOCATABLE attribute type"; 165 166 let description = [{ 167 The type of a heap pointer. Fortran entities with the ALLOCATABLE attribute 168 may be allocated on the heap at runtime. These pointers are explicitly 169 distinguished to disallow the composition of multiple levels of 170 indirection. For example, an ALLOCATABLE POINTER is invalid. 171 }]; 172 173 let parameters = (ins "mlir::Type":$eleTy); 174 175 let genVerifyDecl = 1; 176 177 let skipDefaultBuilders = 1; 178 179 let builders = [ 180 TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{ 181 assert(singleIndirectionLevel(elementType) && "invalid element type"); 182 return Base::get(elementType.getContext(), elementType); 183 }]>, 184 ]; 185} 186 187def fir_IntegerType : FIR_Type<"Integer", "int"> { 188 let summary = "FIR integer type"; 189 190 let description = [{ 191 Model of a Fortran INTEGER intrinsic type, including the KIND type 192 parameter. 193 }]; 194 195 let parameters = (ins "KindTy":$fKind); 196 197 let extraClassDeclaration = [{ 198 using KindTy = unsigned; 199 }]; 200} 201 202def fir_LenType : FIR_Type<"Len", "len"> { 203 let summary = "A LEN parameter (in a RecordType) argument's type"; 204 205 let description = [{ 206 The type of a LEN parameter name. Implementations may defer the layout of a 207 Fortran derived type until runtime. This implies that the runtime must be 208 able to determine the offset of LEN type parameters related to an entity. 209 }]; 210} 211 212def fir_LogicalType : FIR_Type<"Logical", "logical"> { 213 let summary = "FIR logical type"; 214 215 let description = [{ 216 Model of a Fortran LOGICAL intrinsic type, including the KIND type 217 parameter. 218 }]; 219 220 let parameters = (ins "KindTy":$fKind); 221 222 let extraClassDeclaration = [{ 223 using KindTy = unsigned; 224 }]; 225} 226 227def fir_PointerType : FIR_Type<"Pointer", "ptr"> { 228 let summary = "Reference to a POINTER attribute type"; 229 230 let description = [{ 231 The type of entities with the POINTER attribute. These pointers are 232 explicitly distinguished to disallow the composition of multiple levels of 233 indirection. For example, an ALLOCATABLE POINTER is invalid. 234 }]; 235 236 let parameters = (ins "mlir::Type":$eleTy); 237 238 let genVerifyDecl = 1; 239 240 let skipDefaultBuilders = 1; 241 242 let builders = [ 243 TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{ 244 assert(singleIndirectionLevel(elementType) && "invalid element type"); 245 return Base::get(elementType.getContext(), elementType); 246 }]>, 247 ]; 248 249 let extraClassDeclaration = [{ 250 mlir::Type getElementType() const { return getEleTy(); } 251 }]; 252} 253 254def fir_RealType : FIR_Type<"Real", "real"> { 255 let summary = "FIR real type"; 256 257 let description = [{ 258 Model of a Fortran REAL (and DOUBLE PRECISION) intrinsic type, including the 259 KIND type parameter. 260 }]; 261 262 let parameters = (ins "KindTy":$fKind); 263 264 let extraClassDeclaration = [{ 265 using KindTy = unsigned; 266 }]; 267 268 let genVerifyDecl = 1; 269} 270 271def fir_RecordType : FIR_Type<"Record", "type"> { 272 let summary = "FIR derived type"; 273 274 let description = [{ 275 Model of Fortran's derived type, TYPE. The name of the TYPE includes any 276 KIND type parameters. The record includes runtime slots for LEN type 277 parameters and for data components. 278 }]; 279 280 let parameters = (ins StringRefParameter<"name">:$name); 281 282 let genVerifyDecl = 1; 283 let genStorageClass = 0; 284 285 let extraClassDeclaration = [{ 286 using TypePair = std::pair<std::string, mlir::Type>; 287 using TypeList = std::vector<TypePair>; 288 TypeList getTypeList() const; 289 TypeList getLenParamList() const; 290 291 mlir::Type getType(llvm::StringRef ident); 292 // Returns the index of the field \p ident in the type list. 293 // Returns maximum unsigned if ident is not a field of this RecordType. 294 unsigned getFieldIndex(llvm::StringRef ident); 295 mlir::Type getType(unsigned index) { 296 assert(index < getNumFields()); 297 return getTypeList()[index].second; 298 } 299 unsigned getNumFields() { return getTypeList().size(); } 300 unsigned getNumLenParams() { return getLenParamList().size(); } 301 302 void finalize(llvm::ArrayRef<TypePair> lenPList, 303 llvm::ArrayRef<TypePair> typeList); 304 305 detail::RecordTypeStorage const *uniqueKey() const; 306 }]; 307} 308 309def fir_ReferenceType : FIR_Type<"Reference", "ref"> { 310 let summary = "Reference to an entity type"; 311 312 let description = [{ 313 The type of a reference to an entity in memory. 314 }]; 315 316 let parameters = (ins "mlir::Type":$eleTy); 317 318 let skipDefaultBuilders = 1; 319 320 let builders = [ 321 TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{ 322 return Base::get(elementType.getContext(), elementType); 323 }]>, 324 ]; 325 326 let extraClassDeclaration = [{ 327 mlir::Type getElementType() const { return getEleTy(); } 328 }]; 329 330 let genVerifyDecl = 1; 331} 332 333def fir_ShapeType : FIR_Type<"Shape", "shape"> { 334 let summary = "shape of a multidimensional array object"; 335 336 let description = [{ 337 Type of a vector of runtime values that define the shape of a 338 multidimensional array object. The vector is the extents of each array 339 dimension. The rank of a ShapeType must be at least 1. 340 }]; 341 342 let parameters = (ins "unsigned":$rank); 343} 344 345def fir_ShapeShiftType : FIR_Type<"ShapeShift", "shapeshift"> { 346 let summary = "shape and origin of a multidimensional array object"; 347 348 let description = [{ 349 Type of a vector of runtime values that define the shape and the origin of a 350 multidimensional array object. The vector is of pairs, origin offset and 351 extent, of each array dimension. The rank of a ShapeShiftType must be at 352 least 1. 353 }]; 354 355 let parameters = (ins "unsigned":$rank); 356} 357 358def fir_ShiftType : FIR_Type<"Shift", "shift"> { 359 let summary = "lower bounds of a multidimensional array object"; 360 361 let description = [{ 362 Type of a vector of runtime values that define the lower bounds of a 363 multidimensional array object. The vector is the lower bounds of each array 364 dimension. The rank of a ShiftType must be at least 1. 365 }]; 366 367 let parameters = (ins "unsigned":$rank); 368 369 let extraClassDeclaration = [{ 370 using KindTy = unsigned; 371 372 // a !fir.boxchar<k> always wraps a !fir.char<k, ?> 373 CharacterType getElementType(mlir::MLIRContext *context) const; 374 375 CharacterType getEleTy() const; 376 }]; 377} 378 379def fir_SequenceType : FIR_Type<"Sequence", "array"> { 380 let summary = "FIR array type"; 381 382 let description = [{ 383 A sequence type is a multi-dimensional array of values. The sequence type 384 may have an unknown number of dimensions or the extent of dimensions may be 385 unknown. A sequence type models a Fortran array entity, giving it a type in 386 FIR. A sequence type is assumed to be stored in a column-major order, which 387 differs from LLVM IR and other dialects of MLIR. 388 }]; 389 390 let parameters = (ins 391 ArrayRefParameter<"int64_t", "Sequence shape">:$shape, 392 "mlir::Type":$eleTy, 393 "mlir::AffineMapAttr":$layoutMap 394 ); 395 396 let genVerifyDecl = 1; 397 398 let builders = [ 399 TypeBuilderWithInferredContext<(ins 400 "llvm::ArrayRef<int64_t>":$shape, 401 "mlir::Type":$eleTy), [{ 402 return get(eleTy.getContext(), shape, eleTy, {}); 403 }]>, 404 ]; 405 406 let extraClassDeclaration = [{ 407 using Extent = int64_t; 408 using Shape = llvm::SmallVector<Extent, 8>; 409 using ShapeRef = llvm::ArrayRef<int64_t>; 410 unsigned getConstantRows() const; 411 412 // The number of dimensions of the sequence 413 unsigned getDimension() const { return getShape().size(); } 414 415 // Is the interior of the sequence constant? Check if the array is 416 // one of constant shape (`array<C...xCxT>`), unknown shape 417 // (`array<*xT>`), or rows with shape and ending with column(s) of 418 // unknown extent (`array<C...xCx?...x?xT>`). 419 bool hasConstantInterior() const; 420 421 // Is the shape of the sequence constant? 422 bool hasConstantShape() const { return getConstantRows() == getDimension(); } 423 424 // Does the sequence have unknown shape? (`array<* x T>`) 425 bool hasUnknownShape() const { return getShape().empty(); } 426 427 // The value `-1` represents an unknown extent for a dimension 428 static constexpr Extent getUnknownExtent() { return -1; } 429 }]; 430} 431 432def fir_SliceType : FIR_Type<"Slice", "slice"> { 433 let summary = "FIR slice"; 434 435 let description = [{ 436 Type of a vector that represents an array slice operation on an array. 437 Fortran slices are triples of lower bound, upper bound, and stride. The rank 438 of a SliceType must be at least 1. 439 }]; 440 441 let parameters = (ins "unsigned":$rank); 442} 443 444def fir_TypeDescType : FIR_Type<"TypeDesc", "tdesc"> { 445 let summary = "FIR Type descriptor type"; 446 447 let description = [{ 448 The type of a type descriptor object. The runtime may generate type 449 descriptor objects to determine the type of an entity at runtime, etc. 450 }]; 451 452 let parameters = (ins "mlir::Type":$ofTy); 453 454 let genVerifyDecl = 1; 455 456 let skipDefaultBuilders = 1; 457 458 let builders = [ 459 TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{ 460 return Base::get(elementType.getContext(), elementType); 461 }]>, 462 ]; 463} 464 465def fir_VectorType : FIR_Type<"Vector", "vector"> { 466 let summary = "FIR vector type"; 467 468 let description = [{ 469 Replacement for the builtin vector type. 470 The FIR vector type is always rank one. It's size is always a constant. 471 A vector's element type must be real or integer. 472 }]; 473 474 let parameters = (ins "uint64_t":$len, "mlir::Type":$eleTy); 475 476 let genVerifyDecl = 1; 477 478 let extraClassDeclaration = [{ 479 static bool isValidElementType(mlir::Type t); 480 }]; 481 482 let skipDefaultBuilders = 1; 483 484 let builders = [ 485 TypeBuilderWithInferredContext<(ins 486 "uint64_t":$len, 487 "mlir::Type":$eleTy), [{ 488 return Base::get(eleTy.getContext(), len, eleTy); 489 }]>, 490 ]; 491} 492 493def fir_VoidType : FIR_Type<"Void", "void"> { 494 let genStorageClass = 0; 495} 496 497// Generalized FIR and standard dialect types representing intrinsic types 498def AnyIntegerLike : TypeConstraint<Or<[SignlessIntegerLike.predicate, 499 AnySignedInteger.predicate, fir_IntegerType.predicate]>, "any integer">; 500def AnyLogicalLike : TypeConstraint<Or<[BoolLike.predicate, 501 fir_LogicalType.predicate]>, "any logical">; 502def AnyRealLike : TypeConstraint<Or<[FloatLike.predicate, 503 fir_RealType.predicate]>, "any real">; 504def AnyIntegerType : Type<AnyIntegerLike.predicate, "any integer">; 505 506// Composable types 507def AnyCompositeLike : TypeConstraint<Or<[fir_RecordType.predicate, 508 fir_SequenceType.predicate, fir_ComplexType.predicate, 509 fir_VectorType.predicate, IsTupleTypePred, fir_CharacterType.predicate]>, 510 "any composite">; 511 512// Reference types 513def AnyReferenceLike : TypeConstraint<Or<[fir_ReferenceType.predicate, 514 fir_HeapType.predicate, fir_PointerType.predicate]>, "any reference">; 515 516def AnyBoxLike : TypeConstraint<Or<[fir_BoxType.predicate, 517 fir_BoxCharType.predicate, fir_BoxProcType.predicate]>, "any box">; 518 519def AnyRefOrBoxLike : TypeConstraint<Or<[AnyReferenceLike.predicate, 520 AnyBoxLike.predicate]>, 521 "any reference or box like">; 522def AnyRefOrBox : TypeConstraint<Or<[fir_ReferenceType.predicate, 523 fir_HeapType.predicate, fir_PointerType.predicate, fir_BoxType.predicate]>, 524 "any reference or box">; 525 526def AnyShapeLike : TypeConstraint<Or<[fir_ShapeType.predicate, 527 fir_ShapeShiftType.predicate]>, "any legal shape type">; 528def AnyShapeType : Type<AnyShapeLike.predicate, "any legal shape type">; 529def AnyShapeOrShiftLike : TypeConstraint<Or<[fir_ShapeType.predicate, 530 fir_ShapeShiftType.predicate, fir_ShiftType.predicate]>, 531 "any legal shape or shift type">; 532def AnyShapeOrShiftType : Type<AnyShapeOrShiftLike.predicate, 533 "any legal shape or shift type">; 534 535def AnyEmboxLike : TypeConstraint<Or<[AnySignlessInteger.predicate, 536 Index.predicate, fir_IntegerType.predicate]>, 537 "any legal embox argument type">; 538def AnyEmboxArg : Type<AnyEmboxLike.predicate, "embox argument type">; 539 540def AnyComponentLike : TypeConstraint<Or<[AnySignlessInteger.predicate, 541 Index.predicate, fir_IntegerType.predicate, fir_FieldType.predicate]>, 542 "any coordinate index">; 543def AnyComponentType : Type<AnyComponentLike.predicate, "coordinate type">; 544 545def AnyCoordinateLike : TypeConstraint<Or<[AnySignlessInteger.predicate, 546 Index.predicate, fir_IntegerType.predicate, fir_FieldType.predicate, 547 fir_LenType.predicate]>, "any coordinate index">; 548def AnyCoordinateType : Type<AnyCoordinateLike.predicate, "coordinate type">; 549 550// The legal types of global symbols 551def AnyAddressableLike : TypeConstraint<Or<[fir_ReferenceType.predicate, 552 FunctionType.predicate]>, "any addressable">; 553 554#endif // FIR_DIALECT_FIR_TYPES 555