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 "flang/Optimizer/Dialect/FIRAttr.h" 22 #include "flang/Semantics/symbol.h" 23 #include "mlir/IR/Value.h" 24 #include "llvm/ADT/DenseMap.h" 25 26 namespace cuf { 27 class DataAttributeAttr; 28 } 29 30 namespace fir { 31 class ExtendedValue; 32 class FirOpBuilder; 33 class GlobalOp; 34 class FortranVariableFlagsAttr; 35 } // namespace fir 36 37 namespace Fortran { 38 namespace semantics { 39 class Scope; 40 } // namespace semantics 41 42 namespace lower { 43 class AbstractConverter; 44 class CallerInterface; 45 class StatementContext; 46 class SymMap; 47 namespace pft { 48 struct Variable; 49 } 50 51 /// AggregateStoreMap is used to keep track of instantiated aggregate stores 52 /// when lowering a scope containing equivalences (aliases). It must only be 53 /// owned by the code lowering a scope and provided to instantiateVariable. 54 using AggregateStoreKey = 55 std::tuple<const Fortran::semantics::Scope *, std::size_t>; 56 using AggregateStoreMap = llvm::DenseMap<AggregateStoreKey, mlir::Value>; 57 58 /// Instantiate variable \p var and add it to \p symMap. 59 /// The AbstractConverter builder must be set. 60 /// The AbstractConverter own symbol mapping is not used during the 61 /// instantiation and can be different form \p symMap. 62 void instantiateVariable(AbstractConverter &, const pft::Variable &var, 63 SymMap &symMap, AggregateStoreMap &storeMap); 64 65 /// Does this variable have a default initialization? 66 bool hasDefaultInitialization(const Fortran::semantics::Symbol &sym); 67 68 /// Call default initialization runtime routine to initialize \p var. 69 void defaultInitializeAtRuntime(Fortran::lower::AbstractConverter &converter, 70 const Fortran::semantics::Symbol &sym, 71 Fortran::lower::SymMap &symMap); 72 73 /// Call clone initialization runtime routine to initialize \p sym's value. 74 void initializeCloneAtRuntime(Fortran::lower::AbstractConverter &converter, 75 const Fortran::semantics::Symbol &sym, 76 Fortran::lower::SymMap &symMap); 77 78 /// Create a fir::GlobalOp given a module variable definition. This is intended 79 /// to be used when lowering a module definition, not when lowering variables 80 /// used from a module. For used variables instantiateVariable must directly be 81 /// called. 82 void defineModuleVariable(AbstractConverter &, const pft::Variable &var); 83 84 /// Create fir::GlobalOp for all common blocks, including their initial values 85 /// if they have one. This should be called before lowering any scopes so that 86 /// common block globals are available when a common appear in a scope. 87 void defineCommonBlocks( 88 AbstractConverter &, 89 const std::vector<std::pair<semantics::SymbolRef, std::size_t>> 90 &commonBlocks); 91 92 /// The COMMON block is a global structure. \p commonValue is the base address 93 /// of the COMMON block. As the offset from the symbol \p sym, generate the 94 /// COMMON block member value (commonValue + offset) for the symbol. 95 mlir::Value genCommonBlockMember(AbstractConverter &converter, 96 mlir::Location loc, 97 const Fortran::semantics::Symbol &sym, 98 mlir::Value commonValue); 99 100 /// Lower a symbol attributes given an optional storage \p and add it to the 101 /// provided symbol map. If \preAlloc is not provided, a temporary storage will 102 /// be allocated. This is a low level function that should only be used if 103 /// instantiateVariable cannot be called. 104 void mapSymbolAttributes(AbstractConverter &, const pft::Variable &, SymMap &, 105 StatementContext &, mlir::Value preAlloc = {}); 106 void mapSymbolAttributes(AbstractConverter &, const semantics::SymbolRef &, 107 SymMap &, StatementContext &, 108 mlir::Value preAlloc = {}); 109 110 /// Instantiate the variables that appear in the specification expressions 111 /// of the result of a function call. The instantiated variables are added 112 /// to \p symMap. 113 void mapCallInterfaceSymbolsForResult( 114 AbstractConverter &, const Fortran::lower::CallerInterface &caller, 115 SymMap &symMap); 116 117 /// Instantiate the variables that appear in the specification expressions 118 /// of a dummy argument of a procedure call. The instantiated variables are 119 /// added to \p symMap. 120 void mapCallInterfaceSymbolsForDummyArgument( 121 AbstractConverter &, const Fortran::lower::CallerInterface &caller, 122 SymMap &symMap, const Fortran::semantics::Symbol &dummySymbol); 123 124 // TODO: consider saving the initial expression symbol dependence analysis in 125 // in the PFT variable and dealing with the dependent symbols instantiation in 126 // the fir::GlobalOp body at the fir::GlobalOp creation point rather than by 127 // having genExtAddrInInitializer and genInitialDataTarget custom entry points 128 // here to deal with this while lowering the initial expression value. 129 130 /// Create initial-data-target fir.box in a global initializer region. 131 /// This handles the local instantiation of the target variable. 132 mlir::Value genInitialDataTarget(Fortran::lower::AbstractConverter &, 133 mlir::Location, mlir::Type boxType, 134 const SomeExpr &initialTarget, 135 bool couldBeInEquivalence = false); 136 137 /// Call \p genInit to generate code inside \p global initializer region. 138 void createGlobalInitialization( 139 fir::FirOpBuilder &builder, fir::GlobalOp global, 140 std::function<void(fir::FirOpBuilder &)> genInit); 141 142 /// Generate address \p addr inside an initializer. 143 fir::ExtendedValue 144 genExtAddrInInitializer(Fortran::lower::AbstractConverter &converter, 145 mlir::Location loc, const SomeExpr &addr); 146 147 /// Create a global variable for an intrinsic module object. 148 void createIntrinsicModuleGlobal(Fortran::lower::AbstractConverter &converter, 149 const pft::Variable &); 150 151 /// Create a global variable for a compiler generated object that describes a 152 /// derived type for the runtime. 153 void createRuntimeTypeInfoGlobal(Fortran::lower::AbstractConverter &converter, 154 const Fortran::semantics::Symbol &typeInfoSym); 155 156 /// Translate the Fortran attributes of \p sym into the FIR variable attribute 157 /// representation. 158 fir::FortranVariableFlagsAttr 159 translateSymbolAttributes(mlir::MLIRContext *mlirContext, 160 const Fortran::semantics::Symbol &sym, 161 fir::FortranVariableFlagsEnum extraFlags = 162 fir::FortranVariableFlagsEnum::None); 163 164 /// Translate the CUDA Fortran attributes of \p sym into the FIR CUDA attribute 165 /// representation. 166 cuf::DataAttributeAttr 167 translateSymbolCUFDataAttribute(mlir::MLIRContext *mlirContext, 168 const Fortran::semantics::Symbol &sym); 169 170 /// Map a symbol to a given fir::ExtendedValue. This will generate an 171 /// hlfir.declare when lowering to HLFIR and map the hlfir.declare result to the 172 /// symbol. 173 void genDeclareSymbol(Fortran::lower::AbstractConverter &converter, 174 Fortran::lower::SymMap &symMap, 175 const Fortran::semantics::Symbol &sym, 176 const fir::ExtendedValue &exv, 177 fir::FortranVariableFlagsEnum extraFlags = 178 fir::FortranVariableFlagsEnum::None, 179 bool force = false); 180 181 /// Given the Fortran type of a Cray pointee, return the fir.box type used to 182 /// track the cray pointee as Fortran pointer. 183 mlir::Type getCrayPointeeBoxType(mlir::Type); 184 185 } // namespace lower 186 } // namespace Fortran 187 #endif // FORTRAN_LOWER_CONVERT_VARIABLE_H 188