1 //===- Lower/ConvertVariable.h -- lowering of variables to FIR --*- 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 /// Instantiation of pft::Variable in FIR/MLIR.
14 ///
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef FORTRAN_LOWER_CONVERT_VARIABLE_H
18 #define FORTRAN_LOWER_CONVERT_VARIABLE_H
19 
20 #include "flang/Lower/Support/Utils.h"
21 #include "mlir/IR/Value.h"
22 #include "llvm/ADT/DenseMap.h"
23 
24 namespace fir {
25 class ExtendedValue;
26 } // namespace fir
27 
28 namespace Fortran ::lower {
29 class AbstractConverter;
30 class CallerInterface;
31 class StatementContext;
32 class SymMap;
33 namespace pft {
34 struct Variable;
35 }
36 
37 /// AggregateStoreMap is used to keep track of instantiated aggregate stores
38 /// when lowering a scope containing equivalences (aliases). It must only be
39 /// owned by the code lowering a scope and provided to instantiateVariable.
40 using AggregateStoreKey =
41     std::tuple<const Fortran::semantics::Scope *, std::size_t>;
42 using AggregateStoreMap = llvm::DenseMap<AggregateStoreKey, mlir::Value>;
43 
44 /// Instantiate variable \p var and add it to \p symMap.
45 /// The AbstractConverter builder must be set.
46 /// The AbstractConverter own symbol mapping is not used during the
47 /// instantiation and can be different form \p symMap.
48 void instantiateVariable(AbstractConverter &, const pft::Variable &var,
49                          SymMap &symMap, AggregateStoreMap &storeMap);
50 
51 /// Create a fir::GlobalOp given a module variable definition. This is intended
52 /// to be used when lowering a module definition, not when lowering variables
53 /// used from a module. For used variables instantiateVariable must directly be
54 /// called.
55 void defineModuleVariable(AbstractConverter &, const pft::Variable &var);
56 
57 /// Create fir::GlobalOp for all common blocks, including their initial values
58 /// if they have one. This should be called before lowering any scopes so that
59 /// common block globals are available when a common appear in a scope.
60 void defineCommonBlocks(
61     AbstractConverter &,
62     const std::vector<std::pair<semantics::SymbolRef, std::size_t>>
63         &commonBlocks);
64 
65 /// Lower a symbol attributes given an optional storage \p and add it to the
66 /// provided symbol map. If \preAlloc is not provided, a temporary storage will
67 /// be allocated. This is a low level function that should only be used if
68 /// instantiateVariable cannot be called.
69 void mapSymbolAttributes(AbstractConverter &, const pft::Variable &, SymMap &,
70                          StatementContext &, mlir::Value preAlloc = {});
71 
72 /// Instantiate the variables that appear in the specification expressions
73 /// of the result of a function call. The instantiated variables are added
74 /// to \p symMap.
75 void mapCallInterfaceSymbols(AbstractConverter &,
76                              const Fortran::lower::CallerInterface &caller,
77                              SymMap &symMap);
78 
79 // TODO: consider saving the initial expression symbol dependence analysis in
80 // in the PFT variable and dealing with the dependent symbols instantiation in
81 // the fir::GlobalOp body at the fir::GlobalOp creation point rather than by
82 // having genExtAddrInInitializer and genInitialDataTarget custom entry points
83 // here to deal with this while lowering the initial expression value.
84 
85 /// Create initial-data-target fir.box in a global initializer region.
86 /// This handles the local instantiation of the target variable.
87 mlir::Value genInitialDataTarget(Fortran::lower::AbstractConverter &,
88                                  mlir::Location, mlir::Type boxType,
89                                  const SomeExpr &initialTarget);
90 
91 /// Generate address \p addr inside an initializer.
92 fir::ExtendedValue
93 genExtAddrInInitializer(Fortran::lower::AbstractConverter &converter,
94                         mlir::Location loc, const SomeExpr &addr);
95 
96 /// Create global variable from a compiler generated object symbol that
97 /// describes a derived type for the runtime.
98 void createRuntimeTypeInfoGlobal(Fortran::lower::AbstractConverter &converter,
99                                  mlir::Location loc,
100                                  const Fortran::semantics::Symbol &typeInfoSym);
101 
102 } // namespace Fortran::lower
103 #endif // FORTRAN_LOWER_CONVERT_VARIABLE_H
104