1 //===- HLFIRDialect.h - High Level Fortran IR dialect -----------*- 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 // This file defines the HLFIR dialect that models Fortran expressions and 10 // assignments without requiring storage allocation and manipulations. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H 15 #define FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H 16 17 #include "flang/Optimizer/Dialect/FIRType.h" 18 #include "mlir/IR/Dialect.h" 19 20 namespace hlfir { 21 /// Is this a type that can be used for an HLFIR variable ? 22 bool isFortranVariableType(mlir::Type); 23 bool isFortranScalarCharacterType(mlir::Type); 24 bool isFortranScalarCharacterExprType(mlir::Type); 25 bool isFortranArrayCharacterExprType(mlir::Type); 26 } // namespace hlfir 27 28 #include "flang/Optimizer/HLFIR/HLFIRDialect.h.inc" 29 30 #include "flang/Optimizer/HLFIR/HLFIREnums.h.inc" 31 32 #define GET_TYPEDEF_CLASSES 33 #include "flang/Optimizer/HLFIR/HLFIRTypes.h.inc" 34 35 #define GET_ATTRDEF_CLASSES 36 #include "flang/Optimizer/HLFIR/HLFIRAttributes.h.inc" 37 38 namespace hlfir { 39 /// Get the element type of a Fortran entity type. 40 inline mlir::Type getFortranElementType(mlir::Type type) { 41 type = fir::unwrapSequenceType( 42 fir::unwrapPassByRefType(fir::unwrapRefType(type))); 43 if (auto exprType = mlir::dyn_cast<hlfir::ExprType>(type)) 44 return exprType.getEleTy(); 45 if (auto boxCharType = mlir::dyn_cast<fir::BoxCharType>(type)) 46 return boxCharType.getEleTy(); 47 return type; 48 } 49 50 /// If this is the type of a Fortran array entity, get the related 51 /// fir.array type. Otherwise, returns the Fortran element typeof the entity. 52 inline mlir::Type getFortranElementOrSequenceType(mlir::Type type) { 53 type = fir::unwrapPassByRefType(fir::unwrapRefType(type)); 54 if (auto exprType = mlir::dyn_cast<hlfir::ExprType>(type)) { 55 if (exprType.isArray()) 56 return fir::SequenceType::get(exprType.getShape(), exprType.getEleTy()); 57 return exprType.getEleTy(); 58 } 59 if (auto boxCharType = mlir::dyn_cast<fir::BoxCharType>(type)) 60 return boxCharType.getEleTy(); 61 return type; 62 } 63 64 /// Build the hlfir.expr type for the value held in a variable of type \p 65 /// variableType. 66 mlir::Type getExprType(mlir::Type variableType); 67 68 /// Is this a fir.box or fir.class address type? 69 inline bool isBoxAddressType(mlir::Type type) { 70 type = fir::dyn_cast_ptrEleTy(type); 71 return type && mlir::isa<fir::BaseBoxType>(type); 72 } 73 74 /// Is this a fir.box or fir.class address or value type? 75 inline bool isBoxAddressOrValueType(mlir::Type type) { 76 return mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(type)); 77 } 78 79 inline bool isPolymorphicType(mlir::Type type) { 80 if (auto exprType = mlir::dyn_cast<hlfir::ExprType>(type)) 81 return exprType.isPolymorphic(); 82 return fir::isPolymorphicType(type); 83 } 84 85 /// Is this an SSA value type for the value of a Fortran procedure 86 /// designator ? 87 inline bool isFortranProcedureValue(mlir::Type type) { 88 return mlir::isa<fir::BoxProcType>(type) || 89 (mlir::isa<mlir::TupleType>(type) && 90 fir::isCharacterProcedureTuple(type, /*acceptRawFunc=*/false)); 91 } 92 93 /// Is this an SSA value type for the value of a Fortran expression? 94 inline bool isFortranValueType(mlir::Type type) { 95 return mlir::isa<hlfir::ExprType>(type) || fir::isa_trivial(type) || 96 isFortranProcedureValue(type); 97 } 98 99 /// Is this the value of a Fortran expression in an SSA value form? 100 inline bool isFortranValue(mlir::Value value) { 101 return isFortranValueType(value.getType()); 102 } 103 104 /// Is this a Fortran variable? 105 /// Note that by "variable", it must be understood that the mlir::Value is 106 /// a memory value of a storage that can be reason about as a Fortran object 107 /// (its bounds, shape, and type parameters, if any, are retrievable). 108 /// This does not imply that the mlir::Value points to a variable from the 109 /// original source or can be legally defined: temporaries created to store 110 /// expression values are considered to be variables, and so are PARAMETERs 111 /// global constant address. 112 inline bool isFortranEntity(mlir::Value value) { 113 return isFortranValue(value) || isFortranVariableType(value.getType()); 114 } 115 116 bool isFortranScalarNumericalType(mlir::Type); 117 bool isFortranNumericalArrayObject(mlir::Type); 118 bool isFortranNumericalOrLogicalArrayObject(mlir::Type); 119 bool isFortranArrayObject(mlir::Type); 120 bool isFortranLogicalArrayObject(mlir::Type); 121 bool isPassByRefOrIntegerType(mlir::Type); 122 bool isI1Type(mlir::Type); 123 // scalar i1 or logical, or sequence of logical (via (boxed?) array or expr) 124 bool isMaskArgument(mlir::Type); 125 bool isPolymorphicObject(mlir::Type); 126 127 /// If an expression's extents are known at compile time, generate a fir.shape 128 /// for this expression. Otherwise return {} 129 mlir::Value genExprShape(mlir::OpBuilder &builder, const mlir::Location &loc, 130 const hlfir::ExprType &expr); 131 132 /// Return true iff `ty` may have allocatable component. 133 /// TODO: this actually belongs to FIRType.cpp, but the method's implementation 134 /// depends on HLFIRDialect component. FIRType.cpp itself is part of FIRDialect 135 /// that cannot depend on HLFIRBuilder (there will be a cyclic dependency). 136 /// This has to be cleaned up, when HLFIR is the default. 137 bool mayHaveAllocatableComponent(mlir::Type ty); 138 139 /// Scalar integer or a sequence of integers (via boxed array or expr). 140 bool isFortranIntegerScalarOrArrayObject(mlir::Type type); 141 142 } // namespace hlfir 143 144 #endif // FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H 145