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