Warning: This file is not a C or C++ file. It does not have highlighting.

1//===-- Lower/ConvertExpr.h -- lowering of expressions ----------*- 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// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10//
11//===----------------------------------------------------------------------===//
12///
13/// Implements the conversion from Fortran::evaluate::Expr trees to FIR.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef FORTRAN_LOWER_CONVERTEXPR_H
18#define FORTRAN_LOWER_CONVERTEXPR_H
19
20#include "flang/Lower/Support/Utils.h"
21#include "flang/Optimizer/Builder/BoxValue.h"
22#include "flang/Optimizer/Builder/FIRBuilder.h"
23#include <optional>
24
25namespace mlir {
26class Location;
27class Value;
28} // namespace mlir
29
30namespace fir {
31class AllocMemOp;
32class ArrayLoadOp;
33class ShapeOp;
34} // namespace fir
35
36namespace Fortran::lower {
37
38class AbstractConverter;
39class ExplicitIterSpace;
40class ImplicitIterSpace;
41class StatementContext;
42class SymMap;
43
44/// Create an extended expression value.
45fir::ExtendedValue createSomeExtendedExpression(mlir::Location loc,
46 AbstractConverter &converter,
47 const SomeExpr &expr,
48 SymMap &symMap,
49 StatementContext &stmtCtx);
50
51/// Create the IR for the expression \p expr in an initialization context.
52/// Expressions that appear in initializers may not allocate temporaries, do not
53/// have a stack, etc.
54fir::ExtendedValue createSomeInitializerExpression(mlir::Location loc,
55 AbstractConverter &converter,
56 const SomeExpr &expr,
57 SymMap &symMap,
58 StatementContext &stmtCtx);
59
60/// Create an extended expression address.
61fir::ExtendedValue createSomeExtendedAddress(mlir::Location loc,
62 AbstractConverter &converter,
63 const SomeExpr &expr,
64 SymMap &symMap,
65 StatementContext &stmtCtx);
66
67/// Create an address in an initializer context. Must be a constant or a symbol
68/// to be resolved at link-time. Expressions that appear in initializers may not
69/// allocate temporaries, do not have a stack, etc.
70fir::ExtendedValue createInitializerAddress(mlir::Location loc,
71 AbstractConverter &converter,
72 const SomeExpr &expr,
73 SymMap &symMap,
74 StatementContext &stmtCtx);
75
76/// Create the address of the box.
77/// \p expr must be the designator of an allocatable/pointer entity.
78fir::MutableBoxValue createMutableBox(mlir::Location loc,
79 AbstractConverter &converter,
80 const SomeExpr &expr, SymMap &symMap);
81
82/// Return true iff the expression is pointing to a parent component.
83bool isParentComponent(const SomeExpr &expr);
84
85/// Update the extended value to represent the parent component.
86fir::ExtendedValue updateBoxForParentComponent(AbstractConverter &converter,
87 fir::ExtendedValue exv,
88 const SomeExpr &expr);
89
90/// Create a fir::BoxValue describing the value of \p expr.
91/// If \p expr is a variable without vector subscripts, the fir::BoxValue
92/// described the variable storage. Otherwise, the created fir::BoxValue
93/// describes a temporary storage containing \p expr evaluation, and clean-up
94/// for the temporary is added to the provided StatementContext \p stmtCtx.
95fir::ExtendedValue createBoxValue(mlir::Location loc,
96 AbstractConverter &converter,
97 const SomeExpr &expr, SymMap &symMap,
98 StatementContext &stmtCtx);
99
100/// Lower an array assignment expression.
101///
102/// 1. Evaluate the lhs to determine the rank and how to form the ArrayLoad
103/// (e.g., if there is a slicing op).
104/// 2. Scan the rhs, creating the ArrayLoads and evaluate the scalar subparts to
105/// be added to the map.
106/// 3. Create the loop nest and evaluate the elemental expression, threading the
107/// results.
108/// 4. Copy the resulting array back with ArrayMergeStore to the lhs as
109/// determined per step 1.
110void createSomeArrayAssignment(AbstractConverter &converter,
111 const SomeExpr &lhs, const SomeExpr &rhs,
112 SymMap &symMap, StatementContext &stmtCtx);
113
114/// Lower an array assignment expression with a pre-evaluated left hand side.
115///
116/// 1. Scan the rhs, creating the ArrayLoads and evaluate the scalar subparts to
117/// be added to the map.
118/// 2. Create the loop nest and evaluate the elemental expression, threading the
119/// results.
120/// 3. Copy the resulting array back with ArrayMergeStore to the lhs as
121/// determined per step 1.
122void createSomeArrayAssignment(AbstractConverter &converter,
123 const fir::ExtendedValue &lhs,
124 const SomeExpr &rhs, SymMap &symMap,
125 StatementContext &stmtCtx);
126
127/// Lower an array assignment expression with pre-evaluated left and right
128/// hand sides. This implements an array copy taking into account
129/// non-contiguity and potential overlaps.
130void createSomeArrayAssignment(AbstractConverter &converter,
131 const fir::ExtendedValue &lhs,
132 const fir::ExtendedValue &rhs, SymMap &symMap,
133 StatementContext &stmtCtx);
134
135/// Common entry point for both explicit iteration spaces and implicit iteration
136/// spaces with masks.
137///
138/// For an implicit iteration space with masking, lowers an array assignment
139/// expression with masking expression(s).
140///
141/// 1. Evaluate the lhs to determine the rank and how to form the ArrayLoad
142/// (e.g., if there is a slicing op).
143/// 2. Scan the rhs, creating the ArrayLoads and evaluate the scalar subparts to
144/// be added to the map.
145/// 3. Create the loop nest.
146/// 4. Create the masking condition. Step 5 is conditionally executed only when
147/// the mask condition evaluates to true.
148/// 5. Evaluate the elemental expression, threading the results.
149/// 6. Copy the resulting array back with ArrayMergeStore to the lhs as
150/// determined per step 1.
151///
152/// For an explicit iteration space, lower a scalar or array assignment
153/// expression with a user-defined iteration space and possibly with masking
154/// expression(s).
155///
156/// If the expression is scalar, then the assignment is an array assignment but
157/// the array accesses are explicitly defined by the user and not implied for
158/// each element in the array. Mask expressions are optional.
159///
160/// If the expression has rank, then the assignment has a combined user-defined
161/// iteration space as well as a inner (subordinate) implied iteration
162/// space. The implied iteration space may include WHERE conditions, `masks`.
163void createAnyMaskedArrayAssignment(AbstractConverter &converter,
164 const SomeExpr &lhs, const SomeExpr &rhs,
165 ExplicitIterSpace &explicitIterSpace,
166 ImplicitIterSpace &implicitIterSpace,
167 SymMap &symMap, StatementContext &stmtCtx);
168
169/// Lower an assignment to an allocatable array, allocating the array if
170/// it is not allocated yet or reallocation it if it does not conform
171/// with the right hand side.
172void createAllocatableArrayAssignment(AbstractConverter &converter,
173 const SomeExpr &lhs, const SomeExpr &rhs,
174 ExplicitIterSpace &explicitIterSpace,
175 ImplicitIterSpace &implicitIterSpace,
176 SymMap &symMap,
177 StatementContext &stmtCtx);
178
179/// Lower a pointer assignment in an explicit iteration space. The explicit
180/// space iterates over a data structure with a type of `!fir.array<...
181/// !fir.box<!fir.ptr<T>> ...>`. Lower the assignment by copying the rhs box
182/// value to each array element.
183void createArrayOfPointerAssignment(
184 AbstractConverter &converter, const SomeExpr &lhs, const SomeExpr &rhs,
185 ExplicitIterSpace &explicitIterSpace, ImplicitIterSpace &implicitIterSpace,
186 const llvm::SmallVector<mlir::Value> &lbounds,
187 std::optional<llvm::SmallVector<mlir::Value>> ubounds, SymMap &symMap,
188 StatementContext &stmtCtx);
189
190/// Lower an array expression with "parallel" semantics. Such a rhs expression
191/// is fully evaluated prior to being assigned back to a temporary array.
192fir::ExtendedValue createSomeArrayTempValue(AbstractConverter &converter,
193 const SomeExpr &expr,
194 SymMap &symMap,
195 StatementContext &stmtCtx);
196
197/// Somewhat similar to createSomeArrayTempValue, but the temporary buffer is
198/// allocated lazily (inside the loops instead of before the loops) to
199/// accomodate buffers with shapes that cannot be precomputed. In fact, the
200/// buffer need not even be hyperrectangular. The buffer may be created as an
201/// instance of a ragged array, which may be useful if an array's extents are
202/// functions of other loop indices. The ragged array structure is built with \p
203/// raggedHeader being the root header variable. The header is a tuple of
204/// `{rank, data-is-headers, [data]*, [extents]*}`, which is built recursively.
205/// The base header, \p raggedHeader, must be initialized to zeros.
206void createLazyArrayTempValue(AbstractConverter &converter,
207 const SomeExpr &expr, mlir::Value raggedHeader,
208 SymMap &symMap, StatementContext &stmtCtx);
209
210/// Lower an array expression to a value of type box. The expression must be a
211/// variable.
212fir::ExtendedValue createSomeArrayBox(AbstractConverter &converter,
213 const SomeExpr &expr, SymMap &symMap,
214 StatementContext &stmtCtx);
215
216/// Lower a subroutine call. This handles both elemental and non elemental
217/// subroutines. \p isUserDefAssignment must be set if this is called in the
218/// context of a user defined assignment. For subroutines with alternate
219/// returns, the returned value indicates which label the code should jump to.
220/// The returned value is null otherwise.
221mlir::Value createSubroutineCall(AbstractConverter &converter,
222 const evaluate::ProcedureRef &call,
223 ExplicitIterSpace &explicitIterSpace,
224 ImplicitIterSpace &implicitIterSpace,
225 SymMap &symMap, StatementContext &stmtCtx,
226 bool isUserDefAssignment);
227
228mlir::Value addCrayPointerInst(mlir::Location loc, fir::FirOpBuilder &builder,
229 mlir::Value ptrVal, mlir::Type ptrTy,
230 mlir::Type pteTy);
231} // namespace Fortran::lower
232
233#endif // FORTRAN_LOWER_CONVERTEXPR_H
234

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of flang/include/flang/Lower/ConvertExpr.h