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 applyClause(
const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,
237 bool applyClause(
const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,
240 applyClause(
const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,
242 bool applyClause(
const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,
244 bool applyClause(
const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,
247 applyClause(
const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,
249 bool applyClause(
const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &clause,
251 bool applyClause(
const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,
253 bool applyClause(
const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,
255 bool applyClause(
const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,
257 bool applyClause(
const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,
260 applyClause(
const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
265 llvm::omp::Directive inputDirective;
269 std::list<ClauseTy> implicit;
271 std::unordered_map<IdTy, ClauseSet> syms;
272 std::unordered_set<IdTy> mapBases;
276template <
typename ClauseType,
typename HelperType>
281template <
typename C,
typename H>
282void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ObjectTy &
object,
283 const ClauseTy *input) {
284 syms[
object.id()].insert(input);
287template <
typename C,
typename H>
288void ConstructDecompositionT<C, H>::addClauseSymsToMap(
290 for (
auto &
object : objects)
291 syms[
object.id()].insert(input);
294template <
typename C,
typename H>
295void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const TypeTy &item,
296 const ClauseTy *input) {
300template <
typename C,
typename H>
301void ConstructDecompositionT<C, H>::addClauseSymsToMap(
const ExprTy &item,
302 const ClauseTy *input) {
306template <
typename C,
typename H>
307void ConstructDecompositionT<C, H>::addClauseSymsToMap(
308 const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
309 const ClauseTy *input) {
310 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(item.
t);
311 addClauseSymsToMap(objects, input);
312 for (
auto &
object : objects) {
313 if (
auto base = helper.getBaseObject(
object))
314 mapBases.insert(base->id());
318template <
typename C,
typename H>
320void ConstructDecompositionT<C, H>::addClauseSymsToMap(
321 const std::optional<U> &item,
const ClauseTy *input) {
323 addClauseSymsToMap(*item, input);
326template <
typename C,
typename H>
328void ConstructDecompositionT<C, H>::addClauseSymsToMap(
331 addClauseSymsToMap(s, input);
334template <
typename C,
typename H>
335template <
typename...
U,
size_t... Is>
336void ConstructDecompositionT<C, H>::addClauseSymsToMap(
337 const std::tuple<U...> &item,
const ClauseTy *input,
338 std::index_sequence<Is...>) {
340 (addClauseSymsToMap(std::get<Is>(item), input), ...);
343template <
typename C,
typename H>
345std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>,
void>
346ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
347 const ClauseTy *input) {
351template <
typename C,
typename H>
353std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value,
void>
354ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
355 const ClauseTy *input) {
359template <
typename C,
typename H>
361std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value,
void>
362ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
363 const ClauseTy *input) {
367template <
typename C,
typename H>
369std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value,
void>
370ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
371 const ClauseTy *input) {
372 addClauseSymsToMap(item.v, input);
375template <
typename C,
typename H>
377std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value,
void>
378ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
379 const ClauseTy *input) {
380 constexpr size_t tuple_size =
381 std::tuple_size_v<llvm::remove_cvref_t<
decltype(item.t)>>;
382 addClauseSymsToMap(item.t, input, std::make_index_sequence<tuple_size>{});
385template <
typename C,
typename H>
387std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value,
void>
388ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
389 const ClauseTy *input) {
390 std::visit([&](
auto &&s) { addClauseSymsToMap(s, input); }, item.u);
396template <
typename C,
typename H>
397bool ConstructDecompositionT<C, H>::applyToUnique(
const ClauseTy *input) {
399 return llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version);
402 if (unique != leafs.end()) {
403 unique->clauses.push_back(input);
411template <
typename C,
typename H>
412template <
typename Iterator>
413bool ConstructDecompositionT<C, H>::applyToFirst(
418 for (
auto &leaf : range) {
419 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version))
421 leaf.clauses.push_back(input);
429template <
typename C,
typename H>
430bool ConstructDecompositionT<C, H>::applyToInnermost(
const ClauseTy *input) {
436template <
typename C,
typename H>
437bool ConstructDecompositionT<C, H>::applyToOutermost(
const ClauseTy *input) {
441template <
typename C,
typename H>
442template <
typename Predicate>
443bool ConstructDecompositionT<C, H>::applyIf(
const ClauseTy *input,
445 bool applied =
false;
446 for (
auto &leaf : leafs) {
447 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version))
451 leaf.clauses.push_back(input);
458template <
typename C,
typename H>
459bool ConstructDecompositionT<C, H>::applyToAll(
const ClauseTy *input) {
460 return applyIf(input, [](
auto) {
return true; });
463template <
typename C,
typename H>
464template <
typename Specific>
465bool ConstructDecompositionT<C, H>::applyClause(Specific &&specific,
474 if (!applyToUnique(input))
490template <
typename C,
typename H>
491bool ConstructDecompositionT<C, H>::applyClause(
493 const ClauseTy *input) {
498 bool applied = applyIf(input, [&](
const auto &leaf) {
499 return llvm::any_of(leaf.clauses, [&](
const ClauseTy *n) {
500 return llvm::omp::isPrivatizingClause(n->id);
516template <
typename C,
typename H>
517bool ConstructDecompositionT<C, H>::applyClause(
518 const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &
clause,
519 const ClauseTy *input) {
520 if (!applyToInnermost(input))
532template <
typename C,
typename H>
533bool ConstructDecompositionT<C, H>::applyClause(
534 const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &
clause,
535 const ClauseTy *input) {
537 if (!applyToAll(input))
572template <
typename C,
typename H>
573bool ConstructDecompositionT<C, H>::applyClause(
574 const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &
clause,
575 const ClauseTy *input) {
576 bool applied =
false;
579 auto dirDistribute = findDirective(llvm::omp::OMPD_distribute);
580 auto dirTeams = findDirective(llvm::omp::OMPD_teams);
581 if (dirDistribute !=
nullptr) {
582 dirDistribute->clauses.push_back(input);
585 if (dirTeams !=
nullptr) {
586 auto *shared = makeClause(
587 llvm::omp::Clause::OMPC_shared,
588 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
589 dirTeams->clauses.push_back(shared);
591 }
else if (dirTeams !=
nullptr) {
592 dirTeams->clauses.push_back(input);
597 auto findWorksharing = [&]() {
599 for (
auto &leaf : leafs) {
600 auto found =
llvm::find(worksharing, leaf.id);
601 if (found != std::end(worksharing))
604 return static_cast<typename decltype(leafs)::value_type *
>(
nullptr);
607 auto dirWorksharing = findWorksharing();
608 if (dirWorksharing !=
nullptr) {
609 dirWorksharing->clauses.push_back(input);
614 auto dirTaskloop = findDirective(llvm::omp::OMPD_taskloop);
615 if (dirTaskloop !=
nullptr) {
616 dirTaskloop->clauses.push_back(input);
621 auto dirParallel = findDirective(llvm::omp::OMPD_parallel);
622 if (dirParallel !=
nullptr) {
623 if (dirTaskloop ==
nullptr && dirWorksharing ==
nullptr) {
624 dirParallel->clauses.push_back(input);
628 auto *shared = makeClause(
629 llvm::omp::Clause::OMPC_shared,
630 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{
clause.v});
631 dirParallel->clauses.push_back(shared);
636 auto inLastprivate = [&](
const ObjectTy &object) {
637 if (ClauseSet *set = findClausesWith(
object)) {
639 return c->id == llvm::omp::Clause::OMPC_lastprivate;
645 auto dirTarget = findDirective(llvm::omp::OMPD_target);
646 if (dirTarget !=
nullptr) {
649 clause.v, std::back_inserter(objects), [&](
const ObjectTy &
object) {
650 return !inLastprivate(object) && !mapBases.count(object.id());
652 if (!objects.
empty()) {
653 auto *firstp = makeClause(
654 llvm::omp::Clause::OMPC_firstprivate,
655 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{objects});
656 dirTarget->clauses.push_back(firstp);
662 if (
auto dirTask = findDirective(llvm::omp::OMPD_task)) {
663 dirTask->clauses.push_back(input);
683template <
typename C,
typename H>
684bool ConstructDecompositionT<C, H>::applyClause(
685 const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &
clause,
686 const ClauseTy *input) {
687 using DirectiveNameModifier =
690 auto &modifier = std::get<std::optional<DirectiveNameModifier>>(
clause.t);
693 llvm::omp::Directive dirId = *modifier;
695 makeClause(llvm::omp::Clause::OMPC_if,
696 tomp::clause::IfT<TypeTy, IdTy, ExprTy>{
698 std::get<IfExpression>(
clause.t)}});
700 if (
auto *hasDir = findDirective(dirId)) {
701 hasDir->clauses.push_back(unmodified);
707 if (!applyToAll(input))
731template <
typename C,
typename H>
732bool ConstructDecompositionT<C, H>::applyClause(
733 const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &
clause,
734 const ClauseTy *input) {
736 if (!applyToAll(input))
739 auto inFirstprivate = [&](
const ObjectTy &object) {
740 if (ClauseSet *set = findClausesWith(
object)) {
742 return c->id == llvm::omp::Clause::OMPC_firstprivate;
748 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
753 objects, std::back_inserter(sharedObjects),
754 [&](
const ObjectTy &
object) {
return !inFirstprivate(
object); });
756 if (!sharedObjects.empty()) {
758 if (
auto dirParallel = findDirective(llvm::omp::OMPD_parallel)) {
759 auto *shared = makeClause(
760 llvm::omp::Clause::OMPC_shared,
761 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
762 dirParallel->clauses.push_back(shared);
766 if (
auto dirTeams = findDirective(llvm::omp::OMPD_teams)) {
767 auto *shared = makeClause(
768 llvm::omp::Clause::OMPC_shared,
769 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
770 dirTeams->clauses.push_back(shared);
775 if (
auto dirTarget = findDirective(llvm::omp::OMPD_target)) {
778 objects, std::back_inserter(tofrom),
779 [&](
const ObjectTy &
object) {
return !mapBases.count(
object.
id()); });
781 if (!tofrom.
empty()) {
783 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
785 makeClause(llvm::omp::Clause::OMPC_map,
786 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
791 std::nullopt, std::nullopt,
792 std::move(tofrom)}});
793 dirTarget->clauses.push_back(map);
817template <
typename C,
typename H>
818bool ConstructDecompositionT<C, H>::applyClause(
819 const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &
clause,
820 const ClauseTy *input) {
822 if (!applyToInnermost(input))
826 auto dirSimd = findDirective(llvm::omp::Directive::OMPD_simd);
827 std::optional<ObjectTy> iterVar = helper.getLoopIterVar();
828 const auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
834 for (
const ObjectTy &
object : objects) {
835 last.push_back(
object);
836 if (!dirSimd || !iterVar ||
object.
id() != iterVar->id())
837 first.push_back(
object);
840 if (!first.empty()) {
844 bool allowed =
llvm::any_of(leafs, [
this](
const LeafReprInternal &leaf) {
845 return llvm::omp::isAllowedClauseForDirective(
846 leaf.id, llvm::omp::Clause::OMPC_firstprivate, version);
849 auto *firstp = makeClause(
850 llvm::omp::Clause::OMPC_firstprivate,
851 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{first});
852 inputClauses.push_back(firstp);
857 makeClause(llvm::omp::Clause::OMPC_lastprivate,
858 tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>{
859 {std::nullopt,
last}});
860 inputClauses.push_back(lastp);
873template <
typename C,
typename H>
874bool ConstructDecompositionT<C, H>::applyClause(
875 const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &
clause,
876 const ClauseTy *input) {
877 if (!applyToOutermost(input))
883template <
typename C,
typename H>
884bool ConstructDecompositionT<C, H>::applyClause(
885 const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &
clause,
886 const ClauseTy *input) {
887 if (!applyToAll(input))
893template <
typename C,
typename H>
894bool ConstructDecompositionT<C, H>::applyClause(
895 const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &
clause,
896 const ClauseTy *input) {
897 if (!applyToOutermost(input))
909template <
typename C,
typename H>
910bool ConstructDecompositionT<C, H>::applyClause(
911 const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &
clause,
912 const ClauseTy *input) {
914 if (!applyToAll(input))
927template <
typename C,
typename H>
928bool ConstructDecompositionT<C, H>::applyClause(
929 const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &
clause,
930 const ClauseTy *input) {
931 if (!applyToInnermost(input))
962template <
typename C,
typename H>
963bool ConstructDecompositionT<C, H>::applyClause(
964 const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &
clause,
965 const ClauseTy *input) {
966 using ReductionTy = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
969 bool applyToParallel =
true, applyToTeams =
true;
971 auto dirParallel = findDirective(llvm::omp::Directive::OMPD_parallel);
975 llvm::omp::Directive::OMPD_loop,
976 llvm::omp::Directive::OMPD_sections,
977 llvm::omp::Directive::OMPD_taskloop,
979 auto present = [&](llvm::omp::Directive id) {
980 return findDirective(
id) !=
nullptr;
984 applyToParallel =
false;
987 auto dirTeams = findDirective(llvm::omp::Directive::OMPD_teams);
990 if (findDirective(llvm::omp::Directive::OMPD_loop))
991 applyToTeams =
false;
994 using ReductionModifier =
typename ReductionTy::ReductionModifier;
995 using ReductionIdentifiers =
typename ReductionTy::ReductionIdentifiers;
997 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(
clause.t);
998 auto &modifier = std::get<std::optional<ReductionModifier>>(
clause.t);
1003 bool applied =
false;
1006 auto isValidModifier = [](llvm::omp::Directive dir, ReductionModifier
mod,
1007 bool alreadyApplied) {
1009 case ReductionModifier::Inscan:
1012 return dir == llvm::omp::Directive::OMPD_simd ||
1014 case ReductionModifier::Task:
1019 return dir == llvm::omp::Directive::OMPD_parallel ||
1021 case ReductionModifier::Default:
1027 auto *unmodified = makeClause(
1028 llvm::omp::Clause::OMPC_reduction,
1031 std::get<ReductionIdentifiers>(
clause.t),
1034 ReductionModifier effective = modifier.value_or(ReductionModifier::Default);
1035 bool modifierApplied =
false;
1036 bool allowingLeaf =
false;
1040 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, input->id, version))
1044 allowingLeaf =
true;
1045 if (!applyToParallel && &leaf == dirParallel)
1047 if (!applyToTeams && &leaf == dirTeams)
1050 if (isValidModifier(leaf.id, effective, modifierApplied)) {
1052 leaf.clauses.push_back(input);
1053 modifierApplied =
true;
1056 leaf.clauses.push_back(unmodified);
1059 applied = modifierApplied;
1069 [&](
const ObjectTy &
object) {
1070 auto maybeBase = helper.getBaseObject(
object);
1071 return maybeBase ? *maybeBase : object;
1075 if (!sharedObjects.
empty()) {
1076 if (dirParallel && !applyToParallel) {
1077 auto *shared = makeClause(
1078 llvm::omp::Clause::OMPC_shared,
1079 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1080 dirParallel->clauses.push_back(shared);
1082 if (dirTeams && !applyToTeams) {
1083 auto *shared = makeClause(
1084 llvm::omp::Clause::OMPC_shared,
1085 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});
1086 dirTeams->clauses.push_back(shared);
1091 auto dirTarget = findDirective(llvm::omp::Directive::OMPD_target);
1092 if (dirTarget && leafs.size() > 1) {
1095 [&](
const ObjectTy &
object) {
1096 if (
auto maybeBase = helper.getBaseObject(
object))
1097 return !mapBases.count(maybeBase->id());
1098 return !mapBases.count(
object.
id());
1100 if (!tofrom.
empty()) {
1102 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;
1103 auto *map = makeClause(
1104 llvm::omp::Clause::OMPC_map,
1105 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{
1106 {MapType::Tofrom, std::nullopt,
1107 std::nullopt, std::nullopt,
1108 std::nullopt, std::nullopt,
1109 std::move(tofrom)}});
1111 dirTarget->clauses.push_back(map);
1125template <
typename C,
typename H>
1126bool ConstructDecompositionT<C, H>::applyClause(
1127 const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &
clause,
1128 const ClauseTy *input) {
1130 if (!applyToAll(input))
1142template <
typename C,
typename H>
1143bool ConstructDecompositionT<C, H>::applyClause(
1144 const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &
clause,
1145 const ClauseTy *input) {
1147 if (!applyToAll(input))
1154template <
typename C,
typename H>
bool ConstructDecompositionT<C, H>::split() {
1158 leafs.push_back(LeafReprInternal{leaf, {}});
1160 for (
const ClauseTy *input : inputClauses)
1161 addClauseSymsToMap(*input, input);
1168 for (
const ClauseTy *input : inputClauses) {
1169 if (input->id == llvm::omp::Clause::OMPC_linear)
1172 for (
const auto *input : linears) {
1174 applyClause(std::get<tomp::clause::LinearT<TypeTy, IdTy, ExprTy>>(
1181 auto skip = [](
const ClauseTy *input) {
1182 switch (input->id) {
1183 case llvm::omp::Clause::OMPC_allocate:
1184 case llvm::omp::Clause::OMPC_linear:
1192 for (
const ClauseTy *input : inputClauses) {
1197 std::visit([&](
auto &&s) {
return applyClause(s, input); }, input->u);
1201 for (
const ClauseTy *input : inputClauses) {
1202 if (input->id != llvm::omp::Clause::OMPC_allocate)
1206 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(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.
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