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), helper(helper), inputDirective(dir) {
105 inputClauses.push_back(&
clause);
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(input, 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 *input);
203 template <
typename Iterator>
204 bool applyToFirst(
const ClauseTy *input,
209 bool applyToInnermost(
const ClauseTy *input);
213 bool applyToOutermost(
const ClauseTy *input);
218 template <
typename Predicate>
223 bool applyToAll(
const ClauseTy *input);
225 template <
typename Clause>
226 bool applyClause(Clause &&clause,
const ClauseTy *input);
228 bool applyClause(
const tomp::clause::AllocateT<TypeTy, IdTy, ExprTy> &clause,
230 bool applyClause(
const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &clause,
232 bool applyClause(
const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,
235 const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
238 applyClause(
const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,
240 bool applyClause(
const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,
243 applyClause(
const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,
245 bool applyClause(
const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,
247 bool applyClause(
const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,
250 applyClause(
const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,
252 bool applyClause(
const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &clause,
254 bool applyClause(
const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,
256 bool applyClause(
const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,
258 bool applyClause(
const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,
260 bool applyClause(
const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,
263 applyClause(
const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
268 llvm::omp::Directive inputDirective;
272 std::list<ClauseTy> implicit;
274 std::unordered_map<IdTy, ClauseSet> syms;
275 std::unordered_set<IdTy> mapBases;
279template <
typename ClauseType,
typename HelperType>
284template <
typename C,
typename H>
285void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ObjectTy &
object,
286 const ClauseTy *input) {
287 syms[
object.id()].insert(input);
290template <
typename C,
typename H>
291void ConstructDecompositionT<C, H>::addClauseSymsToMap(
293 for (
auto &
object : objects)
294 syms[
object.id()].insert(input);
297template <
typename C,
typename H>
298void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const TypeTy &item,
299 const ClauseTy *input) {
303template <
typename C,
typename H>
304void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ExprTy &item,
305 const ClauseTy *input) {
309template <
typename C,
typename H>
310void ConstructDecompositionT<C, H>::addClauseSymsToMap(
311 const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
312 const ClauseTy *input) {
313 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(item.
t);
314 addClauseSymsToMap(objects, input);
315 for (
auto &
object : objects) {
316 if (
auto base = helper.getBaseObject(
object))
317 mapBases.insert(base->id());
321template <
typename C,
typename H>
323void ConstructDecompositionT<C, H>::addClauseSymsToMap(
324 const std::optional<U> &item,
const ClauseTy *input) {
326 addClauseSymsToMap(*item, input);
329template <
typename C,
typename H>
331void ConstructDecompositionT<C, H>::addClauseSymsToMap(
334 addClauseSymsToMap(s, input);
337template <
typename C,
typename H>
338template <
typename...
U,
size_t... Is>
339void ConstructDecompositionT<C, H>::addClauseSymsToMap(
340 const std::tuple<U...> &item,
const ClauseTy *input,
341 std::index_sequence<Is...>) {
343 (addClauseSymsToMap(std::get<Is>(item), input), ...);
346template <
typename C,
typename H>
348std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
349ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
350 const ClauseTy *input) {
354template <
typename C,
typename H>
356std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
357ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
358 const ClauseTy *input) {
362template <
typename C,
typename H>
364std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
365ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
366 const ClauseTy *input) {
370template <
typename C,
typename H>
372std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
373ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
374 const ClauseTy *input) {
375 addClauseSymsToMap(item.v, input);
378template <
typename C,
typename H>
380std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
381ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
382 const ClauseTy *input) {
383 constexpr size_t tuple_size =
384 std::tuple_size_v<llvm::remove_cvref_t<
decltype(item.t)>>;
385 addClauseSymsToMap(item.t, input, std::make_index_sequence<tuple_size>{});
388template <
typename C,
typename H>
390std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
391ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
392 const ClauseTy *input) {
393 std::visit([&](
auto &&s) { addClauseSymsToMap(s, input); }, item.u);
399template <
typename C,
typename H>
400bool ConstructDecompositionT<C, H>::applyToUnique(
const ClauseTy *input) {
402 return llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version);
405 if (unique != leafs.end()) {
406 unique->clauses.push_back(input);
414template <
typename C,
typename H>
415template <
typename Iterator>
416bool ConstructDecompositionT<C, H>::applyToFirst(
421 for (
auto &leaf : range) {
422 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version))
424 leaf.clauses.push_back(input);
432template <
typename C,
typename H>
433bool ConstructDecompositionT<C, H>::applyToInnermost(
const ClauseTy *input) {
439template <
typename C,
typename H>
440bool ConstructDecompositionT<C, H>::applyToOutermost(
const ClauseTy *input) {
444template <
typename C,
typename H>
445template <
typename Predicate>
446bool ConstructDecompositionT<C, H>::applyIf(
const ClauseTy *input,
448 bool applied =
false;
449 for (
auto &leaf : leafs) {
450 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version))
454 leaf.clauses.push_back(input);
461template <
typename C,
typename H>
462bool ConstructDecompositionT<C, H>::applyToAll(
const ClauseTy *input) {
463 return applyIf(input, [](
auto) {
return true; });
466template <
typename C,
typename H>
467template <
typename Specific>
468bool ConstructDecompositionT<C, H>::applyClause(Specific &&specific,
477 if (!applyToUnique(input))
493template <
typename C,
typename H>
494bool ConstructDecompositionT<C, H>::applyClause(
496 const ClauseTy *input) {
501 bool applied = applyIf(input, [&](
const auto &leaf) {
502 return llvm::any_of(leaf.clauses, [&](
const ClauseTy *n) {
503 return llvm::omp::isPrivatizingClause(n->id, version);
519template <
typename C,
typename H>
520bool ConstructDecompositionT<C, H>::applyClause(
521 const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &
clause,
522 const ClauseTy *input) {
523 if (!applyToInnermost(input))
535template <
typename C,
typename H>
536bool ConstructDecompositionT<C, H>::applyClause(
537 const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &
clause,
538 const ClauseTy *input) {
540 if (!applyToAll(input))
551template <
typename C,
typename H>
552bool ConstructDecompositionT<C, H>::applyClause(
553 const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &
clause,
554 const ClauseTy *node) {
555 if (!applyToOutermost(node))
590template <
typename C,
typename H>
591bool ConstructDecompositionT<C, H>::applyClause(
592 const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &
clause,
593 const ClauseTy *input) {
594 bool applied =
false;
597 auto dirDistribute = findDirective(llvm::omp::OMPD_distribute);
598 auto dirTeams = findDirective(llvm::omp::OMPD_teams);
599 if (dirDistribute !=
nullptr) {
600 dirDistribute->clauses.push_back(input);
603 if (dirTeams !=
nullptr) {
604 auto *shared = makeClause(
605 llvm::omp::Clause::OMPC_shared,
606 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
607 dirTeams->clauses.push_back(shared);
609 }
else if (dirTeams !=
nullptr) {
610 dirTeams->clauses.push_back(input);
615 auto findWorksharing = [&]() {
617 for (
auto &leaf : leafs) {
618 auto found =
llvm::find(worksharing, leaf.id);
619 if (found != std::end(worksharing))
622 return static_cast<typename decltype(leafs)::value_type *
>(
nullptr);
625 auto dirWorksharing = findWorksharing();
626 if (dirWorksharing !=
nullptr) {
627 dirWorksharing->clauses.push_back(input);
632 auto dirTaskloop = findDirective(llvm::omp::OMPD_taskloop);
633 if (dirTaskloop !=
nullptr) {
634 dirTaskloop->clauses.push_back(input);
639 auto dirParallel = findDirective(llvm::omp::OMPD_parallel);
640 if (dirParallel !=
nullptr) {
641 if (dirTaskloop ==
nullptr && dirWorksharing ==
nullptr) {
642 dirParallel->clauses.push_back(input);
646 auto *shared = makeClause(
647 llvm::omp::Clause::OMPC_shared,
648 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
649 dirParallel->clauses.push_back(shared);
654 auto inLastprivate = [&](
const ObjectTy &object) {
655 if (ClauseSet *set = findClausesWith(
object)) {
657 return c->id == llvm::omp::Clause::OMPC_lastprivate;
663 auto dirTarget = findDirective(llvm::omp::OMPD_target);
664 if (dirTarget !=
nullptr) {
667 clause.v, std::back_inserter(objects), [&](
const ObjectTy &
object) {
668 return !inLastprivate(object) && !mapBases.count(object.id());
670 if (!objects.
empty()) {
671 auto *firstp = makeClause(
672 llvm::omp::Clause::OMPC_firstprivate,
673 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{objects});
674 dirTarget->clauses.push_back(firstp);
680 if (
auto dirTask = findDirective(llvm::omp::OMPD_task)) {
681 dirTask->clauses.push_back(input);
701template <
typename C,
typename H>
702bool ConstructDecompositionT<C, H>::applyClause(
703 const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &
clause,
704 const ClauseTy *input) {
705 using DirectiveNameModifier =
708 auto &modifier = std::get<std::optional<DirectiveNameModifier>>(
clause.t);
711 llvm::omp::Directive dirId = *modifier;
713 makeClause(llvm::omp::Clause::OMPC_if,
714 tomp::clause::IfT<TypeTy, IdTy, ExprTy>{
716 std::get<IfExpression>(
clause.t)}});
718 if (
auto *hasDir = findDirective(dirId)) {
719 hasDir->clauses.push_back(unmodified);
725 if (!applyToAll(input))
749template <
typename C,
typename H>
750bool ConstructDecompositionT<C, H>::applyClause(
751 const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &
clause,
752 const ClauseTy *input) {
754 if (!applyToAll(input))
757 auto inFirstprivate = [&](
const ObjectTy &object) {
758 if (ClauseSet *set = findClausesWith(
object)) {
760 return c->id == llvm::omp::Clause::OMPC_firstprivate;
766 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
771 objects, std::back_inserter(sharedObjects),
772 [&](
const ObjectTy &
object) {
return !inFirstprivate(
object); });
774 if (!sharedObjects.empty()) {
776 if (
auto dirParallel = findDirective(llvm::omp::OMPD_parallel)) {
777 auto *shared = makeClause(
778 llvm::omp::Clause::OMPC_shared,
779 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
780 dirParallel->clauses.push_back(shared);
784 if (
auto dirTeams = findDirective(llvm::omp::OMPD_teams)) {
785 auto *shared = makeClause(
786 llvm::omp::Clause::OMPC_shared,
787 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
788 dirTeams->clauses.push_back(shared);
793 if (
auto dirTarget = findDirective(llvm::omp::OMPD_target)) {
796 objects, std::back_inserter(tofrom),
797 [&](
const ObjectTy &
object) {
return !mapBases.count(
object.
id()); });
799 if (!tofrom.
empty()) {
801 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
803 makeClause(llvm::omp::Clause::OMPC_map,
804 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
809 std::nullopt, std::nullopt,
810 std::move(tofrom)}});
811 dirTarget->clauses.push_back(map);
835template <
typename C,
typename H>
836bool ConstructDecompositionT<C, H>::applyClause(
837 const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &
clause,
838 const ClauseTy *input) {
840 if (!applyToInnermost(input))
844 auto dirSimd = findDirective(llvm::omp::Directive::OMPD_simd);
845 std::optional<ObjectTy> iterVar = helper.getLoopIterVar();
846 const auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
852 for (
const ObjectTy &
object : objects) {
853 last.push_back(
object);
854 if (!dirSimd || !iterVar ||
object.
id() != iterVar->id())
855 first.push_back(
object);
858 if (!first.empty()) {
862 bool allowed =
llvm::any_of(leafs, [
this](
const LeafReprInternal &leaf) {
863 return llvm::omp::isAllowedClauseForDirective(
864 leaf.id, llvm::omp::Clause::OMPC_firstprivate, version);
867 auto *firstp = makeClause(
868 llvm::omp::Clause::OMPC_firstprivate,
869 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{first});
870 inputClauses.push_back(firstp);
875 makeClause(llvm::omp::Clause::OMPC_lastprivate,
876 tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>{
877 {std::nullopt,
last}});
878 inputClauses.push_back(lastp);
891template <
typename C,
typename H>
892bool ConstructDecompositionT<C, H>::applyClause(
893 const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &
clause,
894 const ClauseTy *input) {
895 if (!applyToOutermost(input))
901template <
typename C,
typename H>
902bool ConstructDecompositionT<C, H>::applyClause(
903 const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &
clause,
904 const ClauseTy *input) {
905 if (!applyToAll(input))
911template <
typename C,
typename H>
912bool ConstructDecompositionT<C, H>::applyClause(
913 const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &
clause,
914 const ClauseTy *input) {
915 if (!applyToOutermost(input))
927template <
typename C,
typename H>
928bool ConstructDecompositionT<C, H>::applyClause(
929 const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &
clause,
930 const ClauseTy *input) {
932 if (!applyToAll(input))
945template <
typename C,
typename H>
946bool ConstructDecompositionT<C, H>::applyClause(
947 const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &
clause,
948 const ClauseTy *input) {
949 if (!applyToInnermost(input))
980template <
typename C,
typename H>
981bool ConstructDecompositionT<C, H>::applyClause(
982 const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &
clause,
983 const ClauseTy *input) {
984 using ReductionTy = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
987 bool applyToParallel =
true, applyToTeams =
true;
989 auto dirParallel = findDirective(llvm::omp::Directive::OMPD_parallel);
993 llvm::omp::Directive::OMPD_loop,
994 llvm::omp::Directive::OMPD_sections,
995 llvm::omp::Directive::OMPD_taskloop,
997 auto present = [&](llvm::omp::Directive id) {
998 return findDirective(
id) !=
nullptr;
1002 applyToParallel =
false;
1005 auto dirTeams = findDirective(llvm::omp::Directive::OMPD_teams);
1008 if (findDirective(llvm::omp::Directive::OMPD_loop))
1009 applyToTeams =
false;
1012 using ReductionModifier =
typename ReductionTy::ReductionModifier;
1013 using ReductionIdentifiers =
typename ReductionTy::ReductionIdentifiers;
1015 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
1016 auto &modifier = std::get<std::optional<ReductionModifier>>(
clause.t);
1021 bool applied =
false;
1024 auto isValidModifier = [](llvm::omp::Directive dir, ReductionModifier
mod,
1025 bool alreadyApplied) {
1027 case ReductionModifier::Inscan:
1030 return dir == llvm::omp::Directive::OMPD_simd ||
1032 case ReductionModifier::Task:
1037 return dir == llvm::omp::Directive::OMPD_parallel ||
1039 case ReductionModifier::Default:
1045 auto *unmodified = makeClause(
1046 llvm::omp::Clause::OMPC_reduction,
1049 std::get<ReductionIdentifiers>(
clause.t),
1052 ReductionModifier effective = modifier.value_or(ReductionModifier::Default);
1053 bool modifierApplied =
false;
1054 bool allowingLeaf =
false;
1058 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version))
1062 allowingLeaf =
true;
1063 if (!applyToParallel && &leaf == dirParallel)
1065 if (!applyToTeams && &leaf == dirTeams)
1068 if (isValidModifier(leaf.id, effective, modifierApplied)) {
1070 leaf.clauses.push_back(input);
1071 modifierApplied =
true;
1074 leaf.clauses.push_back(unmodified);
1077 applied = modifierApplied;
1087 [&](
const ObjectTy &
object) {
1088 auto maybeBase = helper.getBaseObject(
object);
1089 return maybeBase ? *maybeBase : object;
1093 if (!sharedObjects.
empty()) {
1094 if (dirParallel && !applyToParallel) {
1095 auto *shared = makeClause(
1096 llvm::omp::Clause::OMPC_shared,
1097 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1098 dirParallel->clauses.push_back(shared);
1100 if (dirTeams && !applyToTeams) {
1101 auto *shared = makeClause(
1102 llvm::omp::Clause::OMPC_shared,
1103 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1104 dirTeams->clauses.push_back(shared);
1109 auto dirTarget = findDirective(llvm::omp::Directive::OMPD_target);
1110 if (dirTarget && leafs.size() > 1) {
1113 [&](
const ObjectTy &
object) {
1114 if (
auto maybeBase = helper.getBaseObject(
object))
1115 return !mapBases.count(maybeBase->id());
1116 return !mapBases.count(
object.
id());
1118 if (!tofrom.
empty()) {
1120 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
1121 auto *map = makeClause(
1122 llvm::omp::Clause::OMPC_map,
1123 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
1124 {MapType::Tofrom, std::nullopt,
1125 std::nullopt, std::nullopt,
1126 std::nullopt, std::nullopt,
1127 std::move(tofrom)}});
1129 dirTarget->clauses.push_back(map);
1143template <
typename C,
typename H>
1144bool ConstructDecompositionT<C, H>::applyClause(
1145 const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &
clause,
1146 const ClauseTy *input) {
1148 if (!applyToAll(input))
1160template <
typename C,
typename H>
1161bool ConstructDecompositionT<C, H>::applyClause(
1162 const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &
clause,
1163 const ClauseTy *input) {
1165 if (!applyToAll(input))
1172template <
typename C,
typename H>
bool ConstructDecompositionT<C, H>::split() {
1176 leafs.push_back(LeafReprInternal{leaf, {}});
1178 for (
const ClauseTy *input : inputClauses)
1179 addClauseSymsToMap(*input, input);
1186 for (
const ClauseTy *input : inputClauses) {
1187 if (input->id == llvm::omp::Clause::OMPC_linear)
1190 for (
const auto *input : linears) {
1192 applyClause(std::get<tomp::clause::LinearT<TypeTy, IdTy, ExprTy>>(
1199 auto skip = [](
const ClauseTy *input) {
1200 switch (input->id) {
1201 case llvm::omp::Clause::OMPC_allocate:
1202 case llvm::omp::Clause::OMPC_linear:
1210 for (
const ClauseTy *input : inputClauses) {
1215 std::visit([&](
auto &&s) {
return applyClause(s, input); }, input->u);
1219 for (
const ClauseTy *input : inputClauses) {
1220 if (input->id != llvm::omp::Clause::OMPC_allocate)
1224 std::visit([&](
auto &&s) {
return applyClause(s, input); }, input->u);
static llvm::ArrayRef< llvm::omp::Directive > getWorksharing()
static llvm::ArrayRef< llvm::omp::Directive > getWorksharingLoop()
static bool shouldApply(Function &F, ProfileSummaryInfo &PSI)
static bool skip(GsymDataExtractor &Data, uint64_t &Offset, bool SkippedRanges)
Skip an InlineInfo object in the specified data at the specified offset.
This file defines the SmallVector class.
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.
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