1//===-- Clauses.h -- OpenMP clause handling -------------------------------===//
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#ifndef FORTRAN_LOWER_OPENMP_CLAUSES_H
9#define FORTRAN_LOWER_OPENMP_CLAUSES_H
10
11#include "flang/Evaluate/expression.h"
12#include "flang/Parser/parse-tree.h"
13#include "flang/Semantics/expression.h"
14#include "flang/Semantics/semantics.h"
15#include "flang/Semantics/symbol.h"
16
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/Frontend/OpenMP/ClauseT.h"
19
20#include <optional>
21#include <type_traits>
22#include <utility>
23
24namespace Fortran::lower::omp {
25using namespace Fortran;
26using SomeType = evaluate::SomeType;
27using SomeExpr = semantics::SomeExpr;
28using MaybeExpr = semantics::MaybeExpr;
29
30using TypeTy = SomeType;
31using IdTy = semantics::Symbol *;
32using ExprTy = SomeExpr;
33
34template <typename T>
35using List = tomp::ListT<T>;
36} // namespace Fortran::lower::omp
37
38namespace tomp::type {
39template <>
40struct ObjectT<Fortran::lower::omp::IdTy, Fortran::lower::omp::ExprTy> {
41 using IdTy = Fortran::lower::omp::IdTy;
42 using ExprTy = Fortran::lower::omp::ExprTy;
43
44 const IdTy &id() const { return symbol; }
45 const std::optional<ExprTy> &ref() const { return designator; }
46
47 IdTy symbol;
48 std::optional<ExprTy> designator;
49};
50} // namespace tomp::type
51
52namespace Fortran::lower::omp {
53
54using Object = tomp::ObjectT<IdTy, ExprTy>;
55using ObjectList = tomp::ObjectListT<IdTy, ExprTy>;
56
57Object makeObject(const parser::OmpObject &object,
58 semantics::SemanticsContext &semaCtx);
59Object makeObject(const parser::Name &name,
60 semantics::SemanticsContext &semaCtx);
61Object makeObject(const parser::Designator &dsg,
62 semantics::SemanticsContext &semaCtx);
63Object makeObject(const parser::StructureComponent &comp,
64 semantics::SemanticsContext &semaCtx);
65
66inline auto makeObjectFn(semantics::SemanticsContext &semaCtx) {
67 return [&](auto &&s) { return makeObject(s, semaCtx); };
68}
69
70template <typename T>
71SomeExpr makeExpr(T &&pftExpr, semantics::SemanticsContext &semaCtx) {
72 auto maybeExpr = evaluate::ExpressionAnalyzer(semaCtx).Analyze(pftExpr);
73 assert(maybeExpr);
74 return std::move(*maybeExpr);
75}
76
77inline auto makeExprFn(semantics::SemanticsContext &semaCtx) {
78 return [&](auto &&s) { return makeExpr(s, semaCtx); };
79}
80
81template <
82 typename ContainerTy, typename FunctionTy,
83 typename ElemTy = typename llvm::remove_cvref_t<ContainerTy>::value_type,
84 typename ResultTy = std::invoke_result_t<FunctionTy, ElemTy>>
85List<ResultTy> makeList(ContainerTy &&container, FunctionTy &&func) {
86 List<ResultTy> v;
87 llvm::transform(container, std::back_inserter(v), func);
88 return v;
89}
90
91inline ObjectList makeObjects(const parser::OmpObjectList &objects,
92 semantics::SemanticsContext &semaCtx) {
93 return makeList(objects.v, makeObjectFn(semaCtx));
94}
95
96template <typename FuncTy, //
97 typename ArgTy, //
98 typename ResultTy = std::invoke_result_t<FuncTy, ArgTy>>
99std::optional<ResultTy> maybeApply(FuncTy &&func,
100 const std::optional<ArgTy> &arg) {
101 if (!arg)
102 return std::nullopt;
103 return std::move(func(*arg));
104}
105
106std::optional<Object>
107getBaseObject(const Object &object,
108 Fortran::semantics::SemanticsContext &semaCtx);
109
110namespace clause {
111using DefinedOperator = tomp::type::DefinedOperatorT<IdTy, ExprTy>;
112using ProcedureDesignator = tomp::type::ProcedureDesignatorT<IdTy, ExprTy>;
113using ReductionOperator = tomp::type::ReductionIdentifierT<IdTy, ExprTy>;
114
115// "Requires" clauses are handled early on, and the aggregated information
116// is stored in the Symbol details of modules, programs, and subprograms.
117// These clauses are still handled here to cover all alternatives in the
118// main clause variant.
119
120using AcqRel = tomp::clause::AcqRelT<TypeTy, IdTy, ExprTy>;
121using Acquire = tomp::clause::AcquireT<TypeTy, IdTy, ExprTy>;
122using AdjustArgs = tomp::clause::AdjustArgsT<TypeTy, IdTy, ExprTy>;
123using Affinity = tomp::clause::AffinityT<TypeTy, IdTy, ExprTy>;
124using Aligned = tomp::clause::AlignedT<TypeTy, IdTy, ExprTy>;
125using Align = tomp::clause::AlignT<TypeTy, IdTy, ExprTy>;
126using Allocate = tomp::clause::AllocateT<TypeTy, IdTy, ExprTy>;
127using Allocator = tomp::clause::AllocatorT<TypeTy, IdTy, ExprTy>;
128using AppendArgs = tomp::clause::AppendArgsT<TypeTy, IdTy, ExprTy>;
129using AtomicDefaultMemOrder =
130 tomp::clause::AtomicDefaultMemOrderT<TypeTy, IdTy, ExprTy>;
131using At = tomp::clause::AtT<TypeTy, IdTy, ExprTy>;
132using Bind = tomp::clause::BindT<TypeTy, IdTy, ExprTy>;
133using Capture = tomp::clause::CaptureT<TypeTy, IdTy, ExprTy>;
134using Collapse = tomp::clause::CollapseT<TypeTy, IdTy, ExprTy>;
135using Compare = tomp::clause::CompareT<TypeTy, IdTy, ExprTy>;
136using Copyin = tomp::clause::CopyinT<TypeTy, IdTy, ExprTy>;
137using Copyprivate = tomp::clause::CopyprivateT<TypeTy, IdTy, ExprTy>;
138using Defaultmap = tomp::clause::DefaultmapT<TypeTy, IdTy, ExprTy>;
139using Default = tomp::clause::DefaultT<TypeTy, IdTy, ExprTy>;
140using Depend = tomp::clause::DependT<TypeTy, IdTy, ExprTy>;
141using Destroy = tomp::clause::DestroyT<TypeTy, IdTy, ExprTy>;
142using Detach = tomp::clause::DetachT<TypeTy, IdTy, ExprTy>;
143using Device = tomp::clause::DeviceT<TypeTy, IdTy, ExprTy>;
144using DeviceType = tomp::clause::DeviceTypeT<TypeTy, IdTy, ExprTy>;
145using DistSchedule = tomp::clause::DistScheduleT<TypeTy, IdTy, ExprTy>;
146using Doacross = tomp::clause::DoacrossT<TypeTy, IdTy, ExprTy>;
147using DynamicAllocators =
148 tomp::clause::DynamicAllocatorsT<TypeTy, IdTy, ExprTy>;
149using Enter = tomp::clause::EnterT<TypeTy, IdTy, ExprTy>;
150using Exclusive = tomp::clause::ExclusiveT<TypeTy, IdTy, ExprTy>;
151using Fail = tomp::clause::FailT<TypeTy, IdTy, ExprTy>;
152using Filter = tomp::clause::FilterT<TypeTy, IdTy, ExprTy>;
153using Final = tomp::clause::FinalT<TypeTy, IdTy, ExprTy>;
154using Firstprivate = tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>;
155using From = tomp::clause::FromT<TypeTy, IdTy, ExprTy>;
156using Full = tomp::clause::FullT<TypeTy, IdTy, ExprTy>;
157using Grainsize = tomp::clause::GrainsizeT<TypeTy, IdTy, ExprTy>;
158using HasDeviceAddr = tomp::clause::HasDeviceAddrT<TypeTy, IdTy, ExprTy>;
159using Hint = tomp::clause::HintT<TypeTy, IdTy, ExprTy>;
160using If = tomp::clause::IfT<TypeTy, IdTy, ExprTy>;
161using Inbranch = tomp::clause::InbranchT<TypeTy, IdTy, ExprTy>;
162using Inclusive = tomp::clause::InclusiveT<TypeTy, IdTy, ExprTy>;
163using Indirect = tomp::clause::IndirectT<TypeTy, IdTy, ExprTy>;
164using Init = tomp::clause::InitT<TypeTy, IdTy, ExprTy>;
165using InReduction = tomp::clause::InReductionT<TypeTy, IdTy, ExprTy>;
166using IsDevicePtr = tomp::clause::IsDevicePtrT<TypeTy, IdTy, ExprTy>;
167using Lastprivate = tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>;
168using Linear = tomp::clause::LinearT<TypeTy, IdTy, ExprTy>;
169using Link = tomp::clause::LinkT<TypeTy, IdTy, ExprTy>;
170using Map = tomp::clause::MapT<TypeTy, IdTy, ExprTy>;
171using Match = tomp::clause::MatchT<TypeTy, IdTy, ExprTy>;
172using Mergeable = tomp::clause::MergeableT<TypeTy, IdTy, ExprTy>;
173using Message = tomp::clause::MessageT<TypeTy, IdTy, ExprTy>;
174using Nocontext = tomp::clause::NocontextT<TypeTy, IdTy, ExprTy>;
175using Nogroup = tomp::clause::NogroupT<TypeTy, IdTy, ExprTy>;
176using Nontemporal = tomp::clause::NontemporalT<TypeTy, IdTy, ExprTy>;
177using Notinbranch = tomp::clause::NotinbranchT<TypeTy, IdTy, ExprTy>;
178using Novariants = tomp::clause::NovariantsT<TypeTy, IdTy, ExprTy>;
179using Nowait = tomp::clause::NowaitT<TypeTy, IdTy, ExprTy>;
180using NumTasks = tomp::clause::NumTasksT<TypeTy, IdTy, ExprTy>;
181using NumTeams = tomp::clause::NumTeamsT<TypeTy, IdTy, ExprTy>;
182using NumThreads = tomp::clause::NumThreadsT<TypeTy, IdTy, ExprTy>;
183using OmpxAttribute = tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy>;
184using OmpxBare = tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy>;
185using OmpxDynCgroupMem = tomp::clause::OmpxDynCgroupMemT<TypeTy, IdTy, ExprTy>;
186using Ordered = tomp::clause::OrderedT<TypeTy, IdTy, ExprTy>;
187using Order = tomp::clause::OrderT<TypeTy, IdTy, ExprTy>;
188using Partial = tomp::clause::PartialT<TypeTy, IdTy, ExprTy>;
189using Priority = tomp::clause::PriorityT<TypeTy, IdTy, ExprTy>;
190using Private = tomp::clause::PrivateT<TypeTy, IdTy, ExprTy>;
191using ProcBind = tomp::clause::ProcBindT<TypeTy, IdTy, ExprTy>;
192using Read = tomp::clause::ReadT<TypeTy, IdTy, ExprTy>;
193using Reduction = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
194using Relaxed = tomp::clause::RelaxedT<TypeTy, IdTy, ExprTy>;
195using Release = tomp::clause::ReleaseT<TypeTy, IdTy, ExprTy>;
196using ReverseOffload = tomp::clause::ReverseOffloadT<TypeTy, IdTy, ExprTy>;
197using Safelen = tomp::clause::SafelenT<TypeTy, IdTy, ExprTy>;
198using Schedule = tomp::clause::ScheduleT<TypeTy, IdTy, ExprTy>;
199using SeqCst = tomp::clause::SeqCstT<TypeTy, IdTy, ExprTy>;
200using Severity = tomp::clause::SeverityT<TypeTy, IdTy, ExprTy>;
201using Shared = tomp::clause::SharedT<TypeTy, IdTy, ExprTy>;
202using Simdlen = tomp::clause::SimdlenT<TypeTy, IdTy, ExprTy>;
203using Simd = tomp::clause::SimdT<TypeTy, IdTy, ExprTy>;
204using Sizes = tomp::clause::SizesT<TypeTy, IdTy, ExprTy>;
205using TaskReduction = tomp::clause::TaskReductionT<TypeTy, IdTy, ExprTy>;
206using ThreadLimit = tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy>;
207using Threads = tomp::clause::ThreadsT<TypeTy, IdTy, ExprTy>;
208using To = tomp::clause::ToT<TypeTy, IdTy, ExprTy>;
209using UnifiedAddress = tomp::clause::UnifiedAddressT<TypeTy, IdTy, ExprTy>;
210using UnifiedSharedMemory =
211 tomp::clause::UnifiedSharedMemoryT<TypeTy, IdTy, ExprTy>;
212using Uniform = tomp::clause::UniformT<TypeTy, IdTy, ExprTy>;
213using Unknown = tomp::clause::UnknownT<TypeTy, IdTy, ExprTy>;
214using Untied = tomp::clause::UntiedT<TypeTy, IdTy, ExprTy>;
215using Update = tomp::clause::UpdateT<TypeTy, IdTy, ExprTy>;
216using UseDeviceAddr = tomp::clause::UseDeviceAddrT<TypeTy, IdTy, ExprTy>;
217using UseDevicePtr = tomp::clause::UseDevicePtrT<TypeTy, IdTy, ExprTy>;
218using UsesAllocators = tomp::clause::UsesAllocatorsT<TypeTy, IdTy, ExprTy>;
219using Use = tomp::clause::UseT<TypeTy, IdTy, ExprTy>;
220using Weak = tomp::clause::WeakT<TypeTy, IdTy, ExprTy>;
221using When = tomp::clause::WhenT<TypeTy, IdTy, ExprTy>;
222using Write = tomp::clause::WriteT<TypeTy, IdTy, ExprTy>;
223} // namespace clause
224
225struct CancellationConstructType {
226 using EmptyTrait = std::true_type;
227};
228struct Depobj {
229 using EmptyTrait = std::true_type;
230};
231struct Flush {
232 using EmptyTrait = std::true_type;
233};
234struct MemoryOrder {
235 using EmptyTrait = std::true_type;
236};
237struct Threadprivate {
238 using EmptyTrait = std::true_type;
239};
240
241using ClauseBase = tomp::ClauseT<TypeTy, IdTy, ExprTy,
242 // Extras...
243 CancellationConstructType, Depobj, Flush,
244 MemoryOrder, Threadprivate>;
245
246struct Clause : public ClauseBase {
247 parser::CharBlock source;
248};
249
250template <typename Specific>
251Clause makeClause(llvm::omp::Clause id, Specific &&specific,
252 parser::CharBlock source = {}) {
253 return Clause{{id, specific}, source};
254}
255
256Clause makeClause(const Fortran::parser::OmpClause &cls,
257 semantics::SemanticsContext &semaCtx);
258
259List<Clause> makeClauses(const parser::OmpClauseList &clauses,
260 semantics::SemanticsContext &semaCtx);
261} // namespace Fortran::lower::omp
262
263#endif // FORTRAN_LOWER_OPENMP_CLAUSES_H
264

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