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