18#ifndef LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H
19#define LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H
33#include <unordered_map>
34#include <unordered_set>
39 static llvm::omp::Directive worksharing[] = {
40 llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_for,
41 llvm::omp::Directive::OMPD_scope, llvm::omp::Directive::OMPD_sections,
42 llvm::omp::Directive::OMPD_single, llvm::omp::Directive::OMPD_workshare,
48 static llvm::omp::Directive worksharingLoop[] = {
49 llvm::omp::Directive::OMPD_do,
50 llvm::omp::Directive::OMPD_for,
52 return worksharingLoop;
56template <
typename Container,
typename Predicate>
57typename std::remove_reference_t<Container>::iterator
60 if (first == container.end())
62 auto second = std::find_if(std::next(first), container.end(), pred);
63 if (second == container.end())
65 return container.end();
82template <
typename ClauseType,
typename HelperType>
86 using TypeTy =
typename ClauseTy::TypeTy;
87 using IdTy =
typename ClauseTy::IdTy;
88 using ExprTy =
typename ClauseTy::ExprTy;
92 using ClauseSet = std::unordered_set<const ClauseTy *>;
95 llvm::omp::Directive dir,
97 : version(ver), construct(dir), helper(helper) {
101 bool success = split();
109 for (
auto &leaf : leafs) {
110 output.push_back({leaf.id, {}});
111 auto &out =
output.back();
112 for (
const ClauseTy *c : leaf.clauses)
113 out.clauses.push_back(*c);
122 struct LeafReprInternal {
123 llvm::omp::Directive
id = llvm::omp::Directive::OMPD_unknown;
127 LeafReprInternal *findDirective(llvm::omp::Directive dirId) {
129 leafs, [&](
const LeafReprInternal &leaf) {
return leaf.id == dirId; });
130 return found != leafs.end() ? &*found :
nullptr;
134 if (
auto found = syms.find(
object.id()); found != syms.end())
135 return &found->second;
139 template <
typename S>
140 ClauseTy *makeClause(llvm::omp::Clause clauseId, S &&specific) {
141 implicit.push_back(
typename ClauseTy::BaseT{clauseId, std::move(specific)});
142 return &implicit.back();
150 void addClauseSymsToMap(
const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
153 template <
typename U>
154 void addClauseSymsToMap(
const std::optional<U> &item,
const ClauseTy *);
155 template <
typename U>
157 template <
typename...
U,
size_t... Is>
158 void addClauseSymsToMap(
const std::tuple<U...> &item,
const ClauseTy *,
159 std::index_sequence<Is...> = {});
160 template <
typename U>
161 std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
162 addClauseSymsToMap(U &&item,
const ClauseTy *);
164 template <
typename U>
165 std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
166 addClauseSymsToMap(U &&item,
const ClauseTy *);
168 template <
typename U>
169 std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
170 addClauseSymsToMap(U &&item,
const ClauseTy *);
172 template <
typename U>
173 std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
174 addClauseSymsToMap(U &&item,
const ClauseTy *);
176 template <
typename U>
177 std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
178 addClauseSymsToMap(U &&item,
const ClauseTy *);
180 template <
typename U>
181 std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
182 addClauseSymsToMap(U &&item,
const ClauseTy *);
187 bool applyToUnique(
const ClauseTy *node);
191 template <
typename Iterator>
196 bool applyToInnermost(
const ClauseTy *node);
200 bool applyToOutermost(
const ClauseTy *node);
202 template <
typename Predicate>
205 bool applyToAll(
const ClauseTy *node);
207 template <
typename Clause>
208 bool applyClause(Clause &&clause,
const ClauseTy *node);
210 bool applyClause(
const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &clause,
212 bool applyClause(
const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,
215 applyClause(
const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,
218 applyClause(
const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,
220 bool applyClause(
const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,
222 bool applyClause(
const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,
225 applyClause(
const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
227 bool applyClause(
const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,
229 bool applyClause(
const tomp::clause::AllocateT<TypeTy, IdTy, ExprTy> &clause,
231 bool applyClause(
const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,
233 bool applyClause(
const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,
235 bool applyClause(
const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,
237 bool applyClause(
const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,
240 applyClause(
const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,
242 bool applyClause(
const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &clause,
246 llvm::omp::Directive construct;
250 std::list<ClauseTy> implicit;
252 std::unordered_map<IdTy, ClauseSet> syms;
253 std::unordered_set<IdTy> mapBases;
257template <
typename ClauseType,
typename HelperType>
262template <
typename C,
typename H>
263void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ObjectTy &
object,
264 const ClauseTy *node) {
265 syms[
object.id()].insert(node);
268template <
typename C,
typename H>
269void ConstructDecompositionT<C, H>::addClauseSymsToMap(
271 for (
auto &
object : objects)
272 syms[
object.id()].insert(node);
275template <
typename C,
typename H>
276void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const TypeTy &item,
277 const ClauseTy *node) {
281template <
typename C,
typename H>
282void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ExprTy &item,
283 const ClauseTy *node) {
287template <
typename C,
typename H>
288void ConstructDecompositionT<C, H>::addClauseSymsToMap(
289 const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
290 const ClauseTy *node) {
291 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(item.
t);
292 addClauseSymsToMap(objects, node);
293 for (
auto &
object : objects) {
294 if (
auto base = helper.getBaseObject(
object))
295 mapBases.insert(base->id());
299template <
typename C,
typename H>
301void ConstructDecompositionT<C, H>::addClauseSymsToMap(
302 const std::optional<U> &item,
const ClauseTy *node) {
304 addClauseSymsToMap(*item, node);
307template <
typename C,
typename H>
309void ConstructDecompositionT<C, H>::addClauseSymsToMap(
312 addClauseSymsToMap(s, node);
315template <
typename C,
typename H>
316template <
typename...
U,
size_t... Is>
317void ConstructDecompositionT<C, H>::addClauseSymsToMap(
318 const std::tuple<U...> &item,
const ClauseTy *node,
319 std::index_sequence<Is...>) {
321 (addClauseSymsToMap(std::get<Is>(item), node), ...);
324template <
typename C,
typename H>
326std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
327ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
328 const ClauseTy *node) {
332template <
typename C,
typename H>
334std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
335ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
336 const ClauseTy *node) {
340template <
typename C,
typename H>
342std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
343ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
344 const ClauseTy *node) {
348template <
typename C,
typename H>
350std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
351ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
352 const ClauseTy *node) {
353 addClauseSymsToMap(item.v, node);
356template <
typename C,
typename H>
358std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
359ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
360 const ClauseTy *node) {
361 constexpr size_t tuple_size =
362 std::tuple_size_v<llvm::remove_cvref_t<
decltype(item.t)>>;
363 addClauseSymsToMap(item.t, node, std::make_index_sequence<tuple_size>{});
366template <
typename C,
typename H>
368std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
369ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
370 const ClauseTy *node) {
371 std::visit([&](
auto &&s) { addClauseSymsToMap(s, node); }, item.u);
377template <
typename C,
typename H>
378bool ConstructDecompositionT<C, H>::applyToUnique(
const ClauseTy *node) {
380 return llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version);
383 if (unique != leafs.end()) {
384 unique->clauses.push_back(node);
392template <
typename C,
typename H>
393template <
typename Iterator>
394bool ConstructDecompositionT<C, H>::applyToFirst(
399 for (
auto &leaf : range) {
400 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
402 leaf.clauses.push_back(node);
410template <
typename C,
typename H>
411bool ConstructDecompositionT<C, H>::applyToInnermost(
const ClauseTy *node) {
417template <
typename C,
typename H>
418bool ConstructDecompositionT<C, H>::applyToOutermost(
const ClauseTy *node) {
422template <
typename C,
typename H>
423template <
typename Predicate>
424bool ConstructDecompositionT<C, H>::applyIf(
const ClauseTy *node,
426 bool applied =
false;
427 for (
auto &leaf : leafs) {
428 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
432 leaf.clauses.push_back(node);
439template <
typename C,
typename H>
440bool ConstructDecompositionT<C, H>::applyToAll(
const ClauseTy *node) {
441 return applyIf(node, [](
auto) {
return true; });
444template <
typename C,
typename H>
445template <
typename Specific>
446bool ConstructDecompositionT<C, H>::applyClause(Specific &&specific,
455 if (applyToUnique(node))
468template <
typename C,
typename H>
469bool ConstructDecompositionT<C, H>::applyClause(
471 const ClauseTy *node) {
474 if (!leafs.empty()) {
475 auto &last = leafs.back();
477 if (llvm::omp::isAllowedClauseForDirective(last.id, node->id, version)) {
478 last.clauses.push_back(node);
494template <
typename C,
typename H>
495bool ConstructDecompositionT<C, H>::applyClause(
496 const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &
clause,
497 const ClauseTy *node) {
498 return applyToInnermost(node);
531template <
typename C,
typename H>
532bool ConstructDecompositionT<C, H>::applyClause(
533 const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &
clause,
534 const ClauseTy *node) {
535 bool applied =
false;
538 auto dirDistribute = findDirective(llvm::omp::OMPD_distribute);
539 auto dirTeams = findDirective(llvm::omp::OMPD_teams);
540 if (dirDistribute !=
nullptr) {
541 dirDistribute->clauses.push_back(node);
544 if (dirTeams !=
nullptr) {
545 auto *shared = makeClause(
546 llvm::omp::Clause::OMPC_shared,
547 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
548 dirTeams->clauses.push_back(shared);
550 }
else if (dirTeams !=
nullptr) {
551 dirTeams->clauses.push_back(node);
556 auto findWorksharing = [&]() {
558 for (
auto &leaf : leafs) {
559 auto found =
llvm::find(worksharing, leaf.id);
560 if (found != std::end(worksharing))
563 return static_cast<typename decltype(leafs)::value_type *
>(
nullptr);
566 auto dirWorksharing = findWorksharing();
567 if (dirWorksharing !=
nullptr) {
568 dirWorksharing->clauses.push_back(node);
573 auto dirTaskloop = findDirective(llvm::omp::OMPD_taskloop);
574 if (dirTaskloop !=
nullptr) {
575 dirTaskloop->clauses.push_back(node);
580 auto dirParallel = findDirective(llvm::omp::OMPD_parallel);
581 if (dirParallel !=
nullptr) {
582 if (dirTaskloop ==
nullptr && dirWorksharing ==
nullptr) {
583 dirParallel->clauses.push_back(node);
587 auto *shared = makeClause(
588 llvm::omp::Clause::OMPC_shared,
589 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
590 dirParallel->clauses.push_back(shared);
595 auto inLastprivate = [&](
const ObjectTy &object) {
596 if (ClauseSet *set = findClausesWith(
object)) {
598 return c->id == llvm::omp::Clause::OMPC_lastprivate;
604 auto dirTarget = findDirective(llvm::omp::OMPD_target);
605 if (dirTarget !=
nullptr) {
608 clause.v, std::back_inserter(objects), [&](
const ObjectTy &
object) {
609 return !inLastprivate(object) && !mapBases.count(object.id());
611 if (!objects.
empty()) {
612 auto *firstp = makeClause(
613 llvm::omp::Clause::OMPC_firstprivate,
614 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{objects});
615 dirTarget->clauses.push_back(firstp);
621 if (
auto dirTask = findDirective(llvm::omp::OMPD_task)) {
622 dirTask->clauses.push_back(node);
648template <
typename C,
typename H>
649bool ConstructDecompositionT<C, H>::applyClause(
650 const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &
clause,
651 const ClauseTy *node) {
652 bool applied =
false;
655 applied = applyToAll(node);
659 auto inFirstprivate = [&](
const ObjectTy &object) {
660 if (ClauseSet *set = findClausesWith(
object)) {
662 return c->id == llvm::omp::Clause::OMPC_firstprivate;
668 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
673 objects, std::back_inserter(sharedObjects),
674 [&](
const ObjectTy &
object) {
return !inFirstprivate(
object); });
676 if (!sharedObjects.empty()) {
678 if (
auto dirParallel = findDirective(llvm::omp::OMPD_parallel)) {
679 auto *shared = makeClause(
680 llvm::omp::Clause::OMPC_shared,
681 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
682 dirParallel->clauses.push_back(shared);
687 if (
auto dirTeams = findDirective(llvm::omp::OMPD_teams)) {
688 auto *shared = makeClause(
689 llvm::omp::Clause::OMPC_shared,
690 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
691 dirTeams->clauses.push_back(shared);
697 if (
auto dirTarget = findDirective(llvm::omp::OMPD_target)) {
700 objects, std::back_inserter(tofrom),
701 [&](
const ObjectTy &
object) {
return !mapBases.count(
object.
id()); });
703 if (!tofrom.
empty()) {
705 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
707 makeClause(llvm::omp::Clause::OMPC_map,
708 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
713 std::nullopt, std::nullopt,
714 std::move(tofrom)}});
715 dirTarget->clauses.push_back(map);
730template <
typename C,
typename H>
731bool ConstructDecompositionT<C, H>::applyClause(
732 const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &
clause,
733 const ClauseTy *node) {
735 return applyToAll(node);
745template <
typename C,
typename H>
746bool ConstructDecompositionT<C, H>::applyClause(
747 const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &
clause,
748 const ClauseTy *node) {
750 return applyToAll(node);
760template <
typename C,
typename H>
761bool ConstructDecompositionT<C, H>::applyClause(
762 const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &
clause,
763 const ClauseTy *node) {
765 return applyToAll(node);
775template <
typename C,
typename H>
776bool ConstructDecompositionT<C, H>::applyClause(
777 const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &
clause,
778 const ClauseTy *node) {
780 return applyToAll(node);
792template <
typename C,
typename H>
793bool ConstructDecompositionT<C, H>::applyClause(
794 const tomp::clause::AllocateT<TypeTy, IdTy, ExprTy> &
clause,
795 const ClauseTy *node) {
800 bool applied = applyIf(node, [&](
const auto &leaf) {
801 return llvm::any_of(leaf.clauses, [&](
const ClauseTy *n) {
802 return llvm::omp::isPrivatizingClause(n->id);
835template <
typename C,
typename H>
836bool ConstructDecompositionT<C, H>::applyClause(
837 const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &
clause,
838 const ClauseTy *node) {
839 using ReductionTy = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
842 bool applyToParallel =
true, applyToTeams =
true;
844 auto dirParallel = findDirective(llvm::omp::Directive::OMPD_parallel);
848 llvm::omp::Directive::OMPD_loop,
849 llvm::omp::Directive::OMPD_sections,
850 llvm::omp::Directive::OMPD_taskloop,
852 auto present = [&](llvm::omp::Directive id) {
853 return findDirective(
id) !=
nullptr;
857 applyToParallel =
false;
860 auto dirTeams = findDirective(llvm::omp::Directive::OMPD_teams);
863 if (findDirective(llvm::omp::Directive::OMPD_loop))
864 applyToTeams =
false;
867 using ReductionModifier =
typename ReductionTy::ReductionModifier;
868 using ReductionIdentifiers =
typename ReductionTy::ReductionIdentifiers;
870 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
871 auto &modifier = std::get<std::optional<ReductionModifier>>(
clause.t);
876 bool applied =
false;
879 auto isValidModifier = [](llvm::omp::Directive dir, ReductionModifier
mod,
880 bool alreadyApplied) {
882 case ReductionModifier::Inscan:
885 return dir == llvm::omp::Directive::OMPD_simd ||
887 case ReductionModifier::Task:
892 return dir == llvm::omp::Directive::OMPD_parallel ||
894 case ReductionModifier::Default:
900 auto *unmodified = makeClause(
901 llvm::omp::Clause::OMPC_reduction,
904 std::get<ReductionIdentifiers>(
clause.t),
907 ReductionModifier effective = modifier.value_or(ReductionModifier::Default);
908 bool effectiveApplied =
false;
912 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
914 if (!applyToParallel && &leaf == dirParallel)
916 if (!applyToTeams && &leaf == dirTeams)
919 if (isValidModifier(leaf.id, effective, effectiveApplied)) {
921 leaf.clauses.push_back(node);
922 effectiveApplied =
true;
925 leaf.clauses.push_back(unmodified);
928 applied = effectiveApplied;
936 [&](
const ObjectTy &
object) {
937 auto maybeBase = helper.getBaseObject(
object);
938 return maybeBase ? *maybeBase : object;
942 if (!sharedObjects.
empty()) {
943 if (dirParallel && !applyToParallel) {
944 auto *shared = makeClause(
945 llvm::omp::Clause::OMPC_shared,
946 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
947 dirParallel->clauses.push_back(shared);
949 if (dirTeams && !applyToTeams) {
950 auto *shared = makeClause(
951 llvm::omp::Clause::OMPC_shared,
952 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
953 dirTeams->clauses.push_back(shared);
958 auto dirTarget = findDirective(llvm::omp::Directive::OMPD_target);
959 if (dirTarget && leafs.size() > 1) {
962 [&](
const ObjectTy &
object) {
963 if (
auto maybeBase = helper.getBaseObject(
object))
964 return !mapBases.count(maybeBase->id());
965 return !mapBases.count(
object.
id());
967 if (!tofrom.
empty()) {
969 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
970 auto *map = makeClause(
971 llvm::omp::Clause::OMPC_map,
972 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
973 {MapType::Tofrom, std::nullopt,
974 std::nullopt, std::nullopt,
975 std::nullopt, std::nullopt,
976 std::move(tofrom)}});
978 dirTarget->clauses.push_back(map);
997template <
typename C,
typename H>
998bool ConstructDecompositionT<C, H>::applyClause(
999 const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &
clause,
1000 const ClauseTy *node) {
1001 using DirectiveNameModifier =
1004 auto &modifier = std::get<std::optional<DirectiveNameModifier>>(
clause.t);
1007 llvm::omp::Directive dirId = *modifier;
1009 makeClause(llvm::omp::Clause::OMPC_if,
1010 tomp::clause::IfT<TypeTy, IdTy, ExprTy>{
1012 std::get<IfExpression>(
clause.t)}});
1014 if (
auto *hasDir = findDirective(dirId)) {
1015 hasDir->clauses.push_back(unmodified);
1021 return applyToAll(node);
1041template <
typename C,
typename H>
1042bool ConstructDecompositionT<C, H>::applyClause(
1043 const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &
clause,
1044 const ClauseTy *node) {
1046 if (!applyToInnermost(node))
1050 auto dirSimd = findDirective(llvm::omp::Directive::OMPD_simd);
1051 std::optional<ObjectTy> iterVar = helper.getLoopIterVar();
1052 const auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
1058 for (
const ObjectTy &
object : objects) {
1059 last.push_back(
object);
1060 if (!dirSimd || !iterVar ||
object.
id() != iterVar->id())
1061 first.push_back(
object);
1064 if (!first.empty()) {
1065 auto *firstp = makeClause(
1066 llvm::omp::Clause::OMPC_firstprivate,
1067 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{first});
1068 nodes.push_back(firstp);
1070 if (!
last.empty()) {
1072 makeClause(llvm::omp::Clause::OMPC_lastprivate,
1073 tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>{
1074 {std::nullopt,
last}});
1075 nodes.push_back(lastp);
1088template <
typename C,
typename H>
1089bool ConstructDecompositionT<C, H>::applyClause(
1090 const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &
clause,
1091 const ClauseTy *node) {
1092 return applyToOutermost(node);
1095template <
typename C,
typename H>
1096bool ConstructDecompositionT<C, H>::applyClause(
1097 const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &
clause,
1098 const ClauseTy *node) {
1099 return applyToOutermost(node);
1102template <
typename C,
typename H>
1103bool ConstructDecompositionT<C, H>::applyClause(
1104 const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &
clause,
1105 const ClauseTy *node) {
1106 return applyToAll(node);
1109template <
typename C,
typename H>
bool ConstructDecompositionT<C, H>::split() {
1112 auto isImplicit = [
this](
const ClauseTy *node) {
1116 for (llvm::omp::Directive leaf :
1118 leafs.push_back(LeafReprInternal{leaf, {}});
1120 for (
const ClauseTy *node :
nodes)
1121 addClauseSymsToMap(*node, node);
1128 for (
const ClauseTy *node :
nodes) {
1129 if (node->id == llvm::omp::Clause::OMPC_linear)
1132 for (
const auto *node : linears) {
1134 applyClause(std::get<tomp::clause::LinearT<TypeTy, IdTy, ExprTy>>(
1141 auto skip = [](
const ClauseTy *node) {
1143 case llvm::omp::Clause::OMPC_allocate:
1144 case llvm::omp::Clause::OMPC_linear:
1152 for (
const ClauseTy *node :
nodes) {
1156 std::visit([&](
auto &&s) {
return applyClause(s, node); }, node->u);
1157 if (!isImplicit(node))
1162 for (
const ClauseTy *node :
nodes) {
1163 if (node->id != llvm::omp::Clause::OMPC_allocate)
1167 std::visit([&](
auto &&s) {
return applyClause(s, node); }, node->u);
Unify divergent function exit nodes
static llvm::ArrayRef< llvm::omp::Directive > getWorksharing()
static llvm::ArrayRef< llvm::omp::Directive > getWorksharingLoop()
static bool shouldApply(Function &F, ProfileSummaryInfo &PSI)
static bool skip(DataExtractor &Data, uint64_t &Offset, bool SkippedRanges)
Skip an InlineInfo object in the specified data at the specified offset.
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void push_back(const T &Elt)
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::remove_reference_t< Container >::iterator find_unique(Container &&container, Predicate &&pred)
LLVM_ABI ArrayRef< Directive > getLeafConstructsOrSelf(Directive D)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
auto unique(Range &&R, Predicate P)
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LogicalResult success(bool IsSuccess=true)
Utility function to generate a LogicalResult.
llvm::SmallVector< T, 0 > ListT
type::ObjectListT< I, E > ObjectListT
ConstructDecompositionT(uint32_t, HelperType &, llvm::omp::Directive, llvm::ArrayRef< ClauseType >) -> ConstructDecompositionT< ClauseType, HelperType >
type::ObjectT< I, E > ObjectT
typename ClauseTy::ExprTy ExprTy
std::unordered_set< const ClauseTy * > ClauseSet
typename ClauseTy::TypeTy TypeTy
typename ClauseTy::IdTy IdTy
tomp::ObjectT< IdTy, ExprTy > ObjectTy
ConstructDecompositionT(uint32_t ver, HelperType &helper, llvm::omp::Directive dir, llvm::ArrayRef< ClauseTy > clauses)
tomp::ListT< DirectiveWithClauses< ClauseType > > output
type::DirectiveName DirectiveNameModifier
std::tuple< OPT(MapType), OPT(MapTypeModifiers), OPT(AttachModifier), OPT(RefModifier), OPT(Mappers), OPT(Iterator), LocatorList > t