14d4af15cSKareem Ergawy //===-- Lower/OpenMP/Utils.h ------------------------------------*- C++ -*-===// 24d4af15cSKareem Ergawy // 34d4af15cSKareem Ergawy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44d4af15cSKareem Ergawy // See https://llvm.org/LICENSE.txt for license information. 54d4af15cSKareem Ergawy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64d4af15cSKareem Ergawy // 74d4af15cSKareem Ergawy //===----------------------------------------------------------------------===// 84d4af15cSKareem Ergawy 94d4af15cSKareem Ergawy #ifndef FORTRAN_LOWER_OPENMPUTILS_H 104d4af15cSKareem Ergawy #define FORTRAN_LOWER_OPENMPUTILS_H 114d4af15cSKareem Ergawy 1263e70c05SKrzysztof Parzyszek #include "Clauses.h" 134d4af15cSKareem Ergawy #include "mlir/Dialect/OpenMP/OpenMPDialect.h" 144d4af15cSKareem Ergawy #include "mlir/IR/Location.h" 154d4af15cSKareem Ergawy #include "mlir/IR/Value.h" 164d4af15cSKareem Ergawy #include "llvm/Support/CommandLine.h" 17*e508baccSagozillon #include <cstdint> 184d4af15cSKareem Ergawy 194d4af15cSKareem Ergawy extern llvm::cl::opt<bool> treatIndexAsSection; 2026b8be20SKareem Ergawy extern llvm::cl::opt<bool> enableDelayedPrivatization; 211539da46SKareem Ergawy extern llvm::cl::opt<bool> enableDelayedPrivatizationStaging; 224d4af15cSKareem Ergawy 234d4af15cSKareem Ergawy namespace fir { 244d4af15cSKareem Ergawy class FirOpBuilder; 254d4af15cSKareem Ergawy } // namespace fir 264d4af15cSKareem Ergawy namespace Fortran { 274d4af15cSKareem Ergawy 284d4af15cSKareem Ergawy namespace semantics { 294d4af15cSKareem Ergawy class Symbol; 304d4af15cSKareem Ergawy } // namespace semantics 314d4af15cSKareem Ergawy 324d4af15cSKareem Ergawy namespace parser { 334d4af15cSKareem Ergawy struct OmpObject; 344d4af15cSKareem Ergawy struct OmpObjectList; 354d4af15cSKareem Ergawy } // namespace parser 364d4af15cSKareem Ergawy 374d4af15cSKareem Ergawy namespace lower { 38*e508baccSagozillon class StatementContext; 39554be97dSKrzysztof Parzyszek namespace pft { 40554be97dSKrzysztof Parzyszek struct Evaluation; 41554be97dSKrzysztof Parzyszek } 424d4af15cSKareem Ergawy 434d4af15cSKareem Ergawy class AbstractConverter; 444d4af15cSKareem Ergawy 454d4af15cSKareem Ergawy namespace omp { 464d4af15cSKareem Ergawy 474d4af15cSKareem Ergawy using DeclareTargetCapturePair = 487a66e420SKrzysztof Parzyszek std::pair<mlir::omp::DeclareTargetCaptureClause, const semantics::Symbol &>; 494d4af15cSKareem Ergawy 50435e850bSAndrew Gozillon // A small helper structure for keeping track of a component members MapInfoOp 51435e850bSAndrew Gozillon // and index data when lowering OpenMP map clauses. Keeps track of the 52435e850bSAndrew Gozillon // placement of the component in the derived type hierarchy it rests within, 53435e850bSAndrew Gozillon // alongside the generated mlir::omp::MapInfoOp for the mapped component. 54*e508baccSagozillon // 55*e508baccSagozillon // As an example of what the contents of this data structure may be like, 56*e508baccSagozillon // when provided the following derived type and map of that type: 57*e508baccSagozillon // 58*e508baccSagozillon // type :: bottom_layer 59*e508baccSagozillon // real(8) :: i2 60*e508baccSagozillon // real(4) :: array_i2(10) 61*e508baccSagozillon // real(4) :: array_j2(10) 62*e508baccSagozillon // end type bottom_layer 63*e508baccSagozillon // 64*e508baccSagozillon // type :: top_layer 65*e508baccSagozillon // real(4) :: i 66*e508baccSagozillon // integer(4) :: array_i(10) 67*e508baccSagozillon // real(4) :: j 68*e508baccSagozillon // type(bottom_layer) :: nested 69*e508baccSagozillon // integer, allocatable :: array_j(:) 70*e508baccSagozillon // integer(4) :: k 71*e508baccSagozillon // end type top_layer 72*e508baccSagozillon // 73*e508baccSagozillon // type(top_layer) :: top_dtype 74*e508baccSagozillon // 75*e508baccSagozillon // map(tofrom: top_dtype%nested%i2, top_dtype%k, top_dtype%nested%array_i2) 76*e508baccSagozillon // 77*e508baccSagozillon // We would end up with an OmpMapParentAndMemberData populated like below: 78*e508baccSagozillon // 79*e508baccSagozillon // memberPlacementIndices: 80*e508baccSagozillon // Vector 1: 3, 0 81*e508baccSagozillon // Vector 2: 5 82*e508baccSagozillon // Vector 3: 3, 1 83*e508baccSagozillon // 84*e508baccSagozillon // memberMap: 85*e508baccSagozillon // Entry 1: omp.map.info for "top_dtype%nested%i2" 86*e508baccSagozillon // Entry 2: omp.map.info for "top_dtype%k" 87*e508baccSagozillon // Entry 3: omp.map.info for "top_dtype%nested%array_i2" 88*e508baccSagozillon // 89*e508baccSagozillon // And this OmpMapParentAndMemberData would be accessed via the parent 90*e508baccSagozillon // symbol for top_dtype. Other parent derived type instances that have 91*e508baccSagozillon // members mapped would have there own OmpMapParentAndMemberData entry 92*e508baccSagozillon // accessed via their own symbol. 93*e508baccSagozillon struct OmpMapParentAndMemberData { 94435e850bSAndrew Gozillon // The indices representing the component members placement in its derived 95435e850bSAndrew Gozillon // type parents hierarchy. 96*e508baccSagozillon llvm::SmallVector<llvm::SmallVector<int64_t>> memberPlacementIndices; 97435e850bSAndrew Gozillon 98435e850bSAndrew Gozillon // Placement of the member in the member vector. 99*e508baccSagozillon llvm::SmallVector<mlir::omp::MapInfoOp> memberMap; 100*e508baccSagozillon 101*e508baccSagozillon bool isDuplicateMemberMapInfo(llvm::SmallVectorImpl<int64_t> &memberIndices) { 102*e508baccSagozillon return llvm::find_if(memberPlacementIndices, [&](auto &memberData) { 103*e508baccSagozillon return llvm::equal(memberIndices, memberData); 104*e508baccSagozillon }) != memberPlacementIndices.end(); 105*e508baccSagozillon } 106*e508baccSagozillon 107*e508baccSagozillon void addChildIndexAndMapToParent(const omp::Object &object, 108*e508baccSagozillon mlir::omp::MapInfoOp &mapOp, 109*e508baccSagozillon semantics::SemanticsContext &semaCtx); 110435e850bSAndrew Gozillon }; 111435e850bSAndrew Gozillon 1124d4af15cSKareem Ergawy mlir::omp::MapInfoOp 1134d4af15cSKareem Ergawy createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, 114*e508baccSagozillon mlir::Value baseAddr, mlir::Value varPtrPtr, 115*e508baccSagozillon llvm::StringRef name, llvm::ArrayRef<mlir::Value> bounds, 116*e508baccSagozillon llvm::ArrayRef<mlir::Value> members, 117*e508baccSagozillon mlir::ArrayAttr membersIndex, uint64_t mapType, 1184d4af15cSKareem Ergawy mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy, 119435e850bSAndrew Gozillon bool partialMap = false); 120435e850bSAndrew Gozillon 121435e850bSAndrew Gozillon void insertChildMapInfoIntoParent( 122*e508baccSagozillon Fortran::lower::AbstractConverter &converter, 123*e508baccSagozillon Fortran::semantics::SemanticsContext &semaCtx, 124*e508baccSagozillon Fortran::lower::StatementContext &stmtCtx, 125*e508baccSagozillon std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices, 126435e850bSAndrew Gozillon llvm::SmallVectorImpl<mlir::Value> &mapOperands, 12788478a89SSergio Afonso llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms); 1284d4af15cSKareem Ergawy 129*e508baccSagozillon void generateMemberPlacementIndices( 130*e508baccSagozillon const Object &object, llvm::SmallVectorImpl<int64_t> &indices, 131*e508baccSagozillon Fortran::semantics::SemanticsContext &semaCtx); 132*e508baccSagozillon 133*e508baccSagozillon bool isMemberOrParentAllocatableOrPointer( 134*e508baccSagozillon const Object &object, Fortran::semantics::SemanticsContext &semaCtx); 135*e508baccSagozillon 136*e508baccSagozillon mlir::Value createParentSymAndGenIntermediateMaps( 137*e508baccSagozillon mlir::Location clauseLocation, Fortran::lower::AbstractConverter &converter, 138*e508baccSagozillon semantics::SemanticsContext &semaCtx, lower::StatementContext &stmtCtx, 139*e508baccSagozillon omp::ObjectList &objectList, llvm::SmallVectorImpl<int64_t> &indices, 140*e508baccSagozillon OmpMapParentAndMemberData &parentMemberIndices, llvm::StringRef asFortran, 141*e508baccSagozillon llvm::omp::OpenMPOffloadMappingFlags mapTypeBits); 142*e508baccSagozillon 143*e508baccSagozillon omp::ObjectList gatherObjectsOf(omp::Object derivedTypeMember, 144*e508baccSagozillon semantics::SemanticsContext &semaCtx); 145*e508baccSagozillon 1467a66e420SKrzysztof Parzyszek mlir::Type getLoopVarType(lower::AbstractConverter &converter, 14773402634SSergio Afonso std::size_t loopVarTypeSize); 14873402634SSergio Afonso 1497a66e420SKrzysztof Parzyszek semantics::Symbol * 1507a66e420SKrzysztof Parzyszek getIterationVariableSymbol(const lower::pft::Evaluation &eval); 151554be97dSKrzysztof Parzyszek 1524d4af15cSKareem Ergawy void gatherFuncAndVarSyms( 15363e70c05SKrzysztof Parzyszek const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, 1544d4af15cSKareem Ergawy llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause); 1554d4af15cSKareem Ergawy 156992413deSKrzysztof Parzyszek int64_t getCollapseValue(const List<Clause> &clauses); 157992413deSKrzysztof Parzyszek 15863e70c05SKrzysztof Parzyszek void genObjectList(const ObjectList &objects, 1597a66e420SKrzysztof Parzyszek lower::AbstractConverter &converter, 16063e70c05SKrzysztof Parzyszek llvm::SmallVectorImpl<mlir::Value> &operands); 16163e70c05SKrzysztof Parzyszek 162f9824439SKrzysztof Parzyszek void lastprivateModifierNotSupported(const omp::clause::Lastprivate &lastp, 163f9824439SKrzysztof Parzyszek mlir::Location loc); 164f9824439SKrzysztof Parzyszek 1654d4af15cSKareem Ergawy } // namespace omp 1664d4af15cSKareem Ergawy } // namespace lower 1674d4af15cSKareem Ergawy } // namespace Fortran 1684d4af15cSKareem Ergawy 1694d4af15cSKareem Ergawy #endif // FORTRAN_LOWER_OPENMPUTILS_H 170