@@ -25,6 +25,43 @@ using namespace llvm::omp;
25
25
#define GEN_DIRECTIVES_IMPL
26
26
#include " llvm/Frontend/OpenMP/OMP.inc"
27
27
28
+ static iterator_range<ArrayRef<Directive>::iterator>
29
+ getFirstCompositeRange (iterator_range<ArrayRef<Directive>::iterator> Leafs) {
30
+ // OpenMP Spec 5.2: [17.3, 8-9]
31
+ // If directive-name-A and directive-name-B both correspond to loop-
32
+ // associated constructs then directive-name is a composite construct
33
+ // otherwise directive-name is a combined construct.
34
+ //
35
+ // In the list of leaf constructs, find the first loop-associated construct,
36
+ // this is the beginning of the range. Then, starting from the immediately
37
+ // following leaf construct, find the first sequence of adjacent loop-
38
+ // -associated constructs. The last of those is the last one of the range.
39
+
40
+ auto firstLoopAssociated =
41
+ [](iterator_range<ArrayRef<Directive>::iterator> List) {
42
+ for (auto It = List.begin (), End = List.end (); It != End; ++It) {
43
+ if (getDirectiveAssociation (*It) == Association::Loop)
44
+ return It;
45
+ }
46
+ return List.end ();
47
+ };
48
+
49
+ auto Begin = firstLoopAssociated (Leafs);
50
+ if (Begin == Leafs.end ())
51
+ return llvm::make_range (Leafs.end (), Leafs.end ());
52
+
53
+ auto End =
54
+ firstLoopAssociated (llvm::make_range (std::next (Begin), Leafs.end ()));
55
+ if (End == Leafs.end ())
56
+ return llvm::make_range (Begin, std::next (Begin));
57
+
58
+ for (; End != Leafs.end (); ++End) {
59
+ if (getDirectiveAssociation (*End) != Association::Loop)
60
+ break ;
61
+ }
62
+ return llvm::make_range (Begin, End);
63
+ }
64
+
28
65
namespace llvm ::omp {
29
66
ArrayRef<Directive> getLeafConstructs (Directive D) {
30
67
auto Idx = static_cast <std::size_t >(D);
@@ -34,6 +71,40 @@ ArrayRef<Directive> getLeafConstructs(Directive D) {
34
71
return ArrayRef (&Row[2 ], &Row[2 ] + static_cast <int >(Row[1 ]));
35
72
}
36
73
74
+ ArrayRef<Directive> getLeafConstructsOrSelf (Directive D) {
75
+ if (auto Leafs = getLeafConstructs (D); !Leafs.empty ())
76
+ return Leafs;
77
+ auto Idx = static_cast <size_t >(D);
78
+ assert (Idx < Directive_enumSize && " Invalid directive" );
79
+ const auto *Row = LeafConstructTable[LeafConstructTableOrdering[Idx]];
80
+ // The first entry in the row is the directive itself.
81
+ return ArrayRef (&Row[0 ], &Row[0 ] + 1 );
82
+ }
83
+
84
+ ArrayRef<Directive>
85
+ getLeafOrCompositeConstructs (Directive D, SmallVectorImpl<Directive> &Output) {
86
+ using ArrayTy = ArrayRef<Directive>;
87
+ using IteratorTy = ArrayTy::iterator;
88
+ ArrayRef<Directive> Leafs = getLeafConstructsOrSelf (D);
89
+
90
+ IteratorTy Iter = Leafs.begin ();
91
+ do {
92
+ auto Range = getFirstCompositeRange (llvm::make_range (Iter, Leafs.end ()));
93
+ // All directives before the range are leaf constructs.
94
+ for (; Iter != Range.begin (); ++Iter)
95
+ Output.push_back (*Iter);
96
+ if (!Range.empty ()) {
97
+ Directive Comp =
98
+ getCompoundConstruct (ArrayTy (Range.begin (), Range.end ()));
99
+ assert (Comp != OMPD_unknown);
100
+ Output.push_back (Comp);
101
+ }
102
+ Iter = Range.end ();
103
+ } while (Iter != Leafs.end ());
104
+
105
+ return Output;
106
+ }
107
+
37
108
Directive getCompoundConstruct (ArrayRef<Directive> Parts) {
38
109
if (Parts.empty ())
39
110
return OMPD_unknown;
@@ -88,20 +159,11 @@ Directive getCompoundConstruct(ArrayRef<Directive> Parts) {
88
159
bool isLeafConstruct (Directive D) { return getLeafConstructs (D).empty (); }
89
160
90
161
bool isCompositeConstruct (Directive D) {
91
- // OpenMP Spec 5.2: [17.3, 8-9]
92
- // If directive-name-A and directive-name-B both correspond to loop-
93
- // associated constructs then directive-name is a composite construct
94
- llvm::ArrayRef<Directive> Leafs{getLeafConstructs (D)};
95
- if (Leafs.empty ())
96
- return false ;
97
- if (getDirectiveAssociation (Leafs.front ()) != Association::Loop)
162
+ ArrayRef<Directive> Leafs = getLeafConstructsOrSelf (D);
163
+ if (Leafs.size () <= 1 )
98
164
return false ;
99
-
100
- size_t numLoopConstructs =
101
- llvm::count_if (Leafs.drop_front (), [](Directive L) {
102
- return getDirectiveAssociation (L) == Association::Loop;
103
- });
104
- return numLoopConstructs != 0 ;
165
+ auto Range = getFirstCompositeRange (Leafs);
166
+ return Range.begin () == Leafs.begin () && Range.end () == Leafs.end ();
105
167
}
106
168
107
169
bool isCombinedConstruct (Directive D) {
0 commit comments