FLANG
openmp-utils.h
1//===-- flang/Parser/openmp-utils.h ---------------------------------------===//
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// Common OpenMP utilities.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef FORTRAN_PARSER_OPENMP_UTILS_H
14#define FORTRAN_PARSER_OPENMP_UTILS_H
15
16#include "flang/Common/indirection.h"
17#include "flang/Parser/parse-tree.h"
18#include "llvm/Frontend/OpenMP/OMP.h"
19
20#include <cassert>
21#include <tuple>
22#include <type_traits>
23#include <utility>
24#include <variant>
25
26namespace Fortran::parser::omp {
27
28namespace detail {
29using D = llvm::omp::Directive;
30
31template <typename Construct> //
33 static constexpr llvm::omp::Directive id{D::OMPD_unknown};
34};
35
36#define MAKE_CONSTR_ID(Construct, Id) \
37 template <> struct ConstructId<Construct> { \
38 static constexpr llvm::omp::Directive id{Id}; \
39 }
40
41MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
42MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
43
44#undef MAKE_CONSTR_ID
45
47 static OmpDirectiveName MakeName(CharBlock source = {},
48 llvm::omp::Directive id = llvm::omp::Directive::OMPD_unknown) {
50 name.source = source;
51 name.v = id;
52 return name;
53 }
54
55 static OmpDirectiveName GetOmpDirectiveName(const OmpDirectiveName &x) {
56 return x;
57 }
58
59 static OmpDirectiveName GetOmpDirectiveName(const OmpBeginLoopDirective &x) {
60 return x.DirName();
61 }
62
63 static OmpDirectiveName GetOmpDirectiveName(const OpenMPSectionConstruct &x) {
64 if (auto &spec{std::get<std::optional<OmpDirectiveSpecification>>(x.t)}) {
65 return spec->DirName();
66 } else {
67 return MakeName({}, llvm::omp::Directive::OMPD_section);
68 }
69 }
70
71 static OmpDirectiveName GetOmpDirectiveName(
73 return x.DirName();
74 }
75
76 template <typename T>
77 static OmpDirectiveName GetOmpDirectiveName(const T &x) {
78 if constexpr (WrapperTrait<T>) {
79 if constexpr (std::is_same_v<T, OpenMPCancelConstruct> ||
80 std::is_same_v<T, OpenMPCancellationPointConstruct> ||
81 std::is_same_v<T, OpenMPDepobjConstruct> ||
82 std::is_same_v<T, OpenMPFlushConstruct> ||
83 std::is_same_v<T, OpenMPInteropConstruct> ||
84 std::is_same_v<T, OpenMPSimpleStandaloneConstruct> ||
85 std::is_same_v<T, OpenMPGroupprivate>) {
86 return x.v.DirName();
87 } else {
88 return GetOmpDirectiveName(x.v);
89 }
90 } else if constexpr (TupleTrait<T>) {
91 if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
92 return std::get<OmpBeginDirective>(x.t).DirName();
93 } else if constexpr (std::is_same_v<T, OpenMPDeclarativeAllocate> ||
94 std::is_same_v<T, OpenMPExecutableAllocate>) {
95 return MakeName(std::get<Verbatim>(x.t).source, ConstructId<T>::id);
96 } else {
97 return GetFromTuple(
98 x.t, std::make_index_sequence<std::tuple_size_v<decltype(x.t)>>{});
99 }
100 } else if constexpr (UnionTrait<T>) {
101 return common::visit(
102 [](auto &&s) { return GetOmpDirectiveName(s); }, x.u);
103 } else {
104 return MakeName();
105 }
106 }
107
108 template <typename... Ts, size_t... Is>
109 static OmpDirectiveName GetFromTuple(
110 const std::tuple<Ts...> &t, std::index_sequence<Is...>) {
111 OmpDirectiveName name = MakeName();
112 auto accumulate = [&](const OmpDirectiveName &n) {
113 if (name.v == llvm::omp::Directive::OMPD_unknown) {
114 name = n;
115 } else {
116 assert(
117 n.v == llvm::omp::Directive::OMPD_unknown && "Conflicting names");
118 }
119 };
120 (accumulate(GetOmpDirectiveName(std::get<Is>(t))), ...);
121 return name;
122 }
123
124 template <typename T>
125 static OmpDirectiveName GetOmpDirectiveName(const common::Indirection<T> &x) {
126 return GetOmpDirectiveName(x.value());
127 }
128};
129} // namespace detail
130
131template <typename T> OmpDirectiveName GetOmpDirectiveName(const T &x) {
132 return detail::DirectiveNameScope::GetOmpDirectiveName(x);
133}
134
135const OmpObjectList *GetOmpObjectList(const OmpClause &clause);
136const BlockConstruct *GetFortranBlockConstruct(
137 const ExecutionPartConstruct &epc);
138
139} // namespace Fortran::parser::omp
140
141#endif // FORTRAN_PARSER_OPENMP_UTILS_H
Definition indirection.h:31
Definition char-block.h:28
Definition parse-tree.h:2196
Definition parse-tree.h:547
Definition parse-tree.h:5167
Definition parse-tree.h:4907
Definition parse-tree.h:4791
Definition parse-tree.h:3487
Definition parse-tree.h:5015
Definition parse-tree.h:5041
Definition parse-tree.h:4921
Definition openmp-utils.h:32