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 | |
26 | namespace mlir { |
27 | class SymbolTable; |
28 | } |
29 | |
30 | namespace fir { |
31 | class KindMapping; |
32 | class FirOpBuilder; |
33 | } // namespace fir |
34 | |
35 | namespace Fortran { |
36 | namespace common { |
37 | template <typename> |
38 | class Reference; |
39 | } |
40 | |
41 | namespace evaluate { |
42 | struct DataRef; |
43 | template <typename> |
44 | class Expr; |
45 | class FoldingContext; |
46 | struct SomeType; |
47 | } // namespace evaluate |
48 | |
49 | namespace parser { |
50 | class CharBlock; |
51 | } |
52 | namespace semantics { |
53 | class Symbol; |
54 | class Scope; |
55 | class DerivedTypeSpec; |
56 | } // namespace semantics |
57 | |
58 | namespace lower { |
59 | class SymMap; |
60 | struct SymbolBox; |
61 | namespace pft { |
62 | struct Variable; |
63 | } |
64 | |
65 | using SomeExpr = Fortran::evaluate::Expr<Fortran::evaluate::SomeType>; |
66 | using SymbolRef = Fortran::common::Reference<const Fortran::semantics::Symbol>; |
67 | using TypeConstructionStack = |
68 | llvm::DenseMap<const Fortran::semantics::Scope *, mlir::Type>; |
69 | class StatementContext; |
70 | |
71 | using 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. |
80 | class AbstractConverter { |
81 | public: |
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 | |
321 | private: |
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.