Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- VectorSubscripts.h -- vector subscripts tools -----------*- 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 | /// \file |
10 | /// \brief Defines a compiler internal representation for lowered designators |
11 | /// containing vector subscripts. This representation allows working on such |
12 | /// designators in custom ways while ensuring the designator subscripts are |
13 | /// only evaluated once. It is mainly intended for cases that do not fit in |
14 | /// the array expression lowering framework like input IO in presence of |
15 | /// vector subscripts. |
16 | /// |
17 | //===----------------------------------------------------------------------===// |
18 | |
19 | #ifndef FORTRAN_LOWER_VECTORSUBSCRIPTS_H |
20 | #define FORTRAN_LOWER_VECTORSUBSCRIPTS_H |
21 | |
22 | #include "flang/Optimizer/Builder/BoxValue.h" |
23 | |
24 | namespace fir { |
25 | class FirOpBuilder; |
26 | } |
27 | |
28 | namespace Fortran { |
29 | |
30 | namespace evaluate { |
31 | template <typename> |
32 | class Expr; |
33 | struct SomeType; |
34 | } // namespace evaluate |
35 | |
36 | namespace lower { |
37 | |
38 | class AbstractConverter; |
39 | class StatementContext; |
40 | |
41 | /// VectorSubscriptBox is a lowered representation for any Designator<T> that |
42 | /// contain at least one vector subscript. |
43 | /// |
44 | /// A designator `x%a(i,j)%b(1:foo():1, vector, k)%c%d(m)%e1 |
45 | /// Is lowered into: |
46 | /// - an ExtendedValue for ranked base (x%a(i,j)%b) |
47 | /// - mlir:Values and ExtendedValues for the triplet, vector subscript and |
48 | /// scalar subscripts of the ranked array reference (1:foo():1, vector, k) |
49 | /// - a list of fir.field_index and scalar integers mlir::Value for the |
50 | /// component |
51 | /// path at the right of the ranked array ref (%c%d(m)%e). |
52 | /// |
53 | /// This representation allows later creating loops over the designator elements |
54 | /// and fir.array_coor to get the element addresses without re-evaluating any |
55 | /// sub-expressions. |
56 | class VectorSubscriptBox { |
57 | public: |
58 | /// Type of the callbacks that can be passed to work with the element |
59 | /// addresses. |
60 | using ElementalGenerator = std::function<void(const fir::ExtendedValue &)>; |
61 | using ElementalGeneratorWithBoolReturn = |
62 | std::function<mlir::Value(const fir::ExtendedValue &)>; |
63 | struct LoweredVectorSubscript { |
64 | LoweredVectorSubscript(fir::ExtendedValue &&vector, mlir::Value size) |
65 | : vector{std::move(vector)}, size{size} {} |
66 | fir::ExtendedValue vector; |
67 | // Vector size, guaranteed to be of indexType. |
68 | mlir::Value size; |
69 | }; |
70 | struct LoweredTriplet { |
71 | // Triplets value, guaranteed to be of indexType. |
72 | mlir::Value lb; |
73 | mlir::Value ub; |
74 | mlir::Value stride; |
75 | }; |
76 | using LoweredSubscript = |
77 | std::variant<mlir::Value, LoweredTriplet, LoweredVectorSubscript>; |
78 | using MaybeSubstring = llvm::SmallVector<mlir::Value, 2>; |
79 | VectorSubscriptBox( |
80 | fir::ExtendedValue &&loweredBase, |
81 | llvm::SmallVector<LoweredSubscript, 16> &&loweredSubscripts, |
82 | llvm::SmallVector<mlir::Value> &&componentPath, |
83 | MaybeSubstring substringBounds, mlir::Type elementType) |
84 | : loweredBase{std::move(loweredBase)}, loweredSubscripts{std::move( |
85 | loweredSubscripts)}, |
86 | componentPath{std::move(componentPath)}, |
87 | substringBounds{substringBounds}, elementType{elementType} {}; |
88 | |
89 | /// Loop over the elements described by the VectorSubscriptBox, and call |
90 | /// \p elementalGenerator inside the loops with the element addresses. |
91 | void loopOverElements(fir::FirOpBuilder &builder, mlir::Location loc, |
92 | const ElementalGenerator &elementalGenerator); |
93 | |
94 | /// Loop over the elements described by the VectorSubscriptBox while a |
95 | /// condition is true, and call \p elementalGenerator inside the loops with |
96 | /// the element addresses. The initial condition value is \p initialCondition, |
97 | /// and then it is the result of \p elementalGenerator. The value of the |
98 | /// condition after the loops is returned. |
99 | mlir::Value loopOverElementsWhile( |
100 | fir::FirOpBuilder &builder, mlir::Location loc, |
101 | const ElementalGeneratorWithBoolReturn &elementalGenerator, |
102 | mlir::Value initialCondition); |
103 | |
104 | /// Return the type of the elements of the array section. |
105 | mlir::Type getElementType() { return elementType; } |
106 | |
107 | private: |
108 | /// Common implementation for DoLoop and IterWhile loop creations. |
109 | template <typename LoopType, typename Generator> |
110 | mlir::Value loopOverElementsBase(fir::FirOpBuilder &builder, |
111 | mlir::Location loc, |
112 | const Generator &elementalGenerator, |
113 | mlir::Value initialCondition); |
114 | /// Create sliceOp for the designator. |
115 | mlir::Value createSlice(fir::FirOpBuilder &builder, mlir::Location loc); |
116 | |
117 | /// Create ExtendedValue the element inside the loop. |
118 | fir::ExtendedValue getElementAt(fir::FirOpBuilder &builder, |
119 | mlir::Location loc, mlir::Value shape, |
120 | mlir::Value slice, |
121 | mlir::ValueRange inductionVariables); |
122 | |
123 | /// Generate the [lb, ub, step] to loop over the section (in loop order, not |
124 | /// Fortran dimension order). |
125 | llvm::SmallVector<std::tuple<mlir::Value, mlir::Value, mlir::Value>> |
126 | genLoopBounds(fir::FirOpBuilder &builder, mlir::Location loc); |
127 | |
128 | /// Lowered base of the ranked array ref. |
129 | fir::ExtendedValue loweredBase; |
130 | /// Subscripts values of the rank arrayRef part. |
131 | llvm::SmallVector<LoweredSubscript, 16> loweredSubscripts; |
132 | /// Scalar subscripts and components at the right of the ranked |
133 | /// array ref part of any. |
134 | llvm::SmallVector<mlir::Value> componentPath; |
135 | /// List of substring bounds if this is a substring (only the lower bound if |
136 | /// the upper is implicit). |
137 | MaybeSubstring substringBounds; |
138 | /// Type of the elements described by this array section. |
139 | mlir::Type elementType; |
140 | }; |
141 | |
142 | /// Lower \p expr, that must be an designator containing vector subscripts, to a |
143 | /// VectorSubscriptBox representation. This causes evaluation of all the |
144 | /// subscripts. Any required clean-ups from subscript expression are added to \p |
145 | /// stmtCtx. |
146 | VectorSubscriptBox genVectorSubscriptBox( |
147 | mlir::Location loc, Fortran::lower::AbstractConverter &converter, |
148 | Fortran::lower::StatementContext &stmtCtx, |
149 | const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &expr); |
150 | |
151 | } // namespace lower |
152 | } // namespace Fortran |
153 | |
154 | #endif // FORTRAN_LOWER_VECTORSUBSCRIPTS_H |
155 |
Warning: This file is not a C or C++ file. It does not have highlighting.