LLVM: include/llvm/Frontend/OpenMP/ConstructDecompositionT.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#ifndef LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H
19#define LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H
20
27
28#include
29#include
30#include
31#include
32#include <type_traits>
33#include <unordered_map>
34#include <unordered_set>
35#include
36#include
37
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,
43 };
44 return worksharing;
45}
46
48 static llvm::omp::Directive worksharingLoop[] = {
49 llvm::omp::Directive::OMPD_do,
50 llvm::omp::Directive::OMPD_for,
51 };
52 return worksharingLoop;
53}
54
56template <typename Container, typename Predicate>
57typename std::remove_reference_t::iterator
59 auto first = std::find_if(container.begin(), container.end(), pred);
60 if (first == container.end())
61 return first;
62 auto second = std::find_if(std::next(first), container.end(), pred);
63 if (second == container.end())
64 return first;
65 return container.end();
66}
67}
68
69namespace tomp {
70
71
72
73
74
75
76
77
78
79
80
81
82template <typename ClauseType, typename HelperType>
85
86 using TypeTy = typename ClauseTy::TypeTy;
87 using IdTy = typename ClauseTy::IdTy;
88 using ExprTy = typename ClauseTy::ExprTy;
91
92 using ClauseSet = std::unordered_set<const ClauseTy *>;
93
95 llvm::omp::Directive dir,
97 : version(ver), construct(dir), helper(helper) {
99 nodes.push_back(&clause);
100
101 bool success = split();
102 if (!success)
103 return;
104
105
106
107
108
109 for (auto &leaf : leafs) {
110 output.push_back({leaf.id, {}});
111 auto &out = output.back();
112 for (const ClauseTy *c : leaf.clauses)
113 out.clauses.push_back(*c);
114 }
115 }
116
118
119private:
120 bool split();
121
122 struct LeafReprInternal {
123 llvm::omp::Directive id = llvm::omp::Directive::OMPD_unknown;
125 };
126
127 LeafReprInternal *findDirective(llvm::omp::Directive dirId) {
129 leafs, [&](const LeafReprInternal &leaf) { return leaf.id == dirId; });
130 return found != leafs.end() ? &*found : nullptr;
131 }
132
134 if (auto found = syms.find(object.id()); found != syms.end())
135 return &found->second;
136 return nullptr;
137 }
138
139 template
140 ClauseTy *makeClause(llvm::omp::Clause clauseId, S &&specific) {
141 implicit.push_back(typename ClauseTy::BaseT{clauseId, std::move(specific)});
142 return &implicit.back();
143 }
144
145 void addClauseSymsToMap(const ObjectTy &object, const ClauseTy *);
148 void addClauseSymsToMap(const TypeTy &item, const ClauseTy *);
149 void addClauseSymsToMap(const ExprTy &item, const ClauseTy *);
152
153 template
154 void addClauseSymsToMap(const std::optional &item, const ClauseTy *);
155 template
157 template <typename... U, size_t... Is>
158 void addClauseSymsToMap(const std::tuple<U...> &item, const ClauseTy *,
159 std::index_sequence<Is...> = {});
160 template
161 std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t>, void>
162 addClauseSymsToMap(U &&item, const ClauseTy *);
163
164 template
165 std::enable_if_t<llvm::remove_cvref_t::EmptyTrait::value, void>
166 addClauseSymsToMap(U &&item, const ClauseTy *);
167
168 template
169 std::enable_if_t<llvm::remove_cvref_t::IncompleteTrait::value, void>
170 addClauseSymsToMap(U &&item, const ClauseTy *);
171
172 template
173 std::enable_if_t<llvm::remove_cvref_t::WrapperTrait::value, void>
174 addClauseSymsToMap(U &&item, const ClauseTy *);
175
176 template
177 std::enable_if_t<llvm::remove_cvref_t::TupleTrait::value, void>
178 addClauseSymsToMap(U &&item, const ClauseTy *);
179
180 template
181 std::enable_if_t<llvm::remove_cvref_t::UnionTrait::value, void>
182 addClauseSymsToMap(U &&item, const ClauseTy *);
183
184
185
186
187 bool applyToUnique(const ClauseTy *node);
188
189
190
191 template
193
194
195
196 bool applyToInnermost(const ClauseTy *node);
197
198
199
200 bool applyToOutermost(const ClauseTy *node);
201
202 template
204
205 bool applyToAll(const ClauseTy *node);
206
207 template
208 bool applyClause(Clause &&clause, const ClauseTy *node);
209
214 bool
217 bool
224 bool
239 bool
244
246 llvm::omp::Directive construct;
247 HelperType &helper;
248 ListT leafs;
250 std::list implicit;
251
252 std::unordered_map<IdTy, ClauseSet> syms;
253 std::unordered_set mapBases;
254};
255
256
257template <typename ClauseType, typename HelperType>
261
262template <typename C, typename H>
264 const ClauseTy *node) {
265 syms[object.id()].insert(node);
266}
267
268template <typename C, typename H>
269void ConstructDecompositionT<C, H>::addClauseSymsToMap(
271 for (auto &object : objects)
272 syms[object.id()].insert(node);
273}
274
275template <typename C, typename H>
276void ConstructDecompositionT<C, H>::addClauseSymsToMap(const TypeTy &item,
277 const ClauseTy *node) {
278
279}
280
281template <typename C, typename H>
282void ConstructDecompositionT<C, H>::addClauseSymsToMap(const ExprTy &item,
283 const ClauseTy *node) {
284
285}
286
287template <typename C, typename H>
288void ConstructDecompositionT<C, H>::addClauseSymsToMap(
290 const ClauseTy *node) {
291 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(item.t);
292 addClauseSymsToMap(objects, node);
293 for (auto &object : objects) {
294 if (auto base = helper.getBaseObject(object))
295 mapBases.insert(base->id());
296 }
297}
298
299template <typename C, typename H>
300template
301void ConstructDecompositionT<C, H>::addClauseSymsToMap(
302 const std::optional &item, const ClauseTy *node) {
303 if (item)
304 addClauseSymsToMap(*item, node);
305}
306
307template <typename C, typename H>
308template
309void ConstructDecompositionT<C, H>::addClauseSymsToMap(
311 for (auto &s : item)
312 addClauseSymsToMap(s, node);
313}
314
315template <typename C, typename H>
316template <typename... U, size_t... Is>
317void ConstructDecompositionT<C, H>::addClauseSymsToMap(
318 const std::tuple<U...> &item, const ClauseTy *node,
319 std::index_sequence<Is...>) {
320 (void)node;
321 (addClauseSymsToMap(std::get(item), node), ...);
322}
323
324template <typename C, typename H>
325template
326std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t>, void>
327ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
328 const ClauseTy *node) {
329
330}
331
332template <typename C, typename H>
333template
334std::enable_if_t<llvm::remove_cvref_t::EmptyTrait::value, void>
335ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
336 const ClauseTy *node) {
337
338}
339
340template <typename C, typename H>
341template
342std::enable_if_t<llvm::remove_cvref_t::IncompleteTrait::value, void>
343ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
344 const ClauseTy *node) {
345
346}
347
348template <typename C, typename H>
349template
350std::enable_if_t<llvm::remove_cvref_t::WrapperTrait::value, void>
351ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
352 const ClauseTy *node) {
353 addClauseSymsToMap(item.v, node);
354}
355
356template <typename C, typename H>
357template
358std::enable_if_t<llvm::remove_cvref_t::TupleTrait::value, void>
359ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
360 const ClauseTy *node) {
361 constexpr size_t tuple_size =
363 addClauseSymsToMap(item.t, node, std::make_index_sequence<tuple_size>{});
364}
365
366template <typename C, typename H>
367template
368std::enable_if_t<llvm::remove_cvref_t::UnionTrait::value, void>
369ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
370 const ClauseTy *node) {
371 std::visit([&](auto &&s) { addClauseSymsToMap(s, node); }, item.u);
372}
373
374
375
376
377template <typename C, typename H>
378bool ConstructDecompositionT<C, H>::applyToUnique(const ClauseTy *node) {
380 return llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version);
381 });
382
383 if (unique != leafs.end()) {
384 unique->clauses.push_back(node);
385 return true;
386 }
387 return false;
388}
389
390
391
392template <typename C, typename H>
393template
394bool ConstructDecompositionT<C, H>::applyToFirst(
396 if (range.empty())
397 return false;
398
399 for (auto &leaf : range) {
400 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
401 continue;
402 leaf.clauses.push_back(node);
403 return true;
404 }
405 return false;
406}
407
408
409
410template <typename C, typename H>
411bool ConstructDecompositionT<C, H>::applyToInnermost(const ClauseTy *node) {
413}
414
415
416
417template <typename C, typename H>
418bool ConstructDecompositionT<C, H>::applyToOutermost(const ClauseTy *node) {
420}
421
422template <typename C, typename H>
423template
424bool ConstructDecompositionT<C, H>::applyIf(const ClauseTy *node,
426 bool applied = false;
427 for (auto &leaf : leafs) {
428 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
429 continue;
431 continue;
432 leaf.clauses.push_back(node);
433 applied = true;
434 }
435
436 return applied;
437}
438
439template <typename C, typename H>
440bool ConstructDecompositionT<C, H>::applyToAll(const ClauseTy *node) {
441 return applyIf(node, [](auto) { return true; });
442}
443
444template <typename C, typename H>
445template
448
449
450
451
452
453
454
455 if (applyToUnique(node))
456 return true;
457
458 return false;
459}
460
461
462
463
464
465
466
467
468template <typename C, typename H>
471 const ClauseTy *node) {
472
473
474 if (!leafs.empty()) {
475 auto &last = leafs.back();
476
477 if (llvm::omp::isAllowedClauseForDirective(last.id, node->id, version)) {
478 last.clauses.push_back(node);
479 return true;
480 }
481 }
482
483 return false;
484}
485
486
487
488
489
490
491
492
493
494template <typename C, typename H>
495bool ConstructDecompositionT<C, H>::applyClause(
497 const ClauseTy *node) {
498 return applyToInnermost(node);
499}
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531template <typename C, typename H>
532bool ConstructDecompositionT<C, H>::applyClause(
534 const ClauseTy *node) {
535 bool applied = false;
536
537
538 auto dirDistribute = findDirective(llvm::omp::OMPD_distribute);
539 auto dirTeams = findDirective(llvm::omp::OMPD_teams);
540 if (dirDistribute != nullptr) {
541 dirDistribute->clauses.push_back(node);
542 applied = true;
543
544 if (dirTeams != nullptr) {
545 auto *shared = makeClause(
546 llvm::omp::Clause::OMPC_shared,
548 dirTeams->clauses.push_back(shared);
549 }
550 } else if (dirTeams != nullptr) {
551 dirTeams->clauses.push_back(node);
552 applied = true;
553 }
554
555
556 auto findWorksharing = [&]() {
558 for (auto &leaf : leafs) {
559 auto found = llvm::find(worksharing, leaf.id);
560 if (found != std::end(worksharing))
561 return &leaf;
562 }
563 return static_cast<typename decltype(leafs)::value_type *>(nullptr);
564 };
565
566 auto dirWorksharing = findWorksharing();
567 if (dirWorksharing != nullptr) {
568 dirWorksharing->clauses.push_back(node);
569 applied = true;
570 }
571
572
573 auto dirTaskloop = findDirective(llvm::omp::OMPD_taskloop);
574 if (dirTaskloop != nullptr) {
575 dirTaskloop->clauses.push_back(node);
576 applied = true;
577 }
578
579
580 auto dirParallel = findDirective(llvm::omp::OMPD_parallel);
581 if (dirParallel != nullptr) {
582 if (dirTaskloop == nullptr && dirWorksharing == nullptr) {
583 dirParallel->clauses.push_back(node);
584 applied = true;
585 } else {
586
587 auto *shared = makeClause(
588 llvm::omp::Clause::OMPC_shared,
590 dirParallel->clauses.push_back(shared);
591 }
592 }
593
594
595 auto inLastprivate = [&](const ObjectTy &object) {
596 if (ClauseSet *set = findClausesWith(object)) {
597 return llvm::find_if(*set, [](const ClauseTy *c) {
598 return c->id == llvm::omp::Clause::OMPC_lastprivate;
599 }) != set->end();
600 }
601 return false;
602 };
603
604 auto dirTarget = findDirective(llvm::omp::OMPD_target);
605 if (dirTarget != nullptr) {
608 clause.v, std::back_inserter(objects), [&](const ObjectTy &object) {
609 return !inLastprivate(object) && !mapBases.count(object.id());
610 });
611 if (!objects.empty()) {
612 auto *firstp = makeClause(
613 llvm::omp::Clause::OMPC_firstprivate,
615 dirTarget->clauses.push_back(firstp);
616 applied = true;
617 }
618 }
619
620
621 if (auto dirTask = findDirective(llvm::omp::OMPD_task)) {
622 dirTask->clauses.push_back(node);
623 applied = true;
624 }
625
626 return applied;
627}
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648template <typename C, typename H>
649bool ConstructDecompositionT<C, H>::applyClause(
651 const ClauseTy *node) {
652 bool applied = false;
653
654
655 applied = applyToAll(node);
656 if (!applied)
657 return false;
658
659 auto inFirstprivate = [&](const ObjectTy &object) {
660 if (ClauseSet *set = findClausesWith(object)) {
661 return llvm::find_if(*set, [](const ClauseTy *c) {
662 return c->id == llvm::omp::Clause::OMPC_firstprivate;
663 }) != set->end();
664 }
665 return false;
666 };
667
668 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(clause.t);
669
670
673 objects, std::back_inserter(sharedObjects),
674 [&](const ObjectTy &object) { return !inFirstprivate(object); });
675
676 if (!sharedObjects.empty()) {
677
678 if (auto dirParallel = findDirective(llvm::omp::OMPD_parallel)) {
679 auto *shared = makeClause(
680 llvm::omp::Clause::OMPC_shared,
682 dirParallel->clauses.push_back(shared);
683 applied = true;
684 }
685
686
687 if (auto dirTeams = findDirective(llvm::omp::OMPD_teams)) {
688 auto *shared = makeClause(
689 llvm::omp::Clause::OMPC_shared,
691 dirTeams->clauses.push_back(shared);
692 applied = true;
693 }
694 }
695
696
697 if (auto dirTarget = findDirective(llvm::omp::OMPD_target)) {
700 objects, std::back_inserter(tofrom),
701 [&](const ObjectTy &object) { return !mapBases.count(object.id()); });
702
703 if (!tofrom.empty()) {
704 using MapType =
706 auto *map =
707 makeClause(llvm::omp::Clause::OMPC_map,
709 {MapType::Tofrom,
710 std::nullopt,
711 std::nullopt, std::nullopt,
712 std::move(tofrom)}});
713 dirTarget->clauses.push_back(map);
714 applied = true;
715 }
716 }
717
718 return applied;
719}
720
721
722
723
724
725
726
727
728template <typename C, typename H>
729bool ConstructDecompositionT<C, H>::applyClause(
731 const ClauseTy *node) {
732
733 return applyToAll(node);
734}
735
736
737
738
739
740
741
742
743template <typename C, typename H>
744bool ConstructDecompositionT<C, H>::applyClause(
746 const ClauseTy *node) {
747
748 return applyToAll(node);
749}
750
751
752
753
754
755
756
757
758template <typename C, typename H>
759bool ConstructDecompositionT<C, H>::applyClause(
761 const ClauseTy *node) {
762
763 return applyToAll(node);
764}
765
766
767
768
769
770
771
772
773template <typename C, typename H>
774bool ConstructDecompositionT<C, H>::applyClause(
776 const ClauseTy *node) {
777
778 return applyToAll(node);
779}
780
781
782
783
784
785
786
787
788
789
790template <typename C, typename H>
791bool ConstructDecompositionT<C, H>::applyClause(
793 const ClauseTy *node) {
794
795
796
797
798 auto canMakePrivateCopy = [](llvm::omp::Clause id) {
799 switch (id) {
800
801 case llvm::omp::Clause::OMPC_firstprivate:
802 case llvm::omp::Clause::OMPC_in_reduction:
803 case llvm::omp::Clause::OMPC_lastprivate:
804 case llvm::omp::Clause::OMPC_linear:
805 case llvm::omp::Clause::OMPC_private:
806 case llvm::omp::Clause::OMPC_reduction:
807 case llvm::omp::Clause::OMPC_task_reduction:
808 return true;
809 default:
810 return false;
811 }
812 };
813
814 bool applied = applyIf(node, [&](const auto &leaf) {
815 return llvm::any_of(leaf.clauses, [&](const ClauseTy *n) {
816 return canMakePrivateCopy(n->id);
817 });
818 });
819
820 return applied;
821}
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849template <typename C, typename H>
850bool ConstructDecompositionT<C, H>::applyClause(
852 const ClauseTy *node) {
854
855
856 bool applyToParallel = true, applyToTeams = true;
857
858 auto dirParallel = findDirective(llvm::omp::Directive::OMPD_parallel);
859 if (dirParallel) {
860 auto exclusions = llvm::concat(
862 llvm::omp::Directive::OMPD_loop,
863 llvm::omp::Directive::OMPD_sections,
864 llvm::omp::Directive::OMPD_taskloop,
865 });
866 auto present = [&](llvm::omp::Directive id) {
867 return findDirective(id) != nullptr;
868 };
869
871 applyToParallel = false;
872 }
873
874 auto dirTeams = findDirective(llvm::omp::Directive::OMPD_teams);
875 if (dirTeams) {
876
877 if (findDirective(llvm::omp::Directive::OMPD_loop))
878 applyToTeams = false;
879 }
880
881 using ReductionModifier = typename ReductionTy::ReductionModifier;
882 using ReductionIdentifiers = typename ReductionTy::ReductionIdentifiers;
883
884 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(clause.t);
885 auto &modifier = std::get<std::optional>(clause.t);
886
887
888
889
890 bool applied = false;
891
892
893 auto isValidModifier = [](llvm::omp::Directive dir, ReductionModifier mod,
894 bool alreadyApplied) {
895 switch (mod) {
896 case ReductionModifier::Inscan:
897
898
899 return dir == llvm::omp::Directive::OMPD_simd ||
901 case ReductionModifier::Task:
902 if (alreadyApplied)
903 return false;
904
905
906 return dir == llvm::omp::Directive::OMPD_parallel ||
908 case ReductionModifier::Default:
909 return true;
910 }
912 };
913
914 auto *unmodified = makeClause(
915 llvm::omp::Clause::OMPC_reduction,
916 ReductionTy{
917 {std::nullopt,
918 std::get(clause.t),
919 objects}});
920
921 ReductionModifier effective = modifier.value_or(ReductionModifier::Default);
922 bool effectiveApplied = false;
923
924
926 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))
927 continue;
928 if (!applyToParallel && &leaf == dirParallel)
929 continue;
930 if (!applyToTeams && &leaf == dirTeams)
931 continue;
932
933 if (isValidModifier(leaf.id, effective, effectiveApplied)) {
934
935 leaf.clauses.push_back(node);
936 effectiveApplied = true;
937 } else {
938
939 leaf.clauses.push_back(unmodified);
940 }
941
942 applied = effectiveApplied;
943 }
944
945 if (!applied)
946 return false;
947
949 llvm::transform(objects, std::back_inserter(sharedObjects),
950 [&](const ObjectTy &object) {
951 auto maybeBase = helper.getBaseObject(object);
952 return maybeBase ? *maybeBase : object;
953 });
954
955
956 if (!sharedObjects.empty()) {
957 if (dirParallel && !applyToParallel) {
958 auto *shared = makeClause(
959 llvm::omp::Clause::OMPC_shared,
961 dirParallel->clauses.push_back(shared);
962 }
963 if (dirTeams && !applyToTeams) {
964 auto *shared = makeClause(
965 llvm::omp::Clause::OMPC_shared,
967 dirTeams->clauses.push_back(shared);
968 }
969 }
970
971
972 auto dirTarget = findDirective(llvm::omp::Directive::OMPD_target);
973 if (dirTarget && leafs.size() > 1) {
975 llvm::copy_if(objects, std::back_inserter(tofrom),
976 [&](const ObjectTy &object) {
977 if (auto maybeBase = helper.getBaseObject(object))
978 return !mapBases.count(maybeBase->id());
979 return !mapBases.count(object.id());
980 });
981 if (!tofrom.empty()) {
982 using MapType =
984 auto *map = makeClause(
985 llvm::omp::Clause::OMPC_map,
987 {MapType::Tofrom, std::nullopt,
988 std::nullopt, std::nullopt,
989 std::move(tofrom)}});
990
991 dirTarget->clauses.push_back(map);
992 applied = true;
993 }
994 }
995
996 return applied;
997}
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010template <typename C, typename H>
1011bool ConstructDecompositionT<C, H>::applyClause(
1013 const ClauseTy *node) {
1014 using DirectiveNameModifier =
1017 auto &modifier = std::get<std::optional>(clause.t);
1018
1019 if (modifier) {
1020 llvm::omp::Directive dirId = *modifier;
1021 auto *unmodified =
1022 makeClause(llvm::omp::Clause::OMPC_if,
1024 {std::nullopt,
1025 std::get(clause.t)}});
1026
1027 if (auto *hasDir = findDirective(dirId)) {
1028 hasDir->clauses.push_back(unmodified);
1029 return true;
1030 }
1031 return false;
1032 }
1033
1034 return applyToAll(node);
1035}
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054template <typename C, typename H>
1055bool ConstructDecompositionT<C, H>::applyClause(
1057 const ClauseTy *node) {
1058
1059 if (!applyToInnermost(node))
1060 return false;
1061
1062
1063 auto dirSimd = findDirective(llvm::omp::Directive::OMPD_simd);
1064 std::optional iterVar = helper.getLoopIterVar();
1065 const auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(clause.t);
1066
1067
1068
1070
1071 for (const ObjectTy &object : objects) {
1072 last.push_back(object);
1073 if (!dirSimd || !iterVar || object.id() != iterVar->id())
1074 first.push_back(object);
1075 }
1076
1077 if (!first.empty()) {
1078 auto *firstp = makeClause(
1079 llvm::omp::Clause::OMPC_firstprivate,
1081 nodes.push_back(firstp);
1082 }
1083 if (.empty()) {
1084 auto *lastp =
1085 makeClause(llvm::omp::Clause::OMPC_lastprivate,
1087 {std::nullopt, last}});
1088 nodes.push_back(lastp);
1089 }
1090 return true;
1091}
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101template <typename C, typename H>
1102bool ConstructDecompositionT<C, H>::applyClause(
1104 const ClauseTy *node) {
1105 return applyToOutermost(node);
1106}
1107
1108template <typename C, typename H>
1109bool ConstructDecompositionT<C, H>::applyClause(
1111 const ClauseTy *node) {
1112 return applyToOutermost(node);
1113}
1114
1115template <typename C, typename H>
1116bool ConstructDecompositionT<C, H>::applyClause(
1118 const ClauseTy *node) {
1119 return applyToAll(node);
1120}
1121
1122template <typename C, typename H> bool ConstructDecompositionT<C, H>::split() {
1124
1125 auto isImplicit = [this](const ClauseTy *node) {
1127 implicit, [node](const ClauseTy &clause) { return &clause == node; });
1128 };
1129
1130 for (llvm::omp::Directive leaf :
1132 leafs.push_back(LeafReprInternal{leaf, {}});
1133
1134 for (const ClauseTy *node : nodes)
1135 addClauseSymsToMap(*node, node);
1136
1137
1138
1139
1140
1142 for (const ClauseTy *node : nodes) {
1143 if (node->id == llvm::omp::Clause::OMPC_linear)
1145 }
1146 for (const auto *node : linears) {
1149 node->u),
1150 node);
1151 }
1152
1153
1154
1155 auto skip = [](const ClauseTy *node) {
1156 switch (node->id) {
1157 case llvm::omp::Clause::OMPC_allocate:
1158 case llvm::omp::Clause::OMPC_linear:
1159 return true;
1160 default:
1161 return false;
1162 }
1163 };
1164
1165
1166 for (const ClauseTy *node : nodes) {
1167 if (skip(node))
1168 continue;
1169 bool result =
1170 std::visit([&](auto &&s) { return applyClause(s, node); }, node->u);
1171 if (!isImplicit(node))
1172 success = success && result;
1173 }
1174
1175
1176 for (const ClauseTy *node : nodes) {
1177 if (node->id != llvm::omp::Clause::OMPC_allocate)
1178 continue;
1181 std::visit([&](auto &&s) { return applyClause(s, node); }, node->u);
1182 }
1183
1185}
1186
1187}
1188
1189#endif
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)
A range adaptor for a pair of iterators.
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)
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.
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)
typename llvm::remove_cvref< T >::type remove_cvref_t
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.
typename ClauseTy::ExprTy ExprTy
std::unordered_set< const ClauseTy * > ClauseSet
typename ClauseTy::TypeTy TypeTy
typename ClauseTy::IdTy IdTy
tomp::ObjectT< IdTy, ExprTy > ObjectTy
ConstructDecompositionT(uint32_t ver, HelperType &helper, llvm::omp::Directive dir, llvm::ArrayRef< ClauseTy > clauses)
tomp::ListT< DirectiveWithClauses< ClauseType > > output
std::tuple< OPT(DirectiveNameModifier), IfExpression > t
type::DirectiveName DirectiveNameModifier
std::tuple< OPT(LastprivateModifier), List > t
std::tuple< OPT(StepComplexModifier), OPT(LinearModifier), List > t
std::tuple< OPT(MapType), OPT(MapTypeModifiers), OPT(Mappers), OPT(Iterator), LocatorList > t
std::tuple< OPT(ReductionModifier), ReductionIdentifiers, List > t