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

1//===-- Lower/AbstractConverter.h -------------------------------*- 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#ifndef FORTRAN_LOWER_ABSTRACTCONVERTER_H
14#define FORTRAN_LOWER_ABSTRACTCONVERTER_H
15
16#include "flang/Common/Fortran.h"
17#include "flang/Lower/LoweringOptions.h"
18#include "flang/Lower/PFTDefs.h"
19#include "flang/Optimizer/Builder/BoxValue.h"
20#include "flang/Semantics/symbol.h"
21#include "mlir/IR/Builders.h"
22#include "mlir/IR/BuiltinOps.h"
23#include "mlir/IR/Operation.h"
24#include "llvm/ADT/ArrayRef.h"
25
26namespace mlir {
27class SymbolTable;
28}
29
30namespace fir {
31class KindMapping;
32class FirOpBuilder;
33} // namespace fir
34
35namespace Fortran {
36namespace common {
37template <typename>
38class Reference;
39}
40
41namespace evaluate {
42struct DataRef;
43template <typename>
44class Expr;
45class FoldingContext;
46struct SomeType;
47} // namespace evaluate
48
49namespace parser {
50class CharBlock;
51}
52namespace semantics {
53class Symbol;
54class Scope;
55class DerivedTypeSpec;
56} // namespace semantics
57
58namespace lower {
59class SymMap;
60struct SymbolBox;
61namespace pft {
62struct Variable;
63}
64
65using SomeExpr = Fortran::evaluate::Expr<Fortran::evaluate::SomeType>;
66using SymbolRef = Fortran::common::Reference<const Fortran::semantics::Symbol>;
67using TypeConstructionStack =
68 llvm::DenseMap<const Fortran::semantics::Scope *, mlir::Type>;
69class StatementContext;
70
71using ExprToValueMap = llvm::DenseMap<const SomeExpr *, mlir::Value>;
72
73//===----------------------------------------------------------------------===//
74// AbstractConverter interface
75//===----------------------------------------------------------------------===//
76
77/// The abstract interface for converter implementations to lower Fortran
78/// front-end fragments such as expressions, types, etc. to the FIR dialect of
79/// MLIR.
80class AbstractConverter {
81public:
82 //===--------------------------------------------------------------------===//
83 // Symbols
84 //===--------------------------------------------------------------------===//
85
86 /// Get the mlir instance of a symbol.
87 virtual mlir::Value getSymbolAddress(SymbolRef sym) = 0;
88
89 virtual fir::ExtendedValue
90 getSymbolExtendedValue(const Fortran::semantics::Symbol &sym,
91 Fortran::lower::SymMap *symMap = nullptr) = 0;
92
93 /// Get the binding of an implied do variable by name.
94 virtual mlir::Value impliedDoBinding(llvm::StringRef name) = 0;
95
96 /// Copy the binding of src to target symbol.
97 virtual void copySymbolBinding(SymbolRef src, SymbolRef target) = 0;
98
99 /// Binds the symbol to an fir extended value. The symbol binding will be
100 /// added or replaced at the inner-most level of the local symbol map.
101 virtual void bindSymbol(SymbolRef sym, const fir::ExtendedValue &exval) = 0;
102
103 /// Override lowering of expression with pre-lowered values.
104 /// Associate mlir::Value to evaluate::Expr. All subsequent call to
105 /// genExprXXX() will replace any occurrence of an overridden
106 /// expression in the expression tree by the pre-lowered values.
107 virtual void overrideExprValues(const ExprToValueMap *) = 0;
108 void resetExprOverrides() { overrideExprValues(nullptr); }
109 virtual const ExprToValueMap *getExprOverrides() = 0;
110
111 /// Get the label set associated with a symbol.
112 virtual bool lookupLabelSet(SymbolRef sym, pft::LabelSet &labelSet) = 0;
113
114 /// Get the code defined by a label
115 virtual pft::Evaluation *lookupLabel(pft::Label label) = 0;
116
117 /// For a given symbol which is host-associated, create a clone using
118 /// parameters from the host-associated symbol.
119 virtual bool
120 createHostAssociateVarClone(const Fortran::semantics::Symbol &sym) = 0;
121
122 virtual void
123 createHostAssociateVarCloneDealloc(const Fortran::semantics::Symbol &sym) = 0;
124
125 virtual void copyHostAssociateVar(
126 const Fortran::semantics::Symbol &sym,
127 mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr) = 0;
128
129 virtual void copyVar(mlir::Location loc, mlir::Value dst,
130 mlir::Value src) = 0;
131
132 /// For a given symbol, check if it is present in the inner-most
133 /// level of the symbol map.
134 virtual bool isPresentShallowLookup(Fortran::semantics::Symbol &sym) = 0;
135
136 /// Collect the set of symbols with \p flag in \p eval
137 /// region if \p collectSymbols is true. Likewise, collect the
138 /// set of the host symbols with \p flag of the associated symbols in \p eval
139 /// region if collectHostAssociatedSymbols is true.
140 virtual void collectSymbolSet(
141 pft::Evaluation &eval,
142 llvm::SetVector<const Fortran::semantics::Symbol *> &symbolSet,
143 Fortran::semantics::Symbol::Flag flag, bool collectSymbols = true,
144 bool collectHostAssociatedSymbols = false) = 0;
145
146 /// For the given literal constant \p expression, returns a unique name
147 /// that can be used to create a global object to represent this
148 /// literal constant. It will return the same name for equivalent
149 /// literal constant expressions. \p eleTy specifies the data type
150 /// of the constant elements. For array constants it specifies
151 /// the array's element type.
152 virtual llvm::StringRef
153 getUniqueLitName(mlir::Location loc,
154 std::unique_ptr<Fortran::lower::SomeExpr> expression,
155 mlir::Type eleTy) = 0;
156
157 //===--------------------------------------------------------------------===//
158 // Expressions
159 //===--------------------------------------------------------------------===//
160
161 /// Generate the address of the location holding the expression, \p expr.
162 /// If \p expr is a Designator that is not compile time contiguous, the
163 /// address returned is the one of a contiguous temporary storage holding the
164 /// expression value. The clean-up for this temporary is added to \p context.
165 virtual fir::ExtendedValue genExprAddr(const SomeExpr &expr,
166 StatementContext &context,
167 mlir::Location *locPtr = nullptr) = 0;
168
169 /// Generate the address of the location holding the expression, \p expr.
170 fir::ExtendedValue genExprAddr(mlir::Location loc, const SomeExpr *expr,
171 StatementContext &stmtCtx) {
172 return genExprAddr(*expr, stmtCtx, &loc);
173 }
174 fir::ExtendedValue genExprAddr(mlir::Location loc, const SomeExpr &expr,
175 StatementContext &stmtCtx) {
176 return genExprAddr(expr, stmtCtx, &loc);
177 }
178
179 /// Generate the computations of the expression to produce a value.
180 virtual fir::ExtendedValue genExprValue(const SomeExpr &expr,
181 StatementContext &context,
182 mlir::Location *locPtr = nullptr) = 0;
183
184 /// Generate the computations of the expression, \p expr, to produce a value.
185 fir::ExtendedValue genExprValue(mlir::Location loc, const SomeExpr *expr,
186 StatementContext &stmtCtx) {
187 return genExprValue(*expr, stmtCtx, &loc);
188 }
189 fir::ExtendedValue genExprValue(mlir::Location loc, const SomeExpr &expr,
190 StatementContext &stmtCtx) {
191 return genExprValue(expr, stmtCtx, &loc);
192 }
193
194 /// Generate or get a fir.box describing the expression. If SomeExpr is
195 /// a Designator, the fir.box describes an entity over the Designator base
196 /// storage without making a temporary.
197 virtual fir::ExtendedValue genExprBox(mlir::Location loc,
198 const SomeExpr &expr,
199 StatementContext &stmtCtx) = 0;
200
201 /// Generate the address of the box describing the variable designated
202 /// by the expression. The expression must be an allocatable or pointer
203 /// designator.
204 virtual fir::MutableBoxValue genExprMutableBox(mlir::Location loc,
205 const SomeExpr &expr) = 0;
206
207 /// Get FoldingContext that is required for some expression
208 /// analysis.
209 virtual Fortran::evaluate::FoldingContext &getFoldingContext() = 0;
210
211 /// Host associated variables are grouped as a tuple. This returns that value,
212 /// which is itself a reference. Use bindTuple() to set this value.
213 virtual mlir::Value hostAssocTupleValue() = 0;
214
215 /// Record a binding for the ssa-value of the host assoications tuple for this
216 /// function.
217 virtual void bindHostAssocTuple(mlir::Value val) = 0;
218
219 //===--------------------------------------------------------------------===//
220 // Types
221 //===--------------------------------------------------------------------===//
222
223 /// Generate the type of an Expr
224 virtual mlir::Type genType(const SomeExpr &) = 0;
225 /// Generate the type of a Symbol
226 virtual mlir::Type genType(SymbolRef) = 0;
227 /// Generate the type from a category
228 virtual mlir::Type genType(Fortran::common::TypeCategory tc) = 0;
229 /// Generate the type from a category and kind and length parameters.
230 virtual mlir::Type
231 genType(Fortran::common::TypeCategory tc, int kind,
232 llvm::ArrayRef<std::int64_t> lenParameters = std::nullopt) = 0;
233 /// Generate the type from a DerivedTypeSpec.
234 virtual mlir::Type genType(const Fortran::semantics::DerivedTypeSpec &) = 0;
235 /// Generate the type from a Variable
236 virtual mlir::Type genType(const pft::Variable &) = 0;
237
238 /// Register a runtime derived type information object symbol to ensure its
239 /// object will be generated as a global.
240 virtual void
241 registerTypeInfo(mlir::Location loc, SymbolRef typeInfoSym,
242 const Fortran::semantics::DerivedTypeSpec &typeSpec,
243 fir::RecordType type) = 0;
244
245 /// Get stack of derived type in construction. This is an internal entry point
246 /// for the type conversion utility to allow lowering recursive derived types.
247 virtual TypeConstructionStack &getTypeConstructionStack() = 0;
248
249 //===--------------------------------------------------------------------===//
250 // Locations
251 //===--------------------------------------------------------------------===//
252
253 /// Get the converter's current location
254 virtual mlir::Location getCurrentLocation() = 0;
255 /// Generate a dummy location
256 virtual mlir::Location genUnknownLocation() = 0;
257 /// Generate the location as converted from a CharBlock
258 virtual mlir::Location genLocation(const Fortran::parser::CharBlock &) = 0;
259
260 /// Get the converter's current scope
261 virtual const Fortran::semantics::Scope &getCurrentScope() = 0;
262
263 //===--------------------------------------------------------------------===//
264 // FIR/MLIR
265 //===--------------------------------------------------------------------===//
266
267 /// Get the OpBuilder
268 virtual fir::FirOpBuilder &getFirOpBuilder() = 0;
269 /// Get the ModuleOp
270 virtual mlir::ModuleOp &getModuleOp() = 0;
271 /// Get the MLIRContext
272 virtual mlir::MLIRContext &getMLIRContext() = 0;
273 /// Unique a symbol (add a containing scope specific prefix)
274 virtual std::string mangleName(const Fortran::semantics::Symbol &) = 0;
275 /// Unique a derived type (add a containing scope specific prefix)
276 virtual std::string
277 mangleName(const Fortran::semantics::DerivedTypeSpec &) = 0;
278 /// Unique a compiler generated name (add a containing scope specific prefix)
279 virtual std::string mangleName(std::string &) = 0;
280 /// Return the field name for a derived type component inside a fir.record
281 /// type.
282 virtual std::string
283 getRecordTypeFieldName(const Fortran::semantics::Symbol &component) = 0;
284
285 /// Get the KindMap.
286 virtual const fir::KindMapping &getKindMap() = 0;
287
288 virtual Fortran::lower::StatementContext &getFctCtx() = 0;
289
290 AbstractConverter(const Fortran::lower::LoweringOptions &loweringOptions)
291 : loweringOptions(loweringOptions) {}
292 virtual ~AbstractConverter() = default;
293
294 //===--------------------------------------------------------------------===//
295 // Miscellaneous
296 //===--------------------------------------------------------------------===//
297
298 /// Generate IR for Evaluation \p eval.
299 virtual void genEval(pft::Evaluation &eval,
300 bool unstructuredContext = true) = 0;
301
302 /// Return options controlling lowering behavior.
303 const Fortran::lower::LoweringOptions &getLoweringOptions() const {
304 return loweringOptions;
305 }
306
307 /// Find the symbol in one level up of symbol map such as for host-association
308 /// in OpenMP code or return null.
309 virtual Fortran::lower::SymbolBox
310 lookupOneLevelUpSymbol(const Fortran::semantics::Symbol &sym) = 0;
311
312 /// Return the mlir::SymbolTable associated to the ModuleOp.
313 /// Look-ups are faster using it than using module.lookup<>,
314 /// but the module op should be queried in case of failure
315 /// because this symbol table is not guaranteed to contain
316 /// all the symbols from the ModuleOp (the symbol table should
317 /// always be provided to the builder helper creating globals and
318 /// functions in order to be in sync).
319 virtual mlir::SymbolTable *getMLIRSymbolTable() = 0;
320
321private:
322 /// Options controlling lowering behavior.
323 const Fortran::lower::LoweringOptions &loweringOptions;
324};
325
326} // namespace lower
327} // namespace Fortran
328
329#endif // FORTRAN_LOWER_ABSTRACTCONVERTER_H
330

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

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