195 lines · c
1//===-- Lower/OpenMP/Utils.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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef FORTRAN_LOWER_OPENMPUTILS_H10#define FORTRAN_LOWER_OPENMPUTILS_H11 12#include "flang/Lower/OpenMP/Clauses.h"13#include "mlir/Dialect/OpenMP/OpenMPDialect.h"14#include "mlir/IR/Location.h"15#include "mlir/IR/Value.h"16#include "llvm/Support/CommandLine.h"17#include <cstdint>18 19extern llvm::cl::opt<bool> treatIndexAsSection;20 21namespace fir {22class FirOpBuilder;23class RecordType;24} // namespace fir25namespace Fortran {26 27namespace semantics {28class Symbol;29} // namespace semantics30 31namespace parser {32struct OmpObject;33struct OmpObjectList;34} // namespace parser35 36namespace lower {37class StatementContext;38namespace pft {39struct Evaluation;40}41 42class AbstractConverter;43 44namespace omp {45 46struct DeclareTargetCaptureInfo {47 mlir::omp::DeclareTargetCaptureClause clause;48 bool automap = false;49 const semantics::Symbol &symbol;50 51 DeclareTargetCaptureInfo(mlir::omp::DeclareTargetCaptureClause c,52 const semantics::Symbol &s, bool a = false)53 : clause(c), automap(a), symbol(s) {}54};55 56// A small helper structure for keeping track of a component members MapInfoOp57// and index data when lowering OpenMP map clauses. Keeps track of the58// placement of the component in the derived type hierarchy it rests within,59// alongside the generated mlir::omp::MapInfoOp for the mapped component.60//61// As an example of what the contents of this data structure may be like,62// when provided the following derived type and map of that type:63//64// type :: bottom_layer65// real(8) :: i266// real(4) :: array_i2(10)67// real(4) :: array_j2(10)68// end type bottom_layer69//70// type :: top_layer71// real(4) :: i72// integer(4) :: array_i(10)73// real(4) :: j74// type(bottom_layer) :: nested75// integer, allocatable :: array_j(:)76// integer(4) :: k77// end type top_layer78//79// type(top_layer) :: top_dtype80//81// map(tofrom: top_dtype%nested%i2, top_dtype%k, top_dtype%nested%array_i2)82//83// We would end up with an OmpMapParentAndMemberData populated like below:84//85// memberPlacementIndices:86// Vector 1: 3, 087// Vector 2: 588// Vector 3: 3, 189//90// memberMap:91// Entry 1: omp.map.info for "top_dtype%nested%i2"92// Entry 2: omp.map.info for "top_dtype%k"93// Entry 3: omp.map.info for "top_dtype%nested%array_i2"94//95// And this OmpMapParentAndMemberData would be accessed via the parent96// symbol for top_dtype. Other parent derived type instances that have97// members mapped would have there own OmpMapParentAndMemberData entry98// accessed via their own symbol.99struct OmpMapParentAndMemberData {100 // The indices representing the component members placement in its derived101 // type parents hierarchy.102 llvm::SmallVector<llvm::SmallVector<int64_t>> memberPlacementIndices;103 104 // Placement of the member in the member vector.105 llvm::SmallVector<mlir::omp::MapInfoOp> memberMap;106 107 bool isDuplicateMemberMapInfo(llvm::SmallVectorImpl<int64_t> &memberIndices) {108 return llvm::find_if(memberPlacementIndices, [&](auto &memberData) {109 return llvm::equal(memberIndices, memberData);110 }) != memberPlacementIndices.end();111 }112 113 void addChildIndexAndMapToParent(const omp::Object &object,114 mlir::omp::MapInfoOp &mapOp,115 semantics::SemanticsContext &semaCtx);116};117 118void insertChildMapInfoIntoParent(119 Fortran::lower::AbstractConverter &converter,120 Fortran::semantics::SemanticsContext &semaCtx,121 Fortran::lower::StatementContext &stmtCtx,122 std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices,123 llvm::SmallVectorImpl<mlir::Value> &mapOperands,124 llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms);125 126void generateMemberPlacementIndices(127 const Object &object, llvm::SmallVectorImpl<int64_t> &indices,128 Fortran::semantics::SemanticsContext &semaCtx);129 130bool isMemberOrParentAllocatableOrPointer(131 const Object &object, Fortran::semantics::SemanticsContext &semaCtx);132 133mlir::Value createParentSymAndGenIntermediateMaps(134 mlir::Location clauseLocation, Fortran::lower::AbstractConverter &converter,135 semantics::SemanticsContext &semaCtx, lower::StatementContext &stmtCtx,136 omp::ObjectList &objectList, llvm::SmallVectorImpl<int64_t> &indices,137 OmpMapParentAndMemberData &parentMemberIndices, llvm::StringRef asFortran,138 mlir::omp::ClauseMapFlags mapTypeBits);139 140mlir::FlatSymbolRefAttr getOrGenImplicitDefaultDeclareMapper(141 Fortran::lower::AbstractConverter &converter, mlir::Location loc,142 fir::RecordType recordType, llvm::StringRef mapperNameStr);143 144bool requiresImplicitDefaultDeclareMapper(145 const semantics::DerivedTypeSpec &typeSpec);146 147omp::ObjectList gatherObjectsOf(omp::Object derivedTypeMember,148 semantics::SemanticsContext &semaCtx);149 150mlir::Type getLoopVarType(lower::AbstractConverter &converter,151 std::size_t loopVarTypeSize);152 153semantics::Symbol *154getIterationVariableSymbol(const lower::pft::Evaluation &eval);155 156void gatherFuncAndVarSyms(157 const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause,158 llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &symbolAndClause,159 bool automap = false);160 161int64_t getCollapseValue(const List<Clause> &clauses);162 163void genObjectList(const ObjectList &objects,164 lower::AbstractConverter &converter,165 llvm::SmallVectorImpl<mlir::Value> &operands);166 167void lastprivateModifierNotSupported(const omp::clause::Lastprivate &lastp,168 mlir::Location loc);169 170pft::Evaluation *getNestedDoConstruct(pft::Evaluation &eval);171 172int64_t collectLoopRelatedInfo(173 lower::AbstractConverter &converter, mlir::Location currentLocation,174 lower::pft::Evaluation &eval, const omp::List<omp::Clause> &clauses,175 mlir::omp::LoopRelatedClauseOps &result,176 llvm::SmallVectorImpl<const semantics::Symbol *> &iv);177 178void collectLoopRelatedInfo(179 lower::AbstractConverter &converter, mlir::Location currentLocation,180 lower::pft::Evaluation &eval, std::int64_t collapseValue,181 // const omp::List<omp::Clause> &clauses,182 mlir::omp::LoopRelatedClauseOps &result,183 llvm::SmallVectorImpl<const semantics::Symbol *> &iv);184 185void collectTileSizesFromOpenMPConstruct(186 const parser::OpenMPConstruct *ompCons,187 llvm::SmallVectorImpl<int64_t> &tileSizes,188 Fortran::semantics::SemanticsContext &semaCtx);189 190} // namespace omp191} // namespace lower192} // namespace Fortran193 194#endif // FORTRAN_LOWER_OPENMPUTILS_H195