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
24namespace fir {
25class FirOpBuilder;
26}
27
28namespace Fortran {
29
30namespace evaluate {
31template <typename>
32class Expr;
33struct SomeType;
34} // namespace evaluate
35
36namespace lower {
37
38class AbstractConverter;
39class 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.
56class VectorSubscriptBox {
57public:
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
107private:
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.
146VectorSubscriptBox 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.

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