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();
88template <
typename ClauseType,
typename HelperType>
92 using TypeTy =
typename ClauseTy::TypeTy;
93 using IdTy =
typename ClauseTy::IdTy;
94 using ExprTy =
typename ClauseTy::ExprTy;
98 using ClauseSet = std::unordered_set<const ClauseTy *>;
101 llvm::omp::Directive dir,
103 : version(ver), construct(dir), helper(helper) {
107 bool success = split();
115 for (
auto &leaf : leafs) {
116 output.push_back({leaf.id, {}});
117 auto &out =
output.back();
118 for (
const ClauseTy *c : leaf.clauses)
119 out.clauses.push_back(*c);
130 errors.emplace_back(node, ec);
134 struct LeafReprInternal {
135 llvm::omp::Directive
id = llvm::omp::Directive::OMPD_unknown;
139 LeafReprInternal *findDirective(llvm::omp::Directive dirId) {
141 leafs, [&](
const LeafReprInternal &leaf) {
return leaf.id == dirId; });
142 return found != leafs.end() ? &*found :
nullptr;
146 if (
auto found = syms.find(
object.id()); found != syms.end())
147 return &found->second;
151 template <
typename S>
152 ClauseTy *makeClause(llvm::omp::Clause clauseId, S &&specific) {
153 implicit.push_back(
typename ClauseTy::BaseT{clauseId, std::move(specific)});
154 return &implicit.back();
162 void addClauseSymsToMap(
const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
165 template <
typename U>
166 void addClauseSymsToMap(
const std::optional<U> &item,
const ClauseTy *);
167 template <
typename U>
169 template <
typename...
U,
size_t... Is>
170 void addClauseSymsToMap(
const std::tuple<U...> &item,
const ClauseTy *,
171 std::index_sequence<Is...> = {});
172 template <
typename U>
173 std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
174 addClauseSymsToMap(U &&item,
const ClauseTy *);
176 template <
typename U>
177 std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
178 addClauseSymsToMap(U &&item,
const ClauseTy *);
180 template <
typename U>
181 std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
182 addClauseSymsToMap(U &&item,
const ClauseTy *);
184 template <
typename U>
185 std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
186 addClauseSymsToMap(U &&item,
const ClauseTy *);
188 template <
typename U>
189 std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
190 addClauseSymsToMap(U &&item,
const ClauseTy *);
192 template <
typename U>
193 std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
194 addClauseSymsToMap(U &&item,
const ClauseTy *);
199 bool applyToUnique(
const ClauseTy *node);
203 template <
typename Iterator>
208 bool applyToInnermost(
const ClauseTy *node);
212 bool applyToOutermost(
const ClauseTy *node);
217 template <
typename Predicate>
222 bool applyToAll(
const ClauseTy *node);
224 template <
typename Clause>
225 bool applyClause(Clause &&clause,
const ClauseTy *node);
227 bool applyClause(
const tomp::clause::AllocateT<TypeTy, IdTy, ExprTy> &clause,
229 bool applyClause(
const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &clause,
231 bool applyClause(
const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,
234 applyClause(
const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,
236 bool applyClause(
const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,
239 applyClause(
const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,
241 bool applyClause(
const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,
243 bool applyClause(
const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,
246 applyClause(
const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,
248 bool applyClause(
const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &clause,
250 bool applyClause(
const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,
252 bool applyClause(
const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,
254 bool applyClause(
const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,
256 bool applyClause(
const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,
259 applyClause(
const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
263 llvm::omp::Directive construct;
267 std::list<ClauseTy> implicit;
269 std::unordered_map<IdTy, ClauseSet> syms;
270 std::unordered_set<IdTy> mapBases;
274template <
typename ClauseType,
typename HelperType>
279template <
typename C,
typename H>
280void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ObjectTy &
object,
281 const ClauseTy *node) {
282 syms[
object.id()].insert(node);
285template <
typename C,
typename H>
286void ConstructDecompositionT<C, H>::addClauseSymsToMap(
288 for (
auto &
object : objects)
289 syms[
object.id()].insert(node);
292template <
typename C,
typename H>
293void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const TypeTy &item,
294 const ClauseTy *node) {
298template <
typename C,
typename H>
299void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ExprTy &item,
300 const ClauseTy *node) {
304template <
typename C,
typename H>
305void ConstructDecompositionT<C, H>::addClauseSymsToMap(
306 const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
307 const ClauseTy *node) {
308 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(item.
t);
309 addClauseSymsToMap(objects, node);
310 for (
auto &
object : objects) {
311 if (
auto base = helper.getBaseObject(
object))
312 mapBases.insert(base->id());
316template <
typename C,
typename H>
318void ConstructDecompositionT<C, H>::addClauseSymsToMap(
319 const std::optional<U> &item,
const ClauseTy *node) {
321 addClauseSymsToMap(*item, node);
324template <
typename C,
typename H>
326void ConstructDecompositionT<C, H>::addClauseSymsToMap(
329 addClauseSymsToMap(s, node);
332template <
typename C,
typename H>
333template <
typename...
U,
size_t... Is>
334void ConstructDecompositionT<C, H>::addClauseSymsToMap(
335 const std::tuple<U...> &item,
const ClauseTy *node,
336 std::index_sequence<Is...>) {
338 (addClauseSymsToMap(std::get<Is>(item), node), ...);
341template <
typename C,
typename H>
343std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
344ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
345 const ClauseTy *node) {
349template <
typename C,
typename H>
351std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
352ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
353 const ClauseTy *node) {
357template <
typename C,
typename H>
359std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
360ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
361 const ClauseTy *node) {
365template <
typename C,
typename H>
367std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
368ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
369 const ClauseTy *node) {
370 addClauseSymsToMap(item.v, node);
373template <
typename C,
typename H>
375std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
376ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
377 const ClauseTy *node) {
378 constexpr size_t tuple_size =
379 std::tuple_size_v<llvm::remove_cvref_t<
decltype(item.t)>>;
380 addClauseSymsToMap(item.t, node, std::make_index_sequence<tuple_size>{});
383template <
typename C,
typename H>
385std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
386ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
387 const ClauseTy *node) {
388 std::visit([&](
auto &&s) { addClauseSymsToMap(s, node); }, item.u);
394template <
typename C,
typename H>
395bool ConstructDecompositionT<C, H>::applyToUnique(
const ClauseTy *node) {
397 return llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version);
400 if (unique != leafs.end()) {
401 unique->clauses.push_back(node);
409template <
typename C,
typename H>
410template <
typename Iterator>
411bool ConstructDecompositionT<C, H>::applyToFirst(
416 for (
auto &leaf : range) {
417 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
419 leaf.clauses.push_back(node);
427template <
typename C,
typename H>
428bool ConstructDecompositionT<C, H>::applyToInnermost(
const ClauseTy *node) {
434template <
typename C,
typename H>
435bool ConstructDecompositionT<C, H>::applyToOutermost(
const ClauseTy *node) {
439template <
typename C,
typename H>
440template <
typename Predicate>
441bool ConstructDecompositionT<C, H>::applyIf(
const ClauseTy *node,
443 bool applied =
false;
444 for (
auto &leaf : leafs) {
445 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
449 leaf.clauses.push_back(node);
456template <
typename C,
typename H>
457bool ConstructDecompositionT<C, H>::applyToAll(
const ClauseTy *node) {
458 return applyIf(node, [](
auto) {
return true; });
461template <
typename C,
typename H>
462template <
typename Specific>
463bool ConstructDecompositionT<C, H>::applyClause(Specific &&specific,
472 if (!applyToUnique(node))
488template <
typename C,
typename H>
489bool ConstructDecompositionT<C, H>::applyClause(
491 const ClauseTy *node) {
496 bool applied = applyIf(node, [&](
const auto &leaf) {
497 return llvm::any_of(leaf.clauses, [&](
const ClauseTy *n) {
498 return llvm::omp::isPrivatizingClause(n->id);
514template <
typename C,
typename H>
515bool ConstructDecompositionT<C, H>::applyClause(
516 const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &
clause,
517 const ClauseTy *node) {
518 if (!applyToInnermost(node))
530template <
typename C,
typename H>
531bool ConstructDecompositionT<C, H>::applyClause(
532 const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &
clause,
533 const ClauseTy *node) {
535 if (!applyToAll(node))
570template <
typename C,
typename H>
571bool ConstructDecompositionT<C, H>::applyClause(
572 const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &
clause,
573 const ClauseTy *node) {
574 bool applied =
false;
577 auto dirDistribute = findDirective(llvm::omp::OMPD_distribute);
578 auto dirTeams = findDirective(llvm::omp::OMPD_teams);
579 if (dirDistribute !=
nullptr) {
580 dirDistribute->clauses.push_back(node);
583 if (dirTeams !=
nullptr) {
584 auto *shared = makeClause(
585 llvm::omp::Clause::OMPC_shared,
586 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
587 dirTeams->clauses.push_back(shared);
589 }
else if (dirTeams !=
nullptr) {
590 dirTeams->clauses.push_back(node);
595 auto findWorksharing = [&]() {
597 for (
auto &leaf : leafs) {
598 auto found =
llvm::find(worksharing, leaf.id);
599 if (found != std::end(worksharing))
602 return static_cast<typename decltype(leafs)::value_type *
>(
nullptr);
605 auto dirWorksharing = findWorksharing();
606 if (dirWorksharing !=
nullptr) {
607 dirWorksharing->clauses.push_back(node);
612 auto dirTaskloop = findDirective(llvm::omp::OMPD_taskloop);
613 if (dirTaskloop !=
nullptr) {
614 dirTaskloop->clauses.push_back(node);
619 auto dirParallel = findDirective(llvm::omp::OMPD_parallel);
620 if (dirParallel !=
nullptr) {
621 if (dirTaskloop ==
nullptr && dirWorksharing ==
nullptr) {
622 dirParallel->clauses.push_back(node);
626 auto *shared = makeClause(
627 llvm::omp::Clause::OMPC_shared,
628 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
629 dirParallel->clauses.push_back(shared);
634 auto inLastprivate = [&](
const ObjectTy &object) {
635 if (ClauseSet *set = findClausesWith(
object)) {
637 return c->id == llvm::omp::Clause::OMPC_lastprivate;
643 auto dirTarget = findDirective(llvm::omp::OMPD_target);
644 if (dirTarget !=
nullptr) {
647 clause.v, std::back_inserter(objects), [&](
const ObjectTy &
object) {
648 return !inLastprivate(object) && !mapBases.count(object.id());
650 if (!objects.
empty()) {
651 auto *firstp = makeClause(
652 llvm::omp::Clause::OMPC_firstprivate,
653 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{objects});
654 dirTarget->clauses.push_back(firstp);
660 if (
auto dirTask = findDirective(llvm::omp::OMPD_task)) {
661 dirTask->clauses.push_back(node);
681template <
typename C,
typename H>
682bool ConstructDecompositionT<C, H>::applyClause(
683 const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &
clause,
684 const ClauseTy *node) {
685 using DirectiveNameModifier =
688 auto &modifier = std::get<std::optional<DirectiveNameModifier>>(
clause.t);
691 llvm::omp::Directive dirId = *modifier;
693 makeClause(llvm::omp::Clause::OMPC_if,
694 tomp::clause::IfT<TypeTy, IdTy, ExprTy>{
696 std::get<IfExpression>(
clause.t)}});
698 if (
auto *hasDir = findDirective(dirId)) {
699 hasDir->clauses.push_back(unmodified);
705 if (!applyToAll(node))
729template <
typename C,
typename H>
730bool ConstructDecompositionT<C, H>::applyClause(
731 const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &
clause,
732 const ClauseTy *node) {
734 if (!applyToAll(node))
737 auto inFirstprivate = [&](
const ObjectTy &object) {
738 if (ClauseSet *set = findClausesWith(
object)) {
740 return c->id == llvm::omp::Clause::OMPC_firstprivate;
746 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
751 objects, std::back_inserter(sharedObjects),
752 [&](
const ObjectTy &
object) {
return !inFirstprivate(
object); });
754 if (!sharedObjects.empty()) {
756 if (
auto dirParallel = findDirective(llvm::omp::OMPD_parallel)) {
757 auto *shared = makeClause(
758 llvm::omp::Clause::OMPC_shared,
759 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
760 dirParallel->clauses.push_back(shared);
764 if (
auto dirTeams = findDirective(llvm::omp::OMPD_teams)) {
765 auto *shared = makeClause(
766 llvm::omp::Clause::OMPC_shared,
767 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
768 dirTeams->clauses.push_back(shared);
773 if (
auto dirTarget = findDirective(llvm::omp::OMPD_target)) {
776 objects, std::back_inserter(tofrom),
777 [&](
const ObjectTy &
object) {
return !mapBases.count(
object.
id()); });
779 if (!tofrom.
empty()) {
781 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
783 makeClause(llvm::omp::Clause::OMPC_map,
784 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
789 std::nullopt, std::nullopt,
790 std::move(tofrom)}});
791 dirTarget->clauses.push_back(map);
815template <
typename C,
typename H>
816bool ConstructDecompositionT<C, H>::applyClause(
817 const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &
clause,
818 const ClauseTy *node) {
820 if (!applyToInnermost(node))
824 auto dirSimd = findDirective(llvm::omp::Directive::OMPD_simd);
825 std::optional<ObjectTy> iterVar = helper.getLoopIterVar();
826 const auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
832 for (
const ObjectTy &
object : objects) {
833 last.push_back(
object);
834 if (!dirSimd || !iterVar ||
object.
id() != iterVar->id())
835 first.push_back(
object);
838 if (!first.empty()) {
839 auto *firstp = makeClause(
840 llvm::omp::Clause::OMPC_firstprivate,
841 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{first});
842 nodes.push_back(firstp);
846 makeClause(llvm::omp::Clause::OMPC_lastprivate,
847 tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>{
848 {std::nullopt,
last}});
849 nodes.push_back(lastp);
862template <
typename C,
typename H>
863bool ConstructDecompositionT<C, H>::applyClause(
864 const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &
clause,
865 const ClauseTy *node) {
866 if (!applyToOutermost(node))
872template <
typename C,
typename H>
873bool ConstructDecompositionT<C, H>::applyClause(
874 const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &
clause,
875 const ClauseTy *node) {
876 if (!applyToAll(node))
882template <
typename C,
typename H>
883bool ConstructDecompositionT<C, H>::applyClause(
884 const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &
clause,
885 const ClauseTy *node) {
886 if (!applyToOutermost(node))
898template <
typename C,
typename H>
899bool ConstructDecompositionT<C, H>::applyClause(
900 const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &
clause,
901 const ClauseTy *node) {
903 if (!applyToAll(node))
916template <
typename C,
typename H>
917bool ConstructDecompositionT<C, H>::applyClause(
918 const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &
clause,
919 const ClauseTy *node) {
920 if (!applyToInnermost(node))
951template <
typename C,
typename H>
952bool ConstructDecompositionT<C, H>::applyClause(
953 const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &
clause,
954 const ClauseTy *node) {
955 using ReductionTy = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
958 bool applyToParallel =
true, applyToTeams =
true;
960 auto dirParallel = findDirective(llvm::omp::Directive::OMPD_parallel);
964 llvm::omp::Directive::OMPD_loop,
965 llvm::omp::Directive::OMPD_sections,
966 llvm::omp::Directive::OMPD_taskloop,
968 auto present = [&](llvm::omp::Directive id) {
969 return findDirective(
id) !=
nullptr;
973 applyToParallel =
false;
976 auto dirTeams = findDirective(llvm::omp::Directive::OMPD_teams);
979 if (findDirective(llvm::omp::Directive::OMPD_loop))
980 applyToTeams =
false;
983 using ReductionModifier =
typename ReductionTy::ReductionModifier;
984 using ReductionIdentifiers =
typename ReductionTy::ReductionIdentifiers;
986 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
987 auto &modifier = std::get<std::optional<ReductionModifier>>(
clause.t);
992 bool applied =
false;
995 auto isValidModifier = [](llvm::omp::Directive dir, ReductionModifier
mod,
996 bool alreadyApplied) {
998 case ReductionModifier::Inscan:
1001 return dir == llvm::omp::Directive::OMPD_simd ||
1003 case ReductionModifier::Task:
1008 return dir == llvm::omp::Directive::OMPD_parallel ||
1010 case ReductionModifier::Default:
1016 auto *unmodified = makeClause(
1017 llvm::omp::Clause::OMPC_reduction,
1020 std::get<ReductionIdentifiers>(
clause.t),
1023 ReductionModifier effective = modifier.value_or(ReductionModifier::Default);
1024 bool modifierApplied =
false;
1025 bool allowingLeaf =
false;
1029 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
1033 allowingLeaf =
true;
1034 if (!applyToParallel && &leaf == dirParallel)
1036 if (!applyToTeams && &leaf == dirTeams)
1039 if (isValidModifier(leaf.id, effective, modifierApplied)) {
1041 leaf.clauses.push_back(node);
1042 modifierApplied =
true;
1045 leaf.clauses.push_back(unmodified);
1048 applied = modifierApplied;
1058 [&](
const ObjectTy &
object) {
1059 auto maybeBase = helper.getBaseObject(
object);
1060 return maybeBase ? *maybeBase : object;
1064 if (!sharedObjects.
empty()) {
1065 if (dirParallel && !applyToParallel) {
1066 auto *shared = makeClause(
1067 llvm::omp::Clause::OMPC_shared,
1068 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1069 dirParallel->clauses.push_back(shared);
1071 if (dirTeams && !applyToTeams) {
1072 auto *shared = makeClause(
1073 llvm::omp::Clause::OMPC_shared,
1074 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1075 dirTeams->clauses.push_back(shared);
1080 auto dirTarget = findDirective(llvm::omp::Directive::OMPD_target);
1081 if (dirTarget && leafs.size() > 1) {
1084 [&](
const ObjectTy &
object) {
1085 if (
auto maybeBase = helper.getBaseObject(
object))
1086 return !mapBases.count(maybeBase->id());
1087 return !mapBases.count(
object.
id());
1089 if (!tofrom.
empty()) {
1091 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
1092 auto *map = makeClause(
1093 llvm::omp::Clause::OMPC_map,
1094 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
1095 {MapType::Tofrom, std::nullopt,
1096 std::nullopt, std::nullopt,
1097 std::nullopt, std::nullopt,
1098 std::move(tofrom)}});
1100 dirTarget->clauses.push_back(map);
1114template <
typename C,
typename H>
1115bool ConstructDecompositionT<C, H>::applyClause(
1116 const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &
clause,
1117 const ClauseTy *node) {
1119 if (!applyToAll(node))
1131template <
typename C,
typename H>
1132bool ConstructDecompositionT<C, H>::applyClause(
1133 const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &
clause,
1134 const ClauseTy *node) {
1136 if (!applyToAll(node))
1143template <
typename C,
typename H>
bool ConstructDecompositionT<C, H>::split() {
1146 auto isImplicit = [
this](
const ClauseTy *node) {
1150 for (llvm::omp::Directive leaf :
1152 leafs.push_back(LeafReprInternal{leaf, {}});
1154 for (
const ClauseTy *node :
nodes)
1155 addClauseSymsToMap(*node, node);
1162 for (
const ClauseTy *node :
nodes) {
1163 if (node->id == llvm::omp::Clause::OMPC_linear)
1166 for (
const auto *node : linears) {
1168 applyClause(std::get<tomp::clause::LinearT<TypeTy, IdTy, ExprTy>>(
1175 auto skip = [](
const ClauseTy *node) {
1177 case llvm::omp::Clause::OMPC_allocate:
1178 case llvm::omp::Clause::OMPC_linear:
1186 for (
const ClauseTy *node :
nodes) {
1190 std::visit([&](
auto &&s) {
return applyClause(s, node); }, node->u);
1191 if (!isImplicit(node))
1196 for (
const ClauseTy *node :
nodes) {
1197 if (node->id != llvm::omp::Clause::OMPC_allocate)
1201 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 is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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
llvm::SmallVector< std::pair< const ClauseType *, ErrorCode > > errors
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