| //===- Lower/ConvertVariable.h -- lowering of variables to FIR --*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// Instantiation of pft::Variable in FIR/MLIR. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef FORTRAN_LOWER_CONVERT_VARIABLE_H |
| #define FORTRAN_LOWER_CONVERT_VARIABLE_H |
| |
| #include "flang/Lower/Support/Utils.h" |
| #include "flang/Optimizer/Dialect/FIRAttr.h" |
| #include "flang/Semantics/symbol.h" |
| #include "mlir/IR/Value.h" |
| #include "llvm/ADT/DenseMap.h" |
| |
| namespace fir { |
| class ExtendedValue; |
| class FirOpBuilder; |
| class GlobalOp; |
| class FortranVariableFlagsAttr; |
| } // namespace fir |
| |
| namespace Fortran { |
| namespace semantics { |
| class Scope; |
| } // namespace semantics |
| |
| namespace lower { |
| class AbstractConverter; |
| class CallerInterface; |
| class StatementContext; |
| class SymMap; |
| namespace pft { |
| struct Variable; |
| } |
| |
| /// AggregateStoreMap is used to keep track of instantiated aggregate stores |
| /// when lowering a scope containing equivalences (aliases). It must only be |
| /// owned by the code lowering a scope and provided to instantiateVariable. |
| using AggregateStoreKey = |
| std::tuple<const Fortran::semantics::Scope *, std::size_t>; |
| using AggregateStoreMap = llvm::DenseMap<AggregateStoreKey, mlir::Value>; |
| |
| /// Instantiate variable \p var and add it to \p symMap. |
| /// The AbstractConverter builder must be set. |
| /// The AbstractConverter own symbol mapping is not used during the |
| /// instantiation and can be different form \p symMap. |
| void instantiateVariable(AbstractConverter &, const pft::Variable &var, |
| SymMap &symMap, AggregateStoreMap &storeMap); |
| |
| /// Create a fir::GlobalOp given a module variable definition. This is intended |
| /// to be used when lowering a module definition, not when lowering variables |
| /// used from a module. For used variables instantiateVariable must directly be |
| /// called. |
| void defineModuleVariable(AbstractConverter &, const pft::Variable &var); |
| |
| /// Create fir::GlobalOp for all common blocks, including their initial values |
| /// if they have one. This should be called before lowering any scopes so that |
| /// common block globals are available when a common appear in a scope. |
| void defineCommonBlocks( |
| AbstractConverter &, |
| const std::vector<std::pair<semantics::SymbolRef, std::size_t>> |
| &commonBlocks); |
| |
| /// The COMMON block is a global structure. \p commonValue is the base address |
| /// of the COMMON block. As the offset from the symbol \p sym, generate the |
| /// COMMON block member value (commonValue + offset) for the symbol. |
| mlir::Value genCommonBlockMember(AbstractConverter &converter, |
| mlir::Location loc, |
| const Fortran::semantics::Symbol &sym, |
| mlir::Value commonValue); |
| |
| /// Lower a symbol attributes given an optional storage \p and add it to the |
| /// provided symbol map. If \preAlloc is not provided, a temporary storage will |
| /// be allocated. This is a low level function that should only be used if |
| /// instantiateVariable cannot be called. |
| void mapSymbolAttributes(AbstractConverter &, const pft::Variable &, SymMap &, |
| StatementContext &, mlir::Value preAlloc = {}); |
| void mapSymbolAttributes(AbstractConverter &, const semantics::SymbolRef &, |
| SymMap &, StatementContext &, |
| mlir::Value preAlloc = {}); |
| |
| /// Instantiate the variables that appear in the specification expressions |
| /// of the result of a function call. The instantiated variables are added |
| /// to \p symMap. |
| void mapCallInterfaceSymbolsForResult( |
| AbstractConverter &, const Fortran::lower::CallerInterface &caller, |
| SymMap &symMap); |
| |
| /// Instantiate the variables that appear in the specification expressions |
| /// of a dummy argument of a procedure call. The instantiated variables are |
| /// added to \p symMap. |
| void mapCallInterfaceSymbolsForDummyArgument( |
| AbstractConverter &, const Fortran::lower::CallerInterface &caller, |
| SymMap &symMap, const Fortran::semantics::Symbol &dummySymbol); |
| |
| // TODO: consider saving the initial expression symbol dependence analysis in |
| // in the PFT variable and dealing with the dependent symbols instantiation in |
| // the fir::GlobalOp body at the fir::GlobalOp creation point rather than by |
| // having genExtAddrInInitializer and genInitialDataTarget custom entry points |
| // here to deal with this while lowering the initial expression value. |
| |
| /// Create initial-data-target fir.box in a global initializer region. |
| /// This handles the local instantiation of the target variable. |
| mlir::Value genInitialDataTarget(Fortran::lower::AbstractConverter &, |
| mlir::Location, mlir::Type boxType, |
| const SomeExpr &initialTarget, |
| bool couldBeInEquivalence = false); |
| |
| /// Call \p genInit to generate code inside \p global initializer region. |
| void createGlobalInitialization( |
| fir::FirOpBuilder &builder, fir::GlobalOp global, |
| std::function<void(fir::FirOpBuilder &)> genInit); |
| |
| /// Generate address \p addr inside an initializer. |
| fir::ExtendedValue |
| genExtAddrInInitializer(Fortran::lower::AbstractConverter &converter, |
| mlir::Location loc, const SomeExpr &addr); |
| |
| /// Create a global variable for an intrinsic module object. |
| void createIntrinsicModuleGlobal(Fortran::lower::AbstractConverter &converter, |
| const pft::Variable &); |
| |
| /// Create a global variable for a compiler generated object that describes a |
| /// derived type for the runtime. |
| void createRuntimeTypeInfoGlobal(Fortran::lower::AbstractConverter &converter, |
| const Fortran::semantics::Symbol &typeInfoSym); |
| |
| /// Translate the Fortran attributes of \p sym into the FIR variable attribute |
| /// representation. |
| fir::FortranVariableFlagsAttr |
| translateSymbolAttributes(mlir::MLIRContext *mlirContext, |
| const Fortran::semantics::Symbol &sym, |
| fir::FortranVariableFlagsEnum extraFlags = |
| fir::FortranVariableFlagsEnum::None); |
| |
| /// Translate the CUDA Fortran attributes of \p sym into the FIR CUDA attribute |
| /// representation. |
| fir::CUDADataAttributeAttr |
| translateSymbolCUDADataAttribute(mlir::MLIRContext *mlirContext, |
| const Fortran::semantics::Symbol &sym); |
| |
| /// Map a symbol to a given fir::ExtendedValue. This will generate an |
| /// hlfir.declare when lowering to HLFIR and map the hlfir.declare result to the |
| /// symbol. |
| void genDeclareSymbol(Fortran::lower::AbstractConverter &converter, |
| Fortran::lower::SymMap &symMap, |
| const Fortran::semantics::Symbol &sym, |
| const fir::ExtendedValue &exv, |
| fir::FortranVariableFlagsEnum extraFlags = |
| fir::FortranVariableFlagsEnum::None, |
| bool force = false); |
| |
| /// Given the Fortran type of a Cray pointee, return the fir.box type used to |
| /// track the cray pointee as Fortran pointer. |
| mlir::Type getCrayPointeeBoxType(mlir::Type); |
| |
| } // namespace lower |
| } // namespace Fortran |
| #endif // FORTRAN_LOWER_CONVERT_VARIABLE_H |