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();
90template <
typename ClauseType,
typename HelperType>
94 using TypeTy =
typename ClauseTy::TypeTy;
95 using IdTy =
typename ClauseTy::IdTy;
96 using ExprTy =
typename ClauseTy::ExprTy;
103 llvm::omp::Directive dir,
105 : version(ver), helper(helper), inputDirective(dir) {
107 inputClauses.push_back(&
clause);
109 bool success = split();
117 for (
auto &leaf : leafs) {
118 output.push_back({leaf.id, {}});
119 auto &out =
output.back();
120 for (
const ClauseTy *c : leaf.clauses)
121 out.clauses.push_back(*c);
132 errors.emplace_back(input, ec);
136 struct LeafReprInternal {
137 llvm::omp::Directive
id = llvm::omp::Directive::OMPD_unknown;
141 LeafReprInternal *findDirective(llvm::omp::Directive dirId) {
143 leafs, [&](
const LeafReprInternal &leaf) {
return leaf.id == dirId; });
144 return found != leafs.end() ? &*found :
nullptr;
148 if (
auto found = syms.find(
object.id()); found != syms.end())
149 return &found->second;
153 template <
typename S>
154 ClauseTy *makeClause(llvm::omp::Clause clauseId, S &&specific) {
155 implicit.push_back(
typename ClauseTy::BaseT{clauseId, std::move(specific)});
156 return &implicit.back();
164 void addClauseSymsToMap(
const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
167 template <
typename U>
168 void addClauseSymsToMap(
const std::optional<U> &item,
const ClauseTy *);
169 template <
typename U>
171 template <
typename...
U,
size_t... Is>
172 void addClauseSymsToMap(
const std::tuple<U...> &item,
const ClauseTy *,
173 std::index_sequence<Is...> = {});
174 template <
typename U>
175 std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
176 addClauseSymsToMap(U &&item,
const ClauseTy *);
178 template <
typename U>
179 std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
180 addClauseSymsToMap(U &&item,
const ClauseTy *);
182 template <
typename U>
183 std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
184 addClauseSymsToMap(U &&item,
const ClauseTy *);
186 template <
typename U>
187 std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
188 addClauseSymsToMap(U &&item,
const ClauseTy *);
190 template <
typename U>
191 std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
192 addClauseSymsToMap(U &&item,
const ClauseTy *);
194 template <
typename U>
195 std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
196 addClauseSymsToMap(U &&item,
const ClauseTy *);
201 bool applyToUnique(
const ClauseTy *input);
205 template <
typename Iterator>
206 bool applyToFirst(
const ClauseTy *input,
211 bool applyToInnermost(
const ClauseTy *input);
215 bool applyToOutermost(
const ClauseTy *input);
220 template <
typename Predicate>
225 bool applyToAll(
const ClauseTy *input);
227 template <
typename Clause>
228 bool applyClause(Clause &&clause,
const ClauseTy *input);
230 bool applyClause(
const tomp::clause::AllocateT<TypeTy, IdTy, ExprTy> &clause,
232 bool applyClause(
const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &clause,
234 bool applyClause(
const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,
237 const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
240 applyClause(
const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,
242 bool applyClause(
const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,
245 applyClause(
const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,
247 bool applyClause(
const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,
249 bool applyClause(
const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,
252 applyClause(
const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,
254 bool applyClause(
const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &clause,
256 bool applyClause(
const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,
258 bool applyClause(
const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,
260 bool applyClause(
const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,
262 bool applyClause(
const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,
265 applyClause(
const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
268 llvm::omp::Version version;
270 llvm::omp::Directive inputDirective;
274 std::list<ClauseTy> implicit;
276 std::unordered_map<IdTy, ClauseSet> syms;
277 std::unordered_set<IdTy> mapBases;
281template <
typename ClauseType,
typename HelperType>
286template <
typename C,
typename H>
287void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ObjectTy &
object,
288 const ClauseTy *input) {
289 syms[
object.id()].insert(input);
292template <
typename C,
typename H>
293void ConstructDecompositionT<C, H>::addClauseSymsToMap(
295 for (
auto &
object : objects)
296 syms[
object.id()].insert(input);
299template <
typename C,
typename H>
300void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const TypeTy &item,
301 const ClauseTy *input) {
305template <
typename C,
typename H>
306void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ExprTy &item,
307 const ClauseTy *input) {
311template <
typename C,
typename H>
312void ConstructDecompositionT<C, H>::addClauseSymsToMap(
313 const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
314 const ClauseTy *input) {
315 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(item.
t);
316 addClauseSymsToMap(objects, input);
317 for (
auto &
object : objects) {
318 if (
auto base = helper.getBaseObject(
object))
319 mapBases.insert(base->id());
323template <
typename C,
typename H>
325void ConstructDecompositionT<C, H>::addClauseSymsToMap(
326 const std::optional<U> &item,
const ClauseTy *input) {
328 addClauseSymsToMap(*item, input);
331template <
typename C,
typename H>
333void ConstructDecompositionT<C, H>::addClauseSymsToMap(
336 addClauseSymsToMap(s, input);
339template <
typename C,
typename H>
340template <
typename...
U,
size_t... Is>
341void ConstructDecompositionT<C, H>::addClauseSymsToMap(
342 const std::tuple<U...> &item,
const ClauseTy *input,
343 std::index_sequence<Is...>) {
345 (addClauseSymsToMap(std::get<Is>(item), input), ...);
348template <
typename C,
typename H>
350std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
351ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
352 const ClauseTy *input) {
356template <
typename C,
typename H>
358std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
359ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
360 const ClauseTy *input) {
364template <
typename C,
typename H>
366std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
367ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
368 const ClauseTy *input) {
372template <
typename C,
typename H>
374std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
375ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
376 const ClauseTy *input) {
377 addClauseSymsToMap(item.v, input);
380template <
typename C,
typename H>
382std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
383ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
384 const ClauseTy *input) {
385 constexpr size_t tuple_size =
386 std::tuple_size_v<llvm::remove_cvref_t<
decltype(item.t)>>;
387 addClauseSymsToMap(item.t, input, std::make_index_sequence<tuple_size>{});
390template <
typename C,
typename H>
392std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
393ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
394 const ClauseTy *input) {
395 std::visit([&](
auto &&s) { addClauseSymsToMap(s, input); }, item.u);
401template <
typename C,
typename H>
402bool ConstructDecompositionT<C, H>::applyToUnique(
const ClauseTy *input) {
404 return helper.isClauseAllowedOnDirective(input->id, leaf.id, version);
407 if (unique != leafs.end()) {
408 unique->clauses.push_back(input);
416template <
typename C,
typename H>
417template <
typename Iterator>
418bool ConstructDecompositionT<C, H>::applyToFirst(
423 for (
auto &leaf : range) {
424 if (!helper.isClauseAllowedOnDirective(input->id, leaf.id, version))
426 leaf.clauses.push_back(input);
434template <
typename C,
typename H>
435bool ConstructDecompositionT<C, H>::applyToInnermost(
const ClauseTy *input) {
441template <
typename C,
typename H>
442bool ConstructDecompositionT<C, H>::applyToOutermost(
const ClauseTy *input) {
446template <
typename C,
typename H>
447template <
typename Predicate>
448bool ConstructDecompositionT<C, H>::applyIf(
const ClauseTy *input,
450 bool applied =
false;
451 for (
auto &leaf : leafs) {
452 if (!helper.isClauseAllowedOnDirective(input->id, leaf.id, version))
456 leaf.clauses.push_back(input);
463template <
typename C,
typename H>
464bool ConstructDecompositionT<C, H>::applyToAll(
const ClauseTy *input) {
465 return applyIf(input, [](
auto) {
return true; });
468template <
typename C,
typename H>
469template <
typename Specific>
470bool ConstructDecompositionT<C, H>::applyClause(Specific &&specific,
479 if (!applyToUnique(input))
495template <
typename C,
typename H>
496bool ConstructDecompositionT<C, H>::applyClause(
498 const ClauseTy *input) {
503 bool applied = applyIf(input, [&](
const auto &leaf) {
504 return llvm::any_of(leaf.clauses, [&](
const ClauseTy *n) {
505 return llvm::omp::isPrivatizingClause(n->id, version);
521template <
typename C,
typename H>
522bool ConstructDecompositionT<C, H>::applyClause(
523 const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &
clause,
524 const ClauseTy *input) {
525 if (!applyToInnermost(input))
537template <
typename C,
typename H>
538bool ConstructDecompositionT<C, H>::applyClause(
539 const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &
clause,
540 const ClauseTy *input) {
542 if (!applyToAll(input))
553template <
typename C,
typename H>
554bool ConstructDecompositionT<C, H>::applyClause(
555 const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &
clause,
556 const ClauseTy *node) {
557 if (!applyToOutermost(node))
592template <
typename C,
typename H>
593bool ConstructDecompositionT<C, H>::applyClause(
594 const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &
clause,
595 const ClauseTy *input) {
596 bool applied =
false;
599 auto dirDistribute = findDirective(llvm::omp::OMPD_distribute);
600 auto dirTeams = findDirective(llvm::omp::OMPD_teams);
601 if (dirDistribute !=
nullptr) {
602 dirDistribute->clauses.push_back(input);
605 if (dirTeams !=
nullptr) {
606 auto *shared = makeClause(
607 llvm::omp::Clause::OMPC_shared,
608 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
609 dirTeams->clauses.push_back(shared);
611 }
else if (dirTeams !=
nullptr) {
612 dirTeams->clauses.push_back(input);
619 auto findWorksharingAcceptingFirstprivate = [&]() {
621 for (
auto &leaf : leafs) {
622 auto found =
llvm::find(worksharing, leaf.id);
623 if (found != std::end(worksharing) &&
624 helper.isClauseAllowedOnDirective(input->id, leaf.id, version))
627 return static_cast<typename decltype(leafs)::value_type *
>(
nullptr);
630 auto dirWorksharing = findWorksharingAcceptingFirstprivate();
631 if (dirWorksharing !=
nullptr) {
632 dirWorksharing->clauses.push_back(input);
637 auto dirTaskloop = findDirective(llvm::omp::OMPD_taskloop);
638 if (dirTaskloop !=
nullptr) {
639 dirTaskloop->clauses.push_back(input);
644 auto dirParallel = findDirective(llvm::omp::OMPD_parallel);
645 if (dirParallel !=
nullptr) {
646 if (dirTaskloop ==
nullptr && dirWorksharing ==
nullptr) {
647 dirParallel->clauses.push_back(input);
651 auto *shared = makeClause(
652 llvm::omp::Clause::OMPC_shared,
653 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
654 dirParallel->clauses.push_back(shared);
659 auto inLastprivate = [&](
const ObjectTy &object) {
660 if (ClauseSet *set = findClausesWith(
object)) {
662 return c->id == llvm::omp::Clause::OMPC_lastprivate;
668 auto dirTarget = findDirective(llvm::omp::OMPD_target);
669 if (dirTarget !=
nullptr) {
672 clause.v, std::back_inserter(objects), [&](
const ObjectTy &
object) {
673 return !inLastprivate(object) && !mapBases.count(object.id());
675 if (!objects.
empty()) {
676 auto *firstp = makeClause(
677 llvm::omp::Clause::OMPC_firstprivate,
678 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{objects});
679 dirTarget->clauses.push_back(firstp);
685 if (
auto dirTask = findDirective(llvm::omp::OMPD_task)) {
686 dirTask->clauses.push_back(input);
706template <
typename C,
typename H>
707bool ConstructDecompositionT<C, H>::applyClause(
708 const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &
clause,
709 const ClauseTy *input) {
713 auto &modifier = std::get<std::optional<DirectiveNameModifier>>(
clause.t);
716 llvm::omp::Directive dirId = *modifier;
718 makeClause(llvm::omp::Clause::OMPC_if,
719 tomp::clause::IfT<TypeTy, IdTy, ExprTy>{
721 std::get<IfExpression>(
clause.t)}});
723 if (
auto *hasDir = findDirective(dirId)) {
724 hasDir->clauses.push_back(unmodified);
730 if (!applyToAll(input))
754template <
typename C,
typename H>
755bool ConstructDecompositionT<C, H>::applyClause(
756 const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &
clause,
757 const ClauseTy *input) {
759 if (!applyToAll(input))
762 auto inFirstprivate = [&](
const ObjectTy &object) {
763 if (ClauseSet *set = findClausesWith(
object)) {
765 return c->id == llvm::omp::Clause::OMPC_firstprivate;
771 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
776 objects, std::back_inserter(sharedObjects),
777 [&](
const ObjectTy &
object) {
return !inFirstprivate(
object); });
779 if (!sharedObjects.empty()) {
781 if (
auto dirParallel = findDirective(llvm::omp::OMPD_parallel)) {
782 auto *shared = makeClause(
783 llvm::omp::Clause::OMPC_shared,
784 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
785 dirParallel->clauses.push_back(shared);
789 if (
auto dirTeams = findDirective(llvm::omp::OMPD_teams)) {
790 auto *shared = makeClause(
791 llvm::omp::Clause::OMPC_shared,
792 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
793 dirTeams->clauses.push_back(shared);
798 if (
auto dirTarget = findDirective(llvm::omp::OMPD_target)) {
801 objects, std::back_inserter(tofrom),
802 [&](
const ObjectTy &
object) {
return !mapBases.count(
object.
id()); });
804 if (!tofrom.
empty()) {
806 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
808 makeClause(llvm::omp::Clause::OMPC_map,
809 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
814 std::nullopt, std::nullopt,
815 std::move(tofrom)}});
816 dirTarget->clauses.push_back(map);
840template <
typename C,
typename H>
841bool ConstructDecompositionT<C, H>::applyClause(
842 const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &
clause,
843 const ClauseTy *input) {
845 if (!applyToInnermost(input))
849 auto dirSimd = findDirective(llvm::omp::Directive::OMPD_simd);
850 std::optional<ObjectTy> iterVar = helper.getLoopIterVar();
851 const auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
857 for (
const ObjectTy &
object : objects) {
858 last.push_back(
object);
859 if (!dirSimd || !iterVar ||
object.
id() != iterVar->id())
860 first.push_back(
object);
863 if (!first.empty()) {
867 bool allowed =
llvm::any_of(leafs, [
this](
const LeafReprInternal &leaf) {
868 return helper.isClauseAllowedOnDirective(
869 llvm::omp::Clause::OMPC_firstprivate, leaf.id, version);
872 auto *firstp = makeClause(
873 llvm::omp::Clause::OMPC_firstprivate,
874 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{first});
875 inputClauses.push_back(firstp);
880 makeClause(llvm::omp::Clause::OMPC_lastprivate,
881 tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>{
882 {std::nullopt,
last}});
883 inputClauses.push_back(lastp);
896template <
typename C,
typename H>
897bool ConstructDecompositionT<C, H>::applyClause(
898 const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &
clause,
899 const ClauseTy *input) {
900 if (!applyToOutermost(input))
906template <
typename C,
typename H>
907bool ConstructDecompositionT<C, H>::applyClause(
908 const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &
clause,
909 const ClauseTy *input) {
910 if (!applyToAll(input))
916template <
typename C,
typename H>
917bool ConstructDecompositionT<C, H>::applyClause(
918 const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &
clause,
919 const ClauseTy *input) {
920 if (!applyToOutermost(input))
932template <
typename C,
typename H>
933bool ConstructDecompositionT<C, H>::applyClause(
934 const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &
clause,
935 const ClauseTy *input) {
937 if (!applyToAll(input))
950template <
typename C,
typename H>
951bool ConstructDecompositionT<C, H>::applyClause(
952 const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &
clause,
953 const ClauseTy *input) {
954 if (!applyToInnermost(input))
985template <
typename C,
typename H>
986bool ConstructDecompositionT<C, H>::applyClause(
987 const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &
clause,
988 const ClauseTy *input) {
989 using ReductionTy = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
992 bool applyToParallel =
true, applyToTeams =
true;
994 auto dirParallel = findDirective(llvm::omp::Directive::OMPD_parallel);
998 llvm::omp::Directive::OMPD_loop,
999 llvm::omp::Directive::OMPD_sections,
1000 llvm::omp::Directive::OMPD_taskloop,
1002 auto present = [&](llvm::omp::Directive id) {
1003 return findDirective(
id) !=
nullptr;
1007 applyToParallel =
false;
1010 auto dirTeams = findDirective(llvm::omp::Directive::OMPD_teams);
1013 if (findDirective(llvm::omp::Directive::OMPD_loop))
1014 applyToTeams =
false;
1018 using ReductionIdentifiers =
typename ReductionTy::ReductionIdentifiers;
1020 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
1021 auto &modifier = std::get<std::optional<ReductionModifier>>(
clause.t);
1026 bool applied =
false;
1030 bool alreadyApplied) {
1032 case ReductionModifier::Inscan:
1035 return dir == llvm::omp::Directive::OMPD_simd ||
1037 case ReductionModifier::Task:
1042 return dir == llvm::omp::Directive::OMPD_parallel ||
1044 case ReductionModifier::Default:
1050 auto *unmodified = makeClause(
1051 llvm::omp::Clause::OMPC_reduction,
1054 std::get<ReductionIdentifiers>(
clause.t),
1058 bool modifierApplied =
false;
1059 bool allowingLeaf =
false;
1063 if (!helper.isClauseAllowedOnDirective(input->id, leaf.id, version))
1067 allowingLeaf =
true;
1068 if (!applyToParallel && &leaf == dirParallel)
1070 if (!applyToTeams && &leaf == dirTeams)
1073 if (isValidModifier(leaf.id, effective, modifierApplied)) {
1075 leaf.clauses.push_back(input);
1076 modifierApplied =
true;
1079 leaf.clauses.push_back(unmodified);
1082 applied = modifierApplied;
1092 [&](
const ObjectTy &
object) {
1093 auto maybeBase = helper.getBaseObject(
object);
1094 return maybeBase ? *maybeBase : object;
1098 if (!sharedObjects.
empty()) {
1099 if (dirParallel && !applyToParallel) {
1100 auto *shared = makeClause(
1101 llvm::omp::Clause::OMPC_shared,
1102 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1103 dirParallel->clauses.push_back(shared);
1105 if (dirTeams && !applyToTeams) {
1106 auto *shared = makeClause(
1107 llvm::omp::Clause::OMPC_shared,
1108 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1109 dirTeams->clauses.push_back(shared);
1114 auto dirTarget = findDirective(llvm::omp::Directive::OMPD_target);
1115 if (dirTarget && leafs.size() > 1) {
1118 [&](
const ObjectTy &
object) {
1119 if (
auto maybeBase = helper.getBaseObject(
object))
1120 return !mapBases.count(maybeBase->id());
1121 return !mapBases.count(
object.
id());
1123 if (!tofrom.
empty()) {
1125 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
1126 auto *map = makeClause(
1127 llvm::omp::Clause::OMPC_map,
1128 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
1129 {MapType::Tofrom, std::nullopt,
1130 std::nullopt, std::nullopt,
1131 std::nullopt, std::nullopt,
1132 std::move(tofrom)}});
1134 dirTarget->clauses.push_back(map);
1148template <
typename C,
typename H>
1149bool ConstructDecompositionT<C, H>::applyClause(
1150 const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &
clause,
1151 const ClauseTy *input) {
1153 if (!applyToAll(input))
1165template <
typename C,
typename H>
1166bool ConstructDecompositionT<C, H>::applyClause(
1167 const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &
clause,
1168 const ClauseTy *input) {
1170 if (!applyToAll(input))
1177template <
typename C,
typename H>
bool ConstructDecompositionT<C, H>::split() {
1181 leafs.push_back(LeafReprInternal{leaf, {}});
1183 for (
const ClauseTy *input : inputClauses)
1184 addClauseSymsToMap(*input, input);
1191 for (
const ClauseTy *input : inputClauses) {
1192 if (input->id == llvm::omp::Clause::OMPC_linear)
1195 for (
const auto *input : linears) {
1197 applyClause(std::get<tomp::clause::LinearT<TypeTy, IdTy, ExprTy>>(
1204 auto skip = [](
const ClauseTy *input) {
1205 switch (input->id) {
1206 case llvm::omp::Clause::OMPC_allocate:
1207 case llvm::omp::Clause::OMPC_linear:
1215 for (
const ClauseTy *input : inputClauses) {
1220 std::visit([&](
auto &&s) {
return applyClause(s, input); }, input->u);
1224 for (
const ClauseTy *input : inputClauses) {
1225 if (input->id != llvm::omp::Clause::OMPC_allocate)
1229 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
ConstructDecompositionT(llvm::omp::Version, HelperType &, llvm::omp::Directive, llvm::ArrayRef< ClauseType >) -> ConstructDecompositionT< ClauseType, HelperType >
type::ObjectListT< I, E > ObjectListT
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
ConstructDecompositionT(llvm::omp::Version ver, HelperType &helper, llvm::omp::Directive dir, llvm::ArrayRef< ClauseTy > clauses)
typename ClauseTy::IdTy IdTy
tomp::ObjectT< IdTy, ExprTy > ObjectTy
tomp::ListT< DirectiveWithClauses< ClauseType > > output
type::DirectiveName DirectiveNameModifier
std::tuple< OPT(MapType), OPT(MapTypeModifiers), OPT(AttachModifier), OPT(RefModifier), OPT(Mappers), OPT(Iterator), LocatorList > t