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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_LOWER_OPENMPUTILS_H
10#define FORTRAN_LOWER_OPENMPUTILS_H
11
12#include "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;
23} // namespace fir
24namespace Fortran {
25
26namespace semantics {
27class Symbol;
28} // namespace semantics
29
30namespace parser {
31struct OmpObject;
32struct OmpObjectList;
33} // namespace parser
34
35namespace lower {
36class StatementContext;
37namespace pft {
38struct Evaluation;
39}
40
41class AbstractConverter;
42
43namespace omp {
44
45using DeclareTargetCapturePair =
46 std::pair<mlir::omp::DeclareTargetCaptureClause, const semantics::Symbol &>;
47
48// A small helper structure for keeping track of a component members MapInfoOp
49// and index data when lowering OpenMP map clauses. Keeps track of the
50// placement of the component in the derived type hierarchy it rests within,
51// alongside the generated mlir::omp::MapInfoOp for the mapped component.
52//
53// As an example of what the contents of this data structure may be like,
54// when provided the following derived type and map of that type:
55//
56// type :: bottom_layer
57// real(8) :: i2
58// real(4) :: array_i2(10)
59// real(4) :: array_j2(10)
60// end type bottom_layer
61//
62// type :: top_layer
63// real(4) :: i
64// integer(4) :: array_i(10)
65// real(4) :: j
66// type(bottom_layer) :: nested
67// integer, allocatable :: array_j(:)
68// integer(4) :: k
69// end type top_layer
70//
71// type(top_layer) :: top_dtype
72//
73// map(tofrom: top_dtype%nested%i2, top_dtype%k, top_dtype%nested%array_i2)
74//
75// We would end up with an OmpMapParentAndMemberData populated like below:
76//
77// memberPlacementIndices:
78// Vector 1: 3, 0
79// Vector 2: 5
80// Vector 3: 3, 1
81//
82// memberMap:
83// Entry 1: omp.map.info for "top_dtype%nested%i2"
84// Entry 2: omp.map.info for "top_dtype%k"
85// Entry 3: omp.map.info for "top_dtype%nested%array_i2"
86//
87// And this OmpMapParentAndMemberData would be accessed via the parent
88// symbol for top_dtype. Other parent derived type instances that have
89// members mapped would have there own OmpMapParentAndMemberData entry
90// accessed via their own symbol.
91struct OmpMapParentAndMemberData {
92 // The indices representing the component members placement in its derived
93 // type parents hierarchy.
94 llvm::SmallVector<llvm::SmallVector<int64_t>> memberPlacementIndices;
95
96 // Placement of the member in the member vector.
97 llvm::SmallVector<mlir::omp::MapInfoOp> memberMap;
98
99 bool isDuplicateMemberMapInfo(llvm::SmallVectorImpl<int64_t> &memberIndices) {
100 return llvm::find_if(Range&: memberPlacementIndices, P: [&](auto &memberData) {
101 return llvm::equal(memberIndices, memberData);
102 }) != memberPlacementIndices.end();
103 }
104
105 void addChildIndexAndMapToParent(const omp::Object &object,
106 mlir::omp::MapInfoOp &mapOp,
107 semantics::SemanticsContext &semaCtx);
108};
109
110mlir::omp::MapInfoOp
111createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc,
112 mlir::Value baseAddr, mlir::Value varPtrPtr,
113 llvm::StringRef name, llvm::ArrayRef<mlir::Value> bounds,
114 llvm::ArrayRef<mlir::Value> members,
115 mlir::ArrayAttr membersIndex, uint64_t mapType,
116 mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy,
117 bool partialMap = false,
118 mlir::FlatSymbolRefAttr mapperId = mlir::FlatSymbolRefAttr());
119
120void insertChildMapInfoIntoParent(
121 Fortran::lower::AbstractConverter &converter,
122 Fortran::semantics::SemanticsContext &semaCtx,
123 Fortran::lower::StatementContext &stmtCtx,
124 std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices,
125 llvm::SmallVectorImpl<mlir::Value> &mapOperands,
126 llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms);
127
128void generateMemberPlacementIndices(
129 const Object &object, llvm::SmallVectorImpl<int64_t> &indices,
130 Fortran::semantics::SemanticsContext &semaCtx);
131
132bool isMemberOrParentAllocatableOrPointer(
133 const Object &object, Fortran::semantics::SemanticsContext &semaCtx);
134
135mlir::Value createParentSymAndGenIntermediateMaps(
136 mlir::Location clauseLocation, Fortran::lower::AbstractConverter &converter,
137 semantics::SemanticsContext &semaCtx, lower::StatementContext &stmtCtx,
138 omp::ObjectList &objectList, llvm::SmallVectorImpl<int64_t> &indices,
139 OmpMapParentAndMemberData &parentMemberIndices, llvm::StringRef asFortran,
140 llvm::omp::OpenMPOffloadMappingFlags mapTypeBits);
141
142omp::ObjectList gatherObjectsOf(omp::Object derivedTypeMember,
143 semantics::SemanticsContext &semaCtx);
144
145mlir::Type getLoopVarType(lower::AbstractConverter &converter,
146 std::size_t loopVarTypeSize);
147
148semantics::Symbol *
149getIterationVariableSymbol(const lower::pft::Evaluation &eval);
150
151void gatherFuncAndVarSyms(
152 const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause,
153 llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause);
154
155int64_t getCollapseValue(const List<Clause> &clauses);
156
157void genObjectList(const ObjectList &objects,
158 lower::AbstractConverter &converter,
159 llvm::SmallVectorImpl<mlir::Value> &operands);
160
161void lastprivateModifierNotSupported(const omp::clause::Lastprivate &lastp,
162 mlir::Location loc);
163
164bool collectLoopRelatedInfo(
165 lower::AbstractConverter &converter, mlir::Location currentLocation,
166 lower::pft::Evaluation &eval, const omp::List<omp::Clause> &clauses,
167 mlir::omp::LoopRelatedClauseOps &result,
168 llvm::SmallVectorImpl<const semantics::Symbol *> &iv);
169} // namespace omp
170} // namespace lower
171} // namespace Fortran
172
173#endif // FORTRAN_LOWER_OPENMPUTILS_H
174

source code of flang/lib/Lower/OpenMP/Utils.h