13#ifndef FORTRAN_PARSER_OPENMP_UTILS_H
14#define FORTRAN_PARSER_OPENMP_UTILS_H
16#include "flang/Common/indirection.h"
17#include "flang/Common/template.h"
18#include "flang/Parser/parse-tree.h"
19#include "llvm/Frontend/OpenMP/OMP.h"
28namespace Fortran::parser::omp {
30template <
typename T>
constexpr auto addr_if(std::optional<T> &x) {
31 return x ? &*x :
nullptr;
33template <
typename T>
constexpr auto addr_if(
const std::optional<T> &x) {
34 return x ? &*x :
nullptr;
40 llvm::omp::Directive
id = llvm::omp::Directive::OMPD_unknown) {
56 if (
auto &spec{std::get<std::optional<OmpDirectiveSpecification>>(x.t)}) {
57 return spec->DirName();
59 return MakeName({}, llvm::omp::Directive::OMPD_section);
70 if constexpr (WrapperTrait<T>) {
71 return GetOmpDirectiveName(x.v);
72 }
else if constexpr (TupleTrait<T>) {
73 if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
74 return std::get<OmpBeginDirective>(x.t).DirName();
77 x.t, std::make_index_sequence<std::tuple_size_v<
decltype(x.t)>>{});
79 }
else if constexpr (UnionTrait<T>) {
81 [](
auto &&s) {
return GetOmpDirectiveName(s); }, x.u);
87 template <
typename... Ts,
size_t... Is>
89 const std::tuple<Ts...> &t, std::index_sequence<Is...>) {
92 if (name.v == llvm::omp::Directive::OMPD_unknown) {
96 n.v == llvm::omp::Directive::OMPD_unknown &&
"Conflicting names");
99 (accumulate(GetOmpDirectiveName(std::get<Is>(t))), ...);
103 template <
typename T>
105 return GetOmpDirectiveName(x.value());
111 return detail::DirectiveNameScope::GetOmpDirectiveName(x);
122 static constexpr bool value{
false};
125 static constexpr bool value{
true};
133using MemberObjectListClauses =
134 std::tuple<OmpClause::Copyin, OmpClause::Copyprivate, OmpClause::Exclusive,
135 OmpClause::Firstprivate, OmpClause::HasDeviceAddr, OmpClause::Inclusive,
136 OmpClause::IsDevicePtr, OmpClause::Link, OmpClause::Private,
137 OmpClause::Shared, OmpClause::UseDeviceAddr, OmpClause::UseDevicePtr>;
141using TupleObjectListClauses = std::tuple<OmpClause::AdjustArgs,
142 OmpClause::Affinity, OmpClause::Aligned, OmpClause::Allocate,
143 OmpClause::Enter, OmpClause::From, OmpClause::InReduction,
144 OmpClause::Lastprivate, OmpClause::Linear, OmpClause::Map,
145 OmpClause::Reduction, OmpClause::TaskReduction, OmpClause::To>;
150 static constexpr bool value{
false};
154 static constexpr bool value{std::is_same_v<T,
decltype(U::v)>};
162 static constexpr bool value{
false};
165template <
typename T,
typename U,
typename... Us>
174 static constexpr bool value{
false};
176template <
typename T,
typename... Us>
180template <
typename T,
typename... Us>
184template <
typename T,
typename U>
185constexpr bool WrappedInTupleOrVariantV{WrappedInTupleOrVariant<T, U>::value};
188template <
typename T>
const OmpObjectList *GetOmpObjectList(
const T &clause) {
189 using namespace detail;
190 static_assert(std::is_class_v<T>,
"Unexpected argument type");
192 if constexpr (common::HasMember<T,
decltype(OmpClause::u)>) {
193 if constexpr (common::HasMember<T, MemberObjectListClauses>) {
195 }
else if constexpr (common::HasMember<T, TupleObjectListClauses>) {
196 return &std::get<OmpObjectList>(clause.v.t);
200 }
else if constexpr (WrappedInTupleOrVariantV<T, TupleObjectListClauses>) {
201 return &std::get<OmpObjectList>(clause.t);
202 }
else if constexpr (WrappedInTupleOrVariantV<T,
decltype(OmpClause::u)>) {
206 static_assert(
sizeof(T) < 0 &&
"Unexpected argument type");
210const OmpObjectList *GetOmpObjectList(
const OmpClause &clause);
211const OmpObjectList *GetOmpObjectList(
const OmpClause::Depend &clause);
212const OmpObjectList *GetOmpObjectList(
const OmpDependClause::TaskDep &x);
215const T *GetFirstArgument(
const OmpDirectiveSpecification &spec) {
216 for (
const OmpArgument &arg : spec.Arguments().v) {
217 if (
auto *t{std::get_if<T>(&arg.u)}) {
224const BlockConstruct *GetFortranBlockConstruct(
225 const ExecutionPartConstruct &epc);
226const Block &GetInnermostExecPart(
const Block &block);
227bool IsStrictlyStructuredBlock(
const Block &block);
229const OmpCombinerExpression *GetCombinerExpr(
230 const OmpReductionSpecifier &rspec);
231const OmpInitializerExpression *GetInitializerExpr(
const OmpClause &init);
234 std::vector<const OmpAllocateDirective *> dirs;
241template <
bool IsConst,
typename T>
struct ConstIf {
242 using type = std::conditional_t<IsConst, std::add_const_t<T>, T>;
245template <
bool IsConst,
typename T>
246using ConstIfT =
typename ConstIf<IsConst, T>::type;
249template <
bool IsConst>
struct LoopRange {
250 using QualBlock = detail::ConstIfT<IsConst, Block>;
251 using QualReference =
decltype(std::declval<QualBlock>().front());
252 using QualPointer = std::remove_reference_t<QualReference> *;
254 LoopRange(QualBlock &x) { Initialize(x); }
255 LoopRange(QualReference x);
257 LoopRange(detail::ConstIfT<IsConst, OpenMPLoopConstruct> &x)
258 : LoopRange(std::get<Block>(x.t)) {}
259 LoopRange(detail::ConstIfT<IsConst, DoConstruct> &x)
260 : LoopRange(std::get<Block>(x.t)) {}
262 size_t size()
const {
return items.size(); }
263 bool empty()
const {
return items.size() == 0; }
271 void Initialize(QualBlock &body);
273 std::vector<QualPointer> items;
278template <
bool IsConst>
struct LoopRange<IsConst>::
iterator {
279 QualReference operator*() {
return **at; }
281 bool operator==(
const iterator &other)
const {
return at == other.at; }
282 bool operator!=(
const iterator &other)
const {
return at != other.at; }
296 friend struct LoopRange;
297 typename decltype(LoopRange::items)
::iterator at;
300template <
bool IsConst>
inline auto LoopRange<IsConst>::begin() ->
iterator {
302 x.at = items.begin();
306template <
bool IsConst>
inline auto LoopRange<IsConst>::end() -> iterator {
Definition indirection.h:31
Definition char-block.h:28
Definition parse-tree.h:437
Definition parse-tree.h:2348
Definition parse-tree.h:554
Definition parse-tree.h:5283
Definition parse-tree.h:5420
Definition parse-tree.h:5148
Definition parse-tree.h:3516
Definition parse-tree.h:3561
Definition parse-tree.h:5455
Definition parse-tree.h:5287
Definition parse-tree.h:5429
Definition parse-tree.h:5162
Definition parse-tree.h:359
Definition openmp-utils.h:121
Definition openmp-utils.h:278
Definition openmp-utils.h:249
Definition openmp-utils.h:233
Definition openmp-utils.h:241
Definition openmp-utils.h:38
Definition openmp-utils.h:173
Definition openmp-utils.h:149
Definition openmp-utils.h:159