xref: /llvm-project/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h (revision 1ca392764a0df5a9c263b89b97b882766ed4b3e7)
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