FLANG
ClauseProcessor.h
1//===-- Lower/OpenMP/ClauseProcessor.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// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10//
11//===----------------------------------------------------------------------===//
12#ifndef FORTRAN_LOWER_CLAUSEPROCESSOR_H
13#define FORTRAN_LOWER_CLAUSEPROCESSOR_H
14
15#include "ClauseFinder.h"
16#include "Utils.h"
17#include "flang/Lower/AbstractConverter.h"
18#include "flang/Lower/Bridge.h"
19#include "flang/Lower/DirectivesCommon.h"
20#include "flang/Lower/OpenMP/Clauses.h"
21#include "flang/Optimizer/Builder/Todo.h"
22#include "flang/Parser/dump-parse-tree.h"
23#include "flang/Parser/parse-tree.h"
24#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
25
26namespace fir {
27class FirOpBuilder;
28} // namespace fir
29
30namespace Fortran {
31namespace lower {
32namespace omp {
33
34// Container type for tracking user specified Defaultmaps for a target region
35using DefaultMapsTy = std::map<clause::Defaultmap::VariableCategory,
36 clause::Defaultmap::ImplicitBehavior>;
37
52class ClauseProcessor {
53public:
54 ClauseProcessor(lower::AbstractConverter &converter,
56 const List<Clause> &clauses)
57 : converter(converter), semaCtx(semaCtx), clauses(clauses) {}
58
59 // 'Unique' clauses: They can appear at most once in the clause list.
60 bool processBare(mlir::omp::BareClauseOps &result) const;
61 bool processBind(mlir::omp::BindClauseOps &result) const;
62 bool processCancelDirectiveName(
63 mlir::omp::CancelDirectiveNameClauseOps &result) const;
64 bool
65 processCollapse(mlir::Location currentLocation, lower::pft::Evaluation &eval,
66 mlir::omp::LoopRelatedClauseOps &loopResult,
67 mlir::omp::CollapseClauseOps &collapseResult,
68 llvm::SmallVectorImpl<const semantics::Symbol *> &iv) const;
69 bool processDevice(lower::StatementContext &stmtCtx,
70 mlir::omp::DeviceClauseOps &result) const;
71 bool processDeviceType(mlir::omp::DeviceTypeClauseOps &result) const;
72 bool processDistSchedule(lower::StatementContext &stmtCtx,
73 mlir::omp::DistScheduleClauseOps &result) const;
74 bool processExclusive(mlir::Location currentLocation,
75 mlir::omp::ExclusiveClauseOps &result) const;
76 bool processFilter(lower::StatementContext &stmtCtx,
77 mlir::omp::FilterClauseOps &result) const;
78 bool processFinal(lower::StatementContext &stmtCtx,
79 mlir::omp::FinalClauseOps &result) const;
80 bool processGrainsize(lower::StatementContext &stmtCtx,
81 mlir::omp::GrainsizeClauseOps &result) const;
82 bool processHasDeviceAddr(
84 mlir::omp::HasDeviceAddrClauseOps &result,
85 llvm::SmallVectorImpl<const semantics::Symbol *> &hasDeviceSyms) const;
86 bool processHint(mlir::omp::HintClauseOps &result) const;
87 bool processInclusive(mlir::Location currentLocation,
88 mlir::omp::InclusiveClauseOps &result) const;
89 bool processMergeable(mlir::omp::MergeableClauseOps &result) const;
90 bool processNowait(mlir::omp::NowaitClauseOps &result) const;
91 bool processNumTasks(lower::StatementContext &stmtCtx,
92 mlir::omp::NumTasksClauseOps &result) const;
93 bool processNumTeams(lower::StatementContext &stmtCtx,
94 mlir::omp::NumTeamsClauseOps &result) const;
95 bool processNumThreads(lower::StatementContext &stmtCtx,
96 mlir::omp::NumThreadsClauseOps &result) const;
97 bool processOrder(mlir::omp::OrderClauseOps &result) const;
98 bool processOrdered(mlir::omp::OrderedClauseOps &result) const;
99 bool processPriority(lower::StatementContext &stmtCtx,
100 mlir::omp::PriorityClauseOps &result) const;
101 bool processProcBind(mlir::omp::ProcBindClauseOps &result) const;
102 bool processTileSizes(lower::pft::Evaluation &eval,
103 mlir::omp::LoopNestOperands &result) const;
104 bool processSafelen(mlir::omp::SafelenClauseOps &result) const;
105 bool processSchedule(lower::StatementContext &stmtCtx,
106 mlir::omp::ScheduleClauseOps &result) const;
107 bool processSimdlen(mlir::omp::SimdlenClauseOps &result) const;
108 bool processThreadLimit(lower::StatementContext &stmtCtx,
109 mlir::omp::ThreadLimitClauseOps &result) const;
110 bool processUntied(mlir::omp::UntiedClauseOps &result) const;
111
112 bool processDetach(mlir::omp::DetachClauseOps &result) const;
113 // 'Repeatable' clauses: They can appear multiple times in the clause list.
114 bool processAligned(mlir::omp::AlignedClauseOps &result) const;
115 bool processAllocate(mlir::omp::AllocateClauseOps &result) const;
116 bool processCopyin() const;
117 bool processCopyprivate(mlir::Location currentLocation,
118 mlir::omp::CopyprivateClauseOps &result) const;
119 bool processDefaultMap(lower::StatementContext &stmtCtx,
120 DefaultMapsTy &result) const;
121 bool processDepend(lower::SymMap &symMap, lower::StatementContext &stmtCtx,
122 mlir::omp::DependClauseOps &result) const;
123 bool
124 processEnter(llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &result) const;
125 bool processIf(omp::clause::If::DirectiveNameModifier directiveName,
126 mlir::omp::IfClauseOps &result) const;
127 bool processInReduction(
128 mlir::Location currentLocation, mlir::omp::InReductionClauseOps &result,
129 llvm::SmallVectorImpl<const semantics::Symbol *> &outReductionSyms) const;
130 bool processIsDevicePtr(
131 mlir::omp::IsDevicePtrClauseOps &result,
132 llvm::SmallVectorImpl<const semantics::Symbol *> &isDeviceSyms) const;
133 bool processLinear(mlir::omp::LinearClauseOps &result) const;
134 bool
135 processLink(llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &result) const;
136
137 // This method is used to process a map clause.
138 // The optional parameter mapSyms is used to store the original Fortran symbol
139 // for the map operands. It may be used later on to create the block_arguments
140 // for some of the directives that require it.
141 bool processMap(mlir::Location currentLocation,
143 mlir::omp::MapClauseOps &result,
144 llvm::omp::Directive directive = llvm::omp::OMPD_unknown,
145 llvm::SmallVectorImpl<const semantics::Symbol *> *mapSyms =
146 nullptr) const;
147 bool processMotionClauses(lower::StatementContext &stmtCtx,
148 mlir::omp::MapClauseOps &result);
149 bool processNontemporal(mlir::omp::NontemporalClauseOps &result) const;
150 bool processReduction(
151 mlir::Location currentLocation, mlir::omp::ReductionClauseOps &result,
152 llvm::SmallVectorImpl<const semantics::Symbol *> &reductionSyms) const;
153 bool processTaskReduction(
154 mlir::Location currentLocation, mlir::omp::TaskReductionClauseOps &result,
155 llvm::SmallVectorImpl<const semantics::Symbol *> &outReductionSyms) const;
156 bool processTo(llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &result) const;
157 bool processUseDeviceAddr(
159 mlir::omp::UseDeviceAddrClauseOps &result,
160 llvm::SmallVectorImpl<const semantics::Symbol *> &useDeviceSyms) const;
161 bool processUseDevicePtr(
163 mlir::omp::UseDevicePtrClauseOps &result,
164 llvm::SmallVectorImpl<const semantics::Symbol *> &useDeviceSyms) const;
165
166 // Call this method for these clauses that should be supported but are not
167 // implemented yet. It triggers a compilation error if any of the given
168 // clauses is found.
169 template <typename... Ts>
170 void processTODO(mlir::Location currentLocation,
171 llvm::omp::Directive directive) const;
172
173private:
174 using ClauseIterator = List<Clause>::const_iterator;
175
179 template <typename T>
180 const T *findUniqueClause(const parser::CharBlock **source = nullptr) const;
181
184 template <typename T>
185 bool findRepeatableClause(
186 std::function<void(const T &, const parser::CharBlock &source)>
187 callbackFn) const;
188
190 template <typename T>
191 bool markClauseOccurrence(mlir::UnitAttr &result) const;
192
193 void processMapObjects(
194 lower::StatementContext &stmtCtx, mlir::Location clauseLocation,
195 const omp::ObjectList &objects,
196 llvm::omp::OpenMPOffloadMappingFlags mapTypeBits,
197 std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices,
198 llvm::SmallVectorImpl<mlir::Value> &mapVars,
199 llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms,
200 llvm::StringRef mapperIdNameRef = "") const;
201
202 lower::AbstractConverter &converter;
204 List<Clause> clauses;
205};
206
207template <typename... Ts>
208void ClauseProcessor::processTODO(mlir::Location currentLocation,
209 llvm::omp::Directive directive) const {
210 auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) {
211 if (!x)
212 return;
213 unsigned version = semaCtx.langOptions().OpenMPVersion;
214 bool isSimdDirective = llvm::omp::getOpenMPDirectiveName(directive, version)
215 .upper()
216 .find("SIMD") != llvm::StringRef::npos;
217 if (!semaCtx.langOptions().OpenMPSimd || isSimdDirective)
218 TODO(currentLocation,
219 "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() +
220 " in " +
221 llvm::omp::getOpenMPDirectiveName(directive, version).upper() +
222 " construct");
223 };
224
225 for (ClauseIterator it = clauses.begin(); it != clauses.end(); ++it)
226 (checkUnhandledClause(it->id, std::get_if<Ts>(&it->u)), ...);
227}
228
229template <typename T>
230const T *
231ClauseProcessor::findUniqueClause(const parser::CharBlock **source) const {
232 return ClauseFinder::findUniqueClause<T>(clauses, source);
233}
234
235template <typename T>
236bool ClauseProcessor::findRepeatableClause(
237 std::function<void(const T &, const parser::CharBlock &source)> callbackFn)
238 const {
239 return ClauseFinder::findRepeatableClause<T>(clauses, callbackFn);
240}
241
242template <typename T>
243bool ClauseProcessor::markClauseOccurrence(mlir::UnitAttr &result) const {
244 if (findUniqueClause<T>()) {
245 result = converter.getFirOpBuilder().getUnitAttr();
246 return true;
247 }
248 return false;
249}
250
251} // namespace omp
252} // namespace lower
253} // namespace Fortran
254
255#endif // FORTRAN_LOWER_CLAUSEPROCESSOR_H
Definition AbstractConverter.h:85
Definition StatementContext.h:46
Definition SymbolMap.h:146
static bool findRepeatableClause(const List< Clause > &clauses, std::function< void(const T &, const parser::CharBlock &source)> callbackFn)
Definition ClauseFinder.h:54
static const T * findUniqueClause(const List< Clause > &clauses, const parser::CharBlock **source=nullptr)
Definition ClauseFinder.h:40
Definition char-block.h:28
Definition semantics.h:67
Definition FIRBuilder.h:55
Definition ParserActions.h:24
Definition bit-population-count.h:20
Definition AbstractConverter.h:34
Definition PFTBuilder.h:221