Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | /// \file |
||
9 | /// This file defines OpenMP AST classes for executable directives and |
||
10 | /// clauses. |
||
11 | /// |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef LLVM_CLANG_AST_STMTOPENMP_H |
||
15 | #define LLVM_CLANG_AST_STMTOPENMP_H |
||
16 | |||
17 | #include "clang/AST/ASTContext.h" |
||
18 | #include "clang/AST/Expr.h" |
||
19 | #include "clang/AST/OpenMPClause.h" |
||
20 | #include "clang/AST/Stmt.h" |
||
21 | #include "clang/AST/StmtCXX.h" |
||
22 | #include "clang/Basic/OpenMPKinds.h" |
||
23 | #include "clang/Basic/SourceLocation.h" |
||
24 | |||
25 | namespace clang { |
||
26 | |||
27 | //===----------------------------------------------------------------------===// |
||
28 | // AST classes for directives. |
||
29 | //===----------------------------------------------------------------------===// |
||
30 | |||
31 | /// Representation of an OpenMP canonical loop. |
||
32 | /// |
||
33 | /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape |
||
34 | /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape |
||
35 | /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form |
||
36 | /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form |
||
37 | /// OpenMP 4.0, section 2.6 Canonical Loop Form |
||
38 | /// OpenMP 4.5, section 2.6 Canonical Loop Form |
||
39 | /// OpenMP 5.0, section 2.9.1 Canonical Loop Form |
||
40 | /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form |
||
41 | /// |
||
42 | /// An OpenMP canonical loop is a for-statement or range-based for-statement |
||
43 | /// with additional requirements that ensure that the number of iterations is |
||
44 | /// known before entering the loop and allow skipping to an arbitrary iteration. |
||
45 | /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is |
||
46 | /// known to fulfill OpenMP's canonical loop requirements because of being |
||
47 | /// associated to an OMPLoopBasedDirective. That is, the general structure is: |
||
48 | /// |
||
49 | /// OMPLoopBasedDirective |
||
50 | /// [`- CapturedStmt ] |
||
51 | /// [ `- CapturedDecl] |
||
52 | /// ` OMPCanonicalLoop |
||
53 | /// `- ForStmt/CXXForRangeStmt |
||
54 | /// `- Stmt |
||
55 | /// |
||
56 | /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some |
||
57 | /// directives such as OMPParallelForDirective, but others do not need them |
||
58 | /// (such as OMPTileDirective). In The OMPCanonicalLoop and |
||
59 | /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the |
||
60 | /// directive. A OMPCanonicalLoop must not appear in the AST unless associated |
||
61 | /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the |
||
62 | /// OMPCanonicalLoop may also be wrapped in a CompoundStmt: |
||
63 | /// |
||
64 | /// [...] |
||
65 | /// ` OMPCanonicalLoop |
||
66 | /// `- ForStmt/CXXForRangeStmt |
||
67 | /// `- CompoundStmt |
||
68 | /// |- Leading in-between code (if any) |
||
69 | /// |- OMPCanonicalLoop |
||
70 | /// | `- ForStmt/CXXForRangeStmt |
||
71 | /// | `- ... |
||
72 | /// `- Trailing in-between code (if any) |
||
73 | /// |
||
74 | /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop |
||
75 | /// to avoid confusion which loop belongs to the nesting. |
||
76 | /// |
||
77 | /// There are three different kinds of iteration variables for different |
||
78 | /// purposes: |
||
79 | /// * Loop user variable: The user-accessible variable with different value for |
||
80 | /// each iteration. |
||
81 | /// * Loop iteration variable: The variable used to identify a loop iteration; |
||
82 | /// for range-based for-statement, this is the hidden iterator '__begin'. For |
||
83 | /// other loops, it is identical to the loop user variable. Must be a |
||
84 | /// random-access iterator, pointer or integer type. |
||
85 | /// * Logical iteration counter: Normalized loop counter starting at 0 and |
||
86 | /// incrementing by one at each iteration. Allows abstracting over the type |
||
87 | /// of the loop iteration variable and is always an unsigned integer type |
||
88 | /// appropriate to represent the range of the loop iteration variable. Its |
||
89 | /// value corresponds to the logical iteration number in the OpenMP |
||
90 | /// specification. |
||
91 | /// |
||
92 | /// This AST node provides two captured statements: |
||
93 | /// * The distance function which computes the number of iterations. |
||
94 | /// * The loop user variable function that computes the loop user variable when |
||
95 | /// given a logical iteration number. |
||
96 | /// |
||
97 | /// These captured statements provide the link between C/C++ semantics and the |
||
98 | /// logical iteration counters used by the OpenMPIRBuilder which is |
||
99 | /// language-agnostic and therefore does not know e.g. how to advance a |
||
100 | /// random-access iterator. The OpenMPIRBuilder will use this information to |
||
101 | /// apply simd, workshare-loop, distribute, taskloop and loop directives to the |
||
102 | /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an |
||
103 | /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an |
||
104 | /// OMPLoopDirective and skipped when searching for the associated syntactical |
||
105 | /// loop. |
||
106 | /// |
||
107 | /// Example: |
||
108 | /// <code> |
||
109 | /// std::vector<std::string> Container{1,2,3}; |
||
110 | /// for (std::string Str : Container) |
||
111 | /// Body(Str); |
||
112 | /// </code> |
||
113 | /// which is syntactic sugar for approximately: |
||
114 | /// <code> |
||
115 | /// auto &&__range = Container; |
||
116 | /// auto __begin = std::begin(__range); |
||
117 | /// auto __end = std::end(__range); |
||
118 | /// for (; __begin != __end; ++__begin) { |
||
119 | /// std::String Str = *__begin; |
||
120 | /// Body(Str); |
||
121 | /// } |
||
122 | /// </code> |
||
123 | /// In this example, the loop user variable is `Str`, the loop iteration |
||
124 | /// variable is `__begin` of type `std::vector<std::string>::iterator` and the |
||
125 | /// logical iteration number type is `size_t` (unsigned version of |
||
126 | /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`). |
||
127 | /// Therefore, the distance function will be |
||
128 | /// <code> |
||
129 | /// [&](size_t &Result) { Result = __end - __begin; } |
||
130 | /// </code> |
||
131 | /// and the loop variable function is |
||
132 | /// <code> |
||
133 | /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) { |
||
134 | /// Result = __begin + Logical; |
||
135 | /// } |
||
136 | /// </code> |
||
137 | /// The variable `__begin`, aka the loop iteration variable, is captured by |
||
138 | /// value because it is modified in the loop body, but both functions require |
||
139 | /// the initial value. The OpenMP specification explicitly leaves unspecified |
||
140 | /// when the loop expressions are evaluated such that a capture by reference is |
||
141 | /// sufficient. |
||
142 | class OMPCanonicalLoop : public Stmt { |
||
143 | friend class ASTStmtReader; |
||
144 | friend class ASTStmtWriter; |
||
145 | |||
146 | /// Children of this AST node. |
||
147 | enum { |
||
148 | LOOP_STMT, |
||
149 | DISTANCE_FUNC, |
||
150 | LOOPVAR_FUNC, |
||
151 | LOOPVAR_REF, |
||
152 | LastSubStmt = LOOPVAR_REF |
||
153 | }; |
||
154 | |||
155 | private: |
||
156 | /// This AST node's children. |
||
157 | Stmt *SubStmts[LastSubStmt + 1] = {}; |
||
158 | |||
159 | OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {} |
||
160 | |||
161 | public: |
||
162 | /// Create a new OMPCanonicalLoop. |
||
163 | static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt, |
||
164 | CapturedStmt *DistanceFunc, |
||
165 | CapturedStmt *LoopVarFunc, |
||
166 | DeclRefExpr *LoopVarRef) { |
||
167 | OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop(); |
||
168 | S->setLoopStmt(LoopStmt); |
||
169 | S->setDistanceFunc(DistanceFunc); |
||
170 | S->setLoopVarFunc(LoopVarFunc); |
||
171 | S->setLoopVarRef(LoopVarRef); |
||
172 | return S; |
||
173 | } |
||
174 | |||
175 | /// Create an empty OMPCanonicalLoop for deserialization. |
||
176 | static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) { |
||
177 | return new (Ctx) OMPCanonicalLoop(); |
||
178 | } |
||
179 | |||
180 | static bool classof(const Stmt *S) { |
||
181 | return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass; |
||
182 | } |
||
183 | |||
184 | SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); } |
||
185 | SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); } |
||
186 | |||
187 | /// Return this AST node's children. |
||
188 | /// @{ |
||
189 | child_range children() { |
||
190 | return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); |
||
191 | } |
||
192 | const_child_range children() const { |
||
193 | return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); |
||
194 | } |
||
195 | /// @} |
||
196 | |||
197 | /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt). |
||
198 | /// @{ |
||
199 | Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; } |
||
200 | const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; } |
||
201 | void setLoopStmt(Stmt *S) { |
||
202 | assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) && |
||
203 | "Canonical loop must be a for loop (range-based or otherwise)"); |
||
204 | SubStmts[LOOP_STMT] = S; |
||
205 | } |
||
206 | /// @} |
||
207 | |||
208 | /// The function that computes the number of loop iterations. Can be evaluated |
||
209 | /// before entering the loop but after the syntactical loop's init |
||
210 | /// statement(s). |
||
211 | /// |
||
212 | /// Function signature: void(LogicalTy &Result) |
||
213 | /// Any values necessary to compute the distance are captures of the closure. |
||
214 | /// @{ |
||
215 | CapturedStmt *getDistanceFunc() { |
||
216 | return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); |
||
217 | } |
||
218 | const CapturedStmt *getDistanceFunc() const { |
||
219 | return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); |
||
220 | } |
||
221 | void setDistanceFunc(CapturedStmt *S) { |
||
222 | assert(S && "Expected non-null captured statement"); |
||
223 | SubStmts[DISTANCE_FUNC] = S; |
||
224 | } |
||
225 | /// @} |
||
226 | |||
227 | /// The function that computes the loop user variable from a logical iteration |
||
228 | /// counter. Can be evaluated as first statement in the loop. |
||
229 | /// |
||
230 | /// Function signature: void(LoopVarTy &Result, LogicalTy Number) |
||
231 | /// Any other values required to compute the loop user variable (such as start |
||
232 | /// value, step size) are captured by the closure. In particular, the initial |
||
233 | /// value of loop iteration variable is captured by value to be unaffected by |
||
234 | /// previous iterations. |
||
235 | /// @{ |
||
236 | CapturedStmt *getLoopVarFunc() { |
||
237 | return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); |
||
238 | } |
||
239 | const CapturedStmt *getLoopVarFunc() const { |
||
240 | return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); |
||
241 | } |
||
242 | void setLoopVarFunc(CapturedStmt *S) { |
||
243 | assert(S && "Expected non-null captured statement"); |
||
244 | SubStmts[LOOPVAR_FUNC] = S; |
||
245 | } |
||
246 | /// @} |
||
247 | |||
248 | /// Reference to the loop user variable as accessed in the loop body. |
||
249 | /// @{ |
||
250 | DeclRefExpr *getLoopVarRef() { |
||
251 | return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); |
||
252 | } |
||
253 | const DeclRefExpr *getLoopVarRef() const { |
||
254 | return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); |
||
255 | } |
||
256 | void setLoopVarRef(DeclRefExpr *E) { |
||
257 | assert(E && "Expected non-null loop variable"); |
||
258 | SubStmts[LOOPVAR_REF] = E; |
||
259 | } |
||
260 | /// @} |
||
261 | }; |
||
262 | |||
263 | /// This is a basic class for representing single OpenMP executable |
||
264 | /// directive. |
||
265 | /// |
||
266 | class OMPExecutableDirective : public Stmt { |
||
267 | friend class ASTStmtReader; |
||
268 | friend class ASTStmtWriter; |
||
269 | |||
270 | /// Kind of the directive. |
||
271 | OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; |
||
272 | /// Starting location of the directive (directive keyword). |
||
273 | SourceLocation StartLoc; |
||
274 | /// Ending location of the directive. |
||
275 | SourceLocation EndLoc; |
||
276 | |||
277 | /// Get the clauses storage. |
||
278 | MutableArrayRef<OMPClause *> getClauses() { |
||
279 | if (!Data) |
||
280 | return std::nullopt; |
||
281 | return Data->getClauses(); |
||
282 | } |
||
283 | |||
284 | protected: |
||
285 | /// Data, associated with the directive. |
||
286 | OMPChildren *Data = nullptr; |
||
287 | |||
288 | /// Build instance of directive of class \a K. |
||
289 | /// |
||
290 | /// \param SC Statement class. |
||
291 | /// \param K Kind of OpenMP directive. |
||
292 | /// \param StartLoc Starting location of the directive (directive keyword). |
||
293 | /// \param EndLoc Ending location of the directive. |
||
294 | /// |
||
295 | OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K, |
||
296 | SourceLocation StartLoc, SourceLocation EndLoc) |
||
297 | : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), |
||
298 | EndLoc(std::move(EndLoc)) {} |
||
299 | |||
300 | template <typename T, typename... Params> |
||
301 | static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses, |
||
302 | Stmt *AssociatedStmt, unsigned NumChildren, |
||
303 | Params &&... P) { |
||
304 | void *Mem = |
||
305 | C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt, |
||
306 | NumChildren), |
||
307 | alignof(T)); |
||
308 | |||
309 | auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses, |
||
310 | AssociatedStmt, NumChildren); |
||
311 | auto *Inst = new (Mem) T(std::forward<Params>(P)...); |
||
312 | Inst->Data = Data; |
||
313 | return Inst; |
||
314 | } |
||
315 | |||
316 | template <typename T, typename... Params> |
||
317 | static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, |
||
318 | bool HasAssociatedStmt, unsigned NumChildren, |
||
319 | Params &&... P) { |
||
320 | void *Mem = |
||
321 | C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, |
||
322 | NumChildren), |
||
323 | alignof(T)); |
||
324 | auto *Data = |
||
325 | OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, |
||
326 | HasAssociatedStmt, NumChildren); |
||
327 | auto *Inst = new (Mem) T(std::forward<Params>(P)...); |
||
328 | Inst->Data = Data; |
||
329 | return Inst; |
||
330 | } |
||
331 | |||
332 | template <typename T> |
||
333 | static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, |
||
334 | bool HasAssociatedStmt = false, |
||
335 | unsigned NumChildren = 0) { |
||
336 | void *Mem = |
||
337 | C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, |
||
338 | NumChildren), |
||
339 | alignof(T)); |
||
340 | auto *Data = |
||
341 | OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, |
||
342 | HasAssociatedStmt, NumChildren); |
||
343 | auto *Inst = new (Mem) T; |
||
344 | Inst->Data = Data; |
||
345 | return Inst; |
||
346 | } |
||
347 | |||
348 | public: |
||
349 | /// Iterates over expressions/statements used in the construct. |
||
350 | class used_clauses_child_iterator |
||
351 | : public llvm::iterator_adaptor_base< |
||
352 | used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, |
||
353 | std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { |
||
354 | ArrayRef<OMPClause *>::iterator End; |
||
355 | OMPClause::child_iterator ChildI, ChildEnd; |
||
356 | |||
357 | void MoveToNext() { |
||
358 | if (ChildI != ChildEnd) |
||
359 | return; |
||
360 | while (this->I != End) { |
||
361 | ++this->I; |
||
362 | if (this->I != End) { |
||
363 | ChildI = (*this->I)->used_children().begin(); |
||
364 | ChildEnd = (*this->I)->used_children().end(); |
||
365 | if (ChildI != ChildEnd) |
||
366 | return; |
||
367 | } |
||
368 | } |
||
369 | } |
||
370 | |||
371 | public: |
||
372 | explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) |
||
373 | : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), |
||
374 | End(Clauses.end()) { |
||
375 | if (this->I != End) { |
||
376 | ChildI = (*this->I)->used_children().begin(); |
||
377 | ChildEnd = (*this->I)->used_children().end(); |
||
378 | MoveToNext(); |
||
379 | } |
||
380 | } |
||
381 | Stmt *operator*() const { return *ChildI; } |
||
382 | Stmt *operator->() const { return **this; } |
||
383 | |||
384 | used_clauses_child_iterator &operator++() { |
||
385 | ++ChildI; |
||
386 | if (ChildI != ChildEnd) |
||
387 | return *this; |
||
388 | if (this->I != End) { |
||
389 | ++this->I; |
||
390 | if (this->I != End) { |
||
391 | ChildI = (*this->I)->used_children().begin(); |
||
392 | ChildEnd = (*this->I)->used_children().end(); |
||
393 | } |
||
394 | } |
||
395 | MoveToNext(); |
||
396 | return *this; |
||
397 | } |
||
398 | }; |
||
399 | |||
400 | static llvm::iterator_range<used_clauses_child_iterator> |
||
401 | used_clauses_children(ArrayRef<OMPClause *> Clauses) { |
||
402 | return { |
||
403 | used_clauses_child_iterator(Clauses), |
||
404 | used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))}; |
||
405 | } |
||
406 | |||
407 | /// Iterates over a filtered subrange of clauses applied to a |
||
408 | /// directive. |
||
409 | /// |
||
410 | /// This iterator visits only clauses of type SpecificClause. |
||
411 | template <typename SpecificClause> |
||
412 | class specific_clause_iterator |
||
413 | : public llvm::iterator_adaptor_base< |
||
414 | specific_clause_iterator<SpecificClause>, |
||
415 | ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, |
||
416 | const SpecificClause *, ptrdiff_t, const SpecificClause *, |
||
417 | const SpecificClause *> { |
||
418 | ArrayRef<OMPClause *>::const_iterator End; |
||
419 | |||
420 | void SkipToNextClause() { |
||
421 | while (this->I != End && !isa<SpecificClause>(*this->I)) |
||
422 | ++this->I; |
||
423 | } |
||
424 | |||
425 | public: |
||
426 | explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) |
||
427 | : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), |
||
428 | End(Clauses.end()) { |
||
429 | SkipToNextClause(); |
||
430 | } |
||
431 | |||
432 | const SpecificClause *operator*() const { |
||
433 | return cast<SpecificClause>(*this->I); |
||
434 | } |
||
435 | const SpecificClause *operator->() const { return **this; } |
||
436 | |||
437 | specific_clause_iterator &operator++() { |
||
438 | ++this->I; |
||
439 | SkipToNextClause(); |
||
440 | return *this; |
||
441 | } |
||
442 | }; |
||
443 | |||
444 | template <typename SpecificClause> |
||
445 | static llvm::iterator_range<specific_clause_iterator<SpecificClause>> |
||
446 | getClausesOfKind(ArrayRef<OMPClause *> Clauses) { |
||
447 | return {specific_clause_iterator<SpecificClause>(Clauses), |
||
448 | specific_clause_iterator<SpecificClause>( |
||
449 | llvm::ArrayRef(Clauses.end(), (size_t)0))}; |
||
450 | } |
||
451 | |||
452 | template <typename SpecificClause> |
||
453 | llvm::iterator_range<specific_clause_iterator<SpecificClause>> |
||
454 | getClausesOfKind() const { |
||
455 | return getClausesOfKind<SpecificClause>(clauses()); |
||
456 | } |
||
457 | |||
458 | /// Gets a single clause of the specified kind associated with the |
||
459 | /// current directive iff there is only one clause of this kind (and assertion |
||
460 | /// is fired if there is more than one clause is associated with the |
||
461 | /// directive). Returns nullptr if no clause of this kind is associated with |
||
462 | /// the directive. |
||
463 | template <typename SpecificClause> |
||
464 | static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) { |
||
465 | auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses); |
||
466 | |||
467 | if (ClausesOfKind.begin() != ClausesOfKind.end()) { |
||
468 | assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() && |
||
469 | "There are at least 2 clauses of the specified kind"); |
||
470 | return *ClausesOfKind.begin(); |
||
471 | } |
||
472 | return nullptr; |
||
473 | } |
||
474 | |||
475 | template <typename SpecificClause> |
||
476 | const SpecificClause *getSingleClause() const { |
||
477 | return getSingleClause<SpecificClause>(clauses()); |
||
478 | } |
||
479 | |||
480 | /// Returns true if the current directive has one or more clauses of a |
||
481 | /// specific kind. |
||
482 | template <typename SpecificClause> |
||
483 | bool hasClausesOfKind() const { |
||
484 | auto Clauses = getClausesOfKind<SpecificClause>(); |
||
485 | return Clauses.begin() != Clauses.end(); |
||
486 | } |
||
487 | |||
488 | /// Returns starting location of directive kind. |
||
489 | SourceLocation getBeginLoc() const { return StartLoc; } |
||
490 | /// Returns ending location of directive. |
||
491 | SourceLocation getEndLoc() const { return EndLoc; } |
||
492 | |||
493 | /// Set starting location of directive kind. |
||
494 | /// |
||
495 | /// \param Loc New starting location of directive. |
||
496 | /// |
||
497 | void setLocStart(SourceLocation Loc) { StartLoc = Loc; } |
||
498 | /// Set ending location of directive. |
||
499 | /// |
||
500 | /// \param Loc New ending location of directive. |
||
501 | /// |
||
502 | void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } |
||
503 | |||
504 | /// Get number of clauses. |
||
505 | unsigned getNumClauses() const { |
||
506 | if (!Data) |
||
507 | return 0; |
||
508 | return Data->getNumClauses(); |
||
509 | } |
||
510 | |||
511 | /// Returns specified clause. |
||
512 | /// |
||
513 | /// \param I Number of clause. |
||
514 | /// |
||
515 | OMPClause *getClause(unsigned I) const { return clauses()[I]; } |
||
516 | |||
517 | /// Returns true if directive has associated statement. |
||
518 | bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); } |
||
519 | |||
520 | /// Returns statement associated with the directive. |
||
521 | const Stmt *getAssociatedStmt() const { |
||
522 | return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt(); |
||
523 | } |
||
524 | Stmt *getAssociatedStmt() { |
||
525 | assert(hasAssociatedStmt() && |
||
526 | "Expected directive with the associated statement."); |
||
527 | return Data->getAssociatedStmt(); |
||
528 | } |
||
529 | |||
530 | /// Returns the captured statement associated with the |
||
531 | /// component region within the (combined) directive. |
||
532 | /// |
||
533 | /// \param RegionKind Component region kind. |
||
534 | const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { |
||
535 | assert(hasAssociatedStmt() && |
||
536 | "Expected directive with the associated statement."); |
||
537 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
||
538 | getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); |
||
539 | return Data->getCapturedStmt(RegionKind, CaptureRegions); |
||
540 | } |
||
541 | |||
542 | /// Get innermost captured statement for the construct. |
||
543 | CapturedStmt *getInnermostCapturedStmt() { |
||
544 | assert(hasAssociatedStmt() && |
||
545 | "Expected directive with the associated statement."); |
||
546 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
||
547 | getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); |
||
548 | return Data->getInnermostCapturedStmt(CaptureRegions); |
||
549 | } |
||
550 | |||
551 | const CapturedStmt *getInnermostCapturedStmt() const { |
||
552 | return const_cast<OMPExecutableDirective *>(this) |
||
553 | ->getInnermostCapturedStmt(); |
||
554 | } |
||
555 | |||
556 | OpenMPDirectiveKind getDirectiveKind() const { return Kind; } |
||
557 | |||
558 | static bool classof(const Stmt *S) { |
||
559 | return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && |
||
560 | S->getStmtClass() <= lastOMPExecutableDirectiveConstant; |
||
561 | } |
||
562 | |||
563 | child_range children() { |
||
564 | if (!Data) |
||
565 | return child_range(child_iterator(), child_iterator()); |
||
566 | return Data->getAssociatedStmtAsRange(); |
||
567 | } |
||
568 | |||
569 | const_child_range children() const { |
||
570 | return const_cast<OMPExecutableDirective *>(this)->children(); |
||
571 | } |
||
572 | |||
573 | ArrayRef<OMPClause *> clauses() const { |
||
574 | if (!Data) |
||
575 | return std::nullopt; |
||
576 | return Data->getClauses(); |
||
577 | } |
||
578 | |||
579 | /// Returns whether or not this is a Standalone directive. |
||
580 | /// |
||
581 | /// Stand-alone directives are executable directives |
||
582 | /// that have no associated user code. |
||
583 | bool isStandaloneDirective() const; |
||
584 | |||
585 | /// Returns the AST node representing OpenMP structured-block of this |
||
586 | /// OpenMP executable directive, |
||
587 | /// Prerequisite: Executable Directive must not be Standalone directive. |
||
588 | const Stmt *getStructuredBlock() const { |
||
589 | return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock(); |
||
590 | } |
||
591 | Stmt *getStructuredBlock(); |
||
592 | |||
593 | const Stmt *getRawStmt() const { |
||
594 | return const_cast<OMPExecutableDirective *>(this)->getRawStmt(); |
||
595 | } |
||
596 | Stmt *getRawStmt() { |
||
597 | assert(hasAssociatedStmt() && |
||
598 | "Expected directive with the associated statement."); |
||
599 | return Data->getRawStmt(); |
||
600 | } |
||
601 | }; |
||
602 | |||
603 | /// This represents '#pragma omp parallel' directive. |
||
604 | /// |
||
605 | /// \code |
||
606 | /// #pragma omp parallel private(a,b) reduction(+: c,d) |
||
607 | /// \endcode |
||
608 | /// In this example directive '#pragma omp parallel' has clauses 'private' |
||
609 | /// with the variables 'a' and 'b' and 'reduction' with operator '+' and |
||
610 | /// variables 'c' and 'd'. |
||
611 | /// |
||
612 | class OMPParallelDirective : public OMPExecutableDirective { |
||
613 | friend class ASTStmtReader; |
||
614 | friend class OMPExecutableDirective; |
||
615 | /// true if the construct has inner cancel directive. |
||
616 | bool HasCancel = false; |
||
617 | |||
618 | /// Build directive with the given start and end location. |
||
619 | /// |
||
620 | /// \param StartLoc Starting location of the directive (directive keyword). |
||
621 | /// \param EndLoc Ending Location of the directive. |
||
622 | /// |
||
623 | OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
624 | : OMPExecutableDirective(OMPParallelDirectiveClass, |
||
625 | llvm::omp::OMPD_parallel, StartLoc, EndLoc) {} |
||
626 | |||
627 | /// Build an empty directive. |
||
628 | /// |
||
629 | explicit OMPParallelDirective() |
||
630 | : OMPExecutableDirective(OMPParallelDirectiveClass, |
||
631 | llvm::omp::OMPD_parallel, SourceLocation(), |
||
632 | SourceLocation()) {} |
||
633 | |||
634 | /// Sets special task reduction descriptor. |
||
635 | void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
||
636 | |||
637 | /// Set cancel state. |
||
638 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
639 | |||
640 | public: |
||
641 | /// Creates directive with a list of \a Clauses. |
||
642 | /// |
||
643 | /// \param C AST context. |
||
644 | /// \param StartLoc Starting location of the directive kind. |
||
645 | /// \param EndLoc Ending Location of the directive. |
||
646 | /// \param Clauses List of clauses. |
||
647 | /// \param AssociatedStmt Statement associated with the directive. |
||
648 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
649 | /// taskgroup descriptor. |
||
650 | /// \param HasCancel true if this directive has inner cancel directive. |
||
651 | /// |
||
652 | static OMPParallelDirective * |
||
653 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
654 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
||
655 | bool HasCancel); |
||
656 | |||
657 | /// Creates an empty directive with the place for \a N clauses. |
||
658 | /// |
||
659 | /// \param C AST context. |
||
660 | /// \param NumClauses Number of clauses. |
||
661 | /// |
||
662 | static OMPParallelDirective *CreateEmpty(const ASTContext &C, |
||
663 | unsigned NumClauses, EmptyShell); |
||
664 | |||
665 | /// Returns special task reduction reference expression. |
||
666 | Expr *getTaskReductionRefExpr() { |
||
667 | return cast_or_null<Expr>(Data->getChildren()[0]); |
||
668 | } |
||
669 | const Expr *getTaskReductionRefExpr() const { |
||
670 | return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr(); |
||
671 | } |
||
672 | |||
673 | /// Return true if current directive has inner cancel directive. |
||
674 | bool hasCancel() const { return HasCancel; } |
||
675 | |||
676 | static bool classof(const Stmt *T) { |
||
677 | return T->getStmtClass() == OMPParallelDirectiveClass; |
||
678 | } |
||
679 | }; |
||
680 | |||
681 | /// The base class for all loop-based directives, including loop transformation |
||
682 | /// directives. |
||
683 | class OMPLoopBasedDirective : public OMPExecutableDirective { |
||
684 | friend class ASTStmtReader; |
||
685 | |||
686 | protected: |
||
687 | /// Number of collapsed loops as specified by 'collapse' clause. |
||
688 | unsigned NumAssociatedLoops = 0; |
||
689 | |||
690 | /// Build instance of loop directive of class \a Kind. |
||
691 | /// |
||
692 | /// \param SC Statement class. |
||
693 | /// \param Kind Kind of OpenMP directive. |
||
694 | /// \param StartLoc Starting location of the directive (directive keyword). |
||
695 | /// \param EndLoc Ending location of the directive. |
||
696 | /// \param NumAssociatedLoops Number of loops associated with the construct. |
||
697 | /// |
||
698 | OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind, |
||
699 | SourceLocation StartLoc, SourceLocation EndLoc, |
||
700 | unsigned NumAssociatedLoops) |
||
701 | : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc), |
||
702 | NumAssociatedLoops(NumAssociatedLoops) {} |
||
703 | |||
704 | public: |
||
705 | /// The expressions built to support OpenMP loops in combined/composite |
||
706 | /// pragmas (e.g. pragma omp distribute parallel for) |
||
707 | struct DistCombinedHelperExprs { |
||
708 | /// DistributeLowerBound - used when composing 'omp distribute' with |
||
709 | /// 'omp for' in a same construct. |
||
710 | Expr *LB; |
||
711 | /// DistributeUpperBound - used when composing 'omp distribute' with |
||
712 | /// 'omp for' in a same construct. |
||
713 | Expr *UB; |
||
714 | /// DistributeEnsureUpperBound - used when composing 'omp distribute' |
||
715 | /// with 'omp for' in a same construct, EUB depends on DistUB |
||
716 | Expr *EUB; |
||
717 | /// Distribute loop iteration variable init used when composing 'omp |
||
718 | /// distribute' |
||
719 | /// with 'omp for' in a same construct |
||
720 | Expr *Init; |
||
721 | /// Distribute Loop condition used when composing 'omp distribute' |
||
722 | /// with 'omp for' in a same construct |
||
723 | Expr *Cond; |
||
724 | /// Update of LowerBound for statically scheduled omp loops for |
||
725 | /// outer loop in combined constructs (e.g. 'distribute parallel for') |
||
726 | Expr *NLB; |
||
727 | /// Update of UpperBound for statically scheduled omp loops for |
||
728 | /// outer loop in combined constructs (e.g. 'distribute parallel for') |
||
729 | Expr *NUB; |
||
730 | /// Distribute Loop condition used when composing 'omp distribute' |
||
731 | /// with 'omp for' in a same construct when schedule is chunked. |
||
732 | Expr *DistCond; |
||
733 | /// 'omp parallel for' loop condition used when composed with |
||
734 | /// 'omp distribute' in the same construct and when schedule is |
||
735 | /// chunked and the chunk size is 1. |
||
736 | Expr *ParForInDistCond; |
||
737 | }; |
||
738 | |||
739 | /// The expressions built for the OpenMP loop CodeGen for the |
||
740 | /// whole collapsed loop nest. |
||
741 | struct HelperExprs { |
||
742 | /// Loop iteration variable. |
||
743 | Expr *IterationVarRef; |
||
744 | /// Loop last iteration number. |
||
745 | Expr *LastIteration; |
||
746 | /// Loop number of iterations. |
||
747 | Expr *NumIterations; |
||
748 | /// Calculation of last iteration. |
||
749 | Expr *CalcLastIteration; |
||
750 | /// Loop pre-condition. |
||
751 | Expr *PreCond; |
||
752 | /// Loop condition. |
||
753 | Expr *Cond; |
||
754 | /// Loop iteration variable init. |
||
755 | Expr *Init; |
||
756 | /// Loop increment. |
||
757 | Expr *Inc; |
||
758 | /// IsLastIteration - local flag variable passed to runtime. |
||
759 | Expr *IL; |
||
760 | /// LowerBound - local variable passed to runtime. |
||
761 | Expr *LB; |
||
762 | /// UpperBound - local variable passed to runtime. |
||
763 | Expr *UB; |
||
764 | /// Stride - local variable passed to runtime. |
||
765 | Expr *ST; |
||
766 | /// EnsureUpperBound -- expression UB = min(UB, NumIterations). |
||
767 | Expr *EUB; |
||
768 | /// Update of LowerBound for statically scheduled 'omp for' loops. |
||
769 | Expr *NLB; |
||
770 | /// Update of UpperBound for statically scheduled 'omp for' loops. |
||
771 | Expr *NUB; |
||
772 | /// PreviousLowerBound - local variable passed to runtime in the |
||
773 | /// enclosing schedule or null if that does not apply. |
||
774 | Expr *PrevLB; |
||
775 | /// PreviousUpperBound - local variable passed to runtime in the |
||
776 | /// enclosing schedule or null if that does not apply. |
||
777 | Expr *PrevUB; |
||
778 | /// DistInc - increment expression for distribute loop when found |
||
779 | /// combined with a further loop level (e.g. in 'distribute parallel for') |
||
780 | /// expression IV = IV + ST |
||
781 | Expr *DistInc; |
||
782 | /// PrevEUB - expression similar to EUB but to be used when loop |
||
783 | /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' |
||
784 | /// when ensuring that the UB is either the calculated UB by the runtime or |
||
785 | /// the end of the assigned distribute chunk) |
||
786 | /// expression UB = min (UB, PrevUB) |
||
787 | Expr *PrevEUB; |
||
788 | /// Counters Loop counters. |
||
789 | SmallVector<Expr *, 4> Counters; |
||
790 | /// PrivateCounters Loop counters. |
||
791 | SmallVector<Expr *, 4> PrivateCounters; |
||
792 | /// Expressions for loop counters inits for CodeGen. |
||
793 | SmallVector<Expr *, 4> Inits; |
||
794 | /// Expressions for loop counters update for CodeGen. |
||
795 | SmallVector<Expr *, 4> Updates; |
||
796 | /// Final loop counter values for GodeGen. |
||
797 | SmallVector<Expr *, 4> Finals; |
||
798 | /// List of counters required for the generation of the non-rectangular |
||
799 | /// loops. |
||
800 | SmallVector<Expr *, 4> DependentCounters; |
||
801 | /// List of initializers required for the generation of the non-rectangular |
||
802 | /// loops. |
||
803 | SmallVector<Expr *, 4> DependentInits; |
||
804 | /// List of final conditions required for the generation of the |
||
805 | /// non-rectangular loops. |
||
806 | SmallVector<Expr *, 4> FinalsConditions; |
||
807 | /// Init statement for all captured expressions. |
||
808 | Stmt *PreInits; |
||
809 | |||
810 | /// Expressions used when combining OpenMP loop pragmas |
||
811 | DistCombinedHelperExprs DistCombinedFields; |
||
812 | |||
813 | /// Check if all the expressions are built (does not check the |
||
814 | /// worksharing ones). |
||
815 | bool builtAll() { |
||
816 | return IterationVarRef != nullptr && LastIteration != nullptr && |
||
817 | NumIterations != nullptr && PreCond != nullptr && |
||
818 | Cond != nullptr && Init != nullptr && Inc != nullptr; |
||
819 | } |
||
820 | |||
821 | /// Initialize all the fields to null. |
||
822 | /// \param Size Number of elements in the |
||
823 | /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions |
||
824 | /// arrays. |
||
825 | void clear(unsigned Size) { |
||
826 | IterationVarRef = nullptr; |
||
827 | LastIteration = nullptr; |
||
828 | CalcLastIteration = nullptr; |
||
829 | PreCond = nullptr; |
||
830 | Cond = nullptr; |
||
831 | Init = nullptr; |
||
832 | Inc = nullptr; |
||
833 | IL = nullptr; |
||
834 | LB = nullptr; |
||
835 | UB = nullptr; |
||
836 | ST = nullptr; |
||
837 | EUB = nullptr; |
||
838 | NLB = nullptr; |
||
839 | NUB = nullptr; |
||
840 | NumIterations = nullptr; |
||
841 | PrevLB = nullptr; |
||
842 | PrevUB = nullptr; |
||
843 | DistInc = nullptr; |
||
844 | PrevEUB = nullptr; |
||
845 | Counters.resize(Size); |
||
846 | PrivateCounters.resize(Size); |
||
847 | Inits.resize(Size); |
||
848 | Updates.resize(Size); |
||
849 | Finals.resize(Size); |
||
850 | DependentCounters.resize(Size); |
||
851 | DependentInits.resize(Size); |
||
852 | FinalsConditions.resize(Size); |
||
853 | for (unsigned I = 0; I < Size; ++I) { |
||
854 | Counters[I] = nullptr; |
||
855 | PrivateCounters[I] = nullptr; |
||
856 | Inits[I] = nullptr; |
||
857 | Updates[I] = nullptr; |
||
858 | Finals[I] = nullptr; |
||
859 | DependentCounters[I] = nullptr; |
||
860 | DependentInits[I] = nullptr; |
||
861 | FinalsConditions[I] = nullptr; |
||
862 | } |
||
863 | PreInits = nullptr; |
||
864 | DistCombinedFields.LB = nullptr; |
||
865 | DistCombinedFields.UB = nullptr; |
||
866 | DistCombinedFields.EUB = nullptr; |
||
867 | DistCombinedFields.Init = nullptr; |
||
868 | DistCombinedFields.Cond = nullptr; |
||
869 | DistCombinedFields.NLB = nullptr; |
||
870 | DistCombinedFields.NUB = nullptr; |
||
871 | DistCombinedFields.DistCond = nullptr; |
||
872 | DistCombinedFields.ParForInDistCond = nullptr; |
||
873 | } |
||
874 | }; |
||
875 | |||
876 | /// Get number of collapsed loops. |
||
877 | unsigned getLoopsNumber() const { return NumAssociatedLoops; } |
||
878 | |||
879 | /// Try to find the next loop sub-statement in the specified statement \p |
||
880 | /// CurStmt. |
||
881 | /// \param TryImperfectlyNestedLoops true, if we need to try to look for the |
||
882 | /// imperfectly nested loop. |
||
883 | static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt, |
||
884 | bool TryImperfectlyNestedLoops); |
||
885 | static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt, |
||
886 | bool TryImperfectlyNestedLoops) { |
||
887 | return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt), |
||
888 | TryImperfectlyNestedLoops); |
||
889 | } |
||
890 | |||
891 | /// Calls the specified callback function for all the loops in \p CurStmt, |
||
892 | /// from the outermost to the innermost. |
||
893 | static bool |
||
894 | doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
||
895 | unsigned NumLoops, |
||
896 | llvm::function_ref<bool(unsigned, Stmt *)> Callback, |
||
897 | llvm::function_ref<void(OMPLoopTransformationDirective *)> |
||
898 | OnTransformationCallback); |
||
899 | static bool |
||
900 | doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
||
901 | unsigned NumLoops, |
||
902 | llvm::function_ref<bool(unsigned, const Stmt *)> Callback, |
||
903 | llvm::function_ref<void(const OMPLoopTransformationDirective *)> |
||
904 | OnTransformationCallback) { |
||
905 | auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) { |
||
906 | return Callback(Cnt, CurStmt); |
||
907 | }; |
||
908 | auto &&NewTransformCb = |
||
909 | [OnTransformationCallback](OMPLoopTransformationDirective *A) { |
||
910 | OnTransformationCallback(A); |
||
911 | }; |
||
912 | return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, |
||
913 | NumLoops, NewCallback, NewTransformCb); |
||
914 | } |
||
915 | |||
916 | /// Calls the specified callback function for all the loops in \p CurStmt, |
||
917 | /// from the outermost to the innermost. |
||
918 | static bool |
||
919 | doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
||
920 | unsigned NumLoops, |
||
921 | llvm::function_ref<bool(unsigned, Stmt *)> Callback) { |
||
922 | auto &&TransformCb = [](OMPLoopTransformationDirective *) {}; |
||
923 | return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback, |
||
924 | TransformCb); |
||
925 | } |
||
926 | static bool |
||
927 | doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
||
928 | unsigned NumLoops, |
||
929 | llvm::function_ref<bool(unsigned, const Stmt *)> Callback) { |
||
930 | auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) { |
||
931 | return Callback(Cnt, CurStmt); |
||
932 | }; |
||
933 | return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, |
||
934 | NumLoops, NewCallback); |
||
935 | } |
||
936 | |||
937 | /// Calls the specified callback function for all the loop bodies in \p |
||
938 | /// CurStmt, from the outermost loop to the innermost. |
||
939 | static void doForAllLoopsBodies( |
||
940 | Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, |
||
941 | llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback); |
||
942 | static void doForAllLoopsBodies( |
||
943 | const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, |
||
944 | llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) { |
||
945 | auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) { |
||
946 | Callback(Cnt, Loop, Body); |
||
947 | }; |
||
948 | doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, |
||
949 | NumLoops, NewCallback); |
||
950 | } |
||
951 | |||
952 | static bool classof(const Stmt *T) { |
||
953 | if (auto *D = dyn_cast<OMPExecutableDirective>(T)) |
||
954 | return isOpenMPLoopDirective(D->getDirectiveKind()); |
||
955 | return false; |
||
956 | } |
||
957 | }; |
||
958 | |||
959 | /// The base class for all loop transformation directives. |
||
960 | class OMPLoopTransformationDirective : public OMPLoopBasedDirective { |
||
961 | friend class ASTStmtReader; |
||
962 | |||
963 | /// Number of loops generated by this loop transformation. |
||
964 | unsigned NumGeneratedLoops = 0; |
||
965 | |||
966 | protected: |
||
967 | explicit OMPLoopTransformationDirective(StmtClass SC, |
||
968 | OpenMPDirectiveKind Kind, |
||
969 | SourceLocation StartLoc, |
||
970 | SourceLocation EndLoc, |
||
971 | unsigned NumAssociatedLoops) |
||
972 | : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {} |
||
973 | |||
974 | /// Set the number of loops generated by this loop transformation. |
||
975 | void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; } |
||
976 | |||
977 | public: |
||
978 | /// Return the number of associated (consumed) loops. |
||
979 | unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } |
||
980 | |||
981 | /// Return the number of loops generated by this loop transformation. |
||
982 | unsigned getNumGeneratedLoops() { return NumGeneratedLoops; } |
||
983 | |||
984 | /// Get the de-sugared statements after the loop transformation. |
||
985 | /// |
||
986 | /// Might be nullptr if either the directive generates no loops and is handled |
||
987 | /// directly in CodeGen, or resolving a template-dependence context is |
||
988 | /// required. |
||
989 | Stmt *getTransformedStmt() const; |
||
990 | |||
991 | /// Return preinits statement. |
||
992 | Stmt *getPreInits() const; |
||
993 | |||
994 | static bool classof(const Stmt *T) { |
||
995 | return T->getStmtClass() == OMPTileDirectiveClass || |
||
996 | T->getStmtClass() == OMPUnrollDirectiveClass; |
||
997 | } |
||
998 | }; |
||
999 | |||
1000 | /// This is a common base class for loop directives ('omp simd', 'omp |
||
1001 | /// for', 'omp for simd' etc.). It is responsible for the loop code generation. |
||
1002 | /// |
||
1003 | class OMPLoopDirective : public OMPLoopBasedDirective { |
||
1004 | friend class ASTStmtReader; |
||
1005 | |||
1006 | /// Offsets to the stored exprs. |
||
1007 | /// This enumeration contains offsets to all the pointers to children |
||
1008 | /// expressions stored in OMPLoopDirective. |
||
1009 | /// The first 9 children are necessary for all the loop directives, |
||
1010 | /// the next 8 are specific to the worksharing ones, and the next 11 are |
||
1011 | /// used for combined constructs containing two pragmas associated to loops. |
||
1012 | /// After the fixed children, three arrays of length NumAssociatedLoops are |
||
1013 | /// allocated: loop counters, their updates and final values. |
||
1014 | /// PrevLowerBound and PrevUpperBound are used to communicate blocking |
||
1015 | /// information in composite constructs which require loop blocking |
||
1016 | /// DistInc is used to generate the increment expression for the distribute |
||
1017 | /// loop when combined with a further nested loop |
||
1018 | /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the |
||
1019 | /// for loop when combined with a previous distribute loop in the same pragma |
||
1020 | /// (e.g. 'distribute parallel for') |
||
1021 | /// |
||
1022 | enum { |
||
1023 | IterationVariableOffset = 0, |
||
1024 | LastIterationOffset = 1, |
||
1025 | CalcLastIterationOffset = 2, |
||
1026 | PreConditionOffset = 3, |
||
1027 | CondOffset = 4, |
||
1028 | InitOffset = 5, |
||
1029 | IncOffset = 6, |
||
1030 | PreInitsOffset = 7, |
||
1031 | // The '...End' enumerators do not correspond to child expressions - they |
||
1032 | // specify the offset to the end (and start of the following counters/ |
||
1033 | // updates/finals/dependent_counters/dependent_inits/finals_conditions |
||
1034 | // arrays). |
||
1035 | DefaultEnd = 8, |
||
1036 | // The following 8 exprs are used by worksharing and distribute loops only. |
||
1037 | IsLastIterVariableOffset = 8, |
||
1038 | LowerBoundVariableOffset = 9, |
||
1039 | UpperBoundVariableOffset = 10, |
||
1040 | StrideVariableOffset = 11, |
||
1041 | EnsureUpperBoundOffset = 12, |
||
1042 | NextLowerBoundOffset = 13, |
||
1043 | NextUpperBoundOffset = 14, |
||
1044 | NumIterationsOffset = 15, |
||
1045 | // Offset to the end for worksharing loop directives. |
||
1046 | WorksharingEnd = 16, |
||
1047 | PrevLowerBoundVariableOffset = 16, |
||
1048 | PrevUpperBoundVariableOffset = 17, |
||
1049 | DistIncOffset = 18, |
||
1050 | PrevEnsureUpperBoundOffset = 19, |
||
1051 | CombinedLowerBoundVariableOffset = 20, |
||
1052 | CombinedUpperBoundVariableOffset = 21, |
||
1053 | CombinedEnsureUpperBoundOffset = 22, |
||
1054 | CombinedInitOffset = 23, |
||
1055 | CombinedConditionOffset = 24, |
||
1056 | CombinedNextLowerBoundOffset = 25, |
||
1057 | CombinedNextUpperBoundOffset = 26, |
||
1058 | CombinedDistConditionOffset = 27, |
||
1059 | CombinedParForInDistConditionOffset = 28, |
||
1060 | // Offset to the end (and start of the following |
||
1061 | // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions |
||
1062 | // arrays) for combined distribute loop directives. |
||
1063 | CombinedDistributeEnd = 29, |
||
1064 | }; |
||
1065 | |||
1066 | /// Get the counters storage. |
||
1067 | MutableArrayRef<Expr *> getCounters() { |
||
1068 | auto **Storage = reinterpret_cast<Expr **>( |
||
1069 | &Data->getChildren()[getArraysOffset(getDirectiveKind())]); |
||
1070 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1071 | } |
||
1072 | |||
1073 | /// Get the private counters storage. |
||
1074 | MutableArrayRef<Expr *> getPrivateCounters() { |
||
1075 | auto **Storage = reinterpret_cast<Expr **>( |
||
1076 | &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
||
1077 | getLoopsNumber()]); |
||
1078 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1079 | } |
||
1080 | |||
1081 | /// Get the updates storage. |
||
1082 | MutableArrayRef<Expr *> getInits() { |
||
1083 | auto **Storage = reinterpret_cast<Expr **>( |
||
1084 | &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
||
1085 | 2 * getLoopsNumber()]); |
||
1086 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1087 | } |
||
1088 | |||
1089 | /// Get the updates storage. |
||
1090 | MutableArrayRef<Expr *> getUpdates() { |
||
1091 | auto **Storage = reinterpret_cast<Expr **>( |
||
1092 | &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
||
1093 | 3 * getLoopsNumber()]); |
||
1094 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1095 | } |
||
1096 | |||
1097 | /// Get the final counter updates storage. |
||
1098 | MutableArrayRef<Expr *> getFinals() { |
||
1099 | auto **Storage = reinterpret_cast<Expr **>( |
||
1100 | &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
||
1101 | 4 * getLoopsNumber()]); |
||
1102 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1103 | } |
||
1104 | |||
1105 | /// Get the dependent counters storage. |
||
1106 | MutableArrayRef<Expr *> getDependentCounters() { |
||
1107 | auto **Storage = reinterpret_cast<Expr **>( |
||
1108 | &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
||
1109 | 5 * getLoopsNumber()]); |
||
1110 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1111 | } |
||
1112 | |||
1113 | /// Get the dependent inits storage. |
||
1114 | MutableArrayRef<Expr *> getDependentInits() { |
||
1115 | auto **Storage = reinterpret_cast<Expr **>( |
||
1116 | &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
||
1117 | 6 * getLoopsNumber()]); |
||
1118 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1119 | } |
||
1120 | |||
1121 | /// Get the finals conditions storage. |
||
1122 | MutableArrayRef<Expr *> getFinalsConditions() { |
||
1123 | auto **Storage = reinterpret_cast<Expr **>( |
||
1124 | &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
||
1125 | 7 * getLoopsNumber()]); |
||
1126 | return llvm::MutableArrayRef(Storage, getLoopsNumber()); |
||
1127 | } |
||
1128 | |||
1129 | protected: |
||
1130 | /// Build instance of loop directive of class \a Kind. |
||
1131 | /// |
||
1132 | /// \param SC Statement class. |
||
1133 | /// \param Kind Kind of OpenMP directive. |
||
1134 | /// \param StartLoc Starting location of the directive (directive keyword). |
||
1135 | /// \param EndLoc Ending location of the directive. |
||
1136 | /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. |
||
1137 | /// |
||
1138 | OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind, |
||
1139 | SourceLocation StartLoc, SourceLocation EndLoc, |
||
1140 | unsigned CollapsedNum) |
||
1141 | : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {} |
||
1142 | |||
1143 | /// Offset to the start of children expression arrays. |
||
1144 | static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { |
||
1145 | if (isOpenMPLoopBoundSharingDirective(Kind)) |
||
1146 | return CombinedDistributeEnd; |
||
1147 | if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || |
||
1148 | isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) |
||
1149 | return WorksharingEnd; |
||
1150 | return DefaultEnd; |
||
1151 | } |
||
1152 | |||
1153 | /// Children number. |
||
1154 | static unsigned numLoopChildren(unsigned CollapsedNum, |
||
1155 | OpenMPDirectiveKind Kind) { |
||
1156 | return getArraysOffset(Kind) + |
||
1157 | 8 * CollapsedNum; // Counters, PrivateCounters, Inits, |
||
1158 | // Updates, Finals, DependentCounters, |
||
1159 | // DependentInits, FinalsConditions. |
||
1160 | } |
||
1161 | |||
1162 | void setIterationVariable(Expr *IV) { |
||
1163 | Data->getChildren()[IterationVariableOffset] = IV; |
||
1164 | } |
||
1165 | void setLastIteration(Expr *LI) { |
||
1166 | Data->getChildren()[LastIterationOffset] = LI; |
||
1167 | } |
||
1168 | void setCalcLastIteration(Expr *CLI) { |
||
1169 | Data->getChildren()[CalcLastIterationOffset] = CLI; |
||
1170 | } |
||
1171 | void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } |
||
1172 | void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } |
||
1173 | void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } |
||
1174 | void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } |
||
1175 | void setPreInits(Stmt *PreInits) { |
||
1176 | Data->getChildren()[PreInitsOffset] = PreInits; |
||
1177 | } |
||
1178 | void setIsLastIterVariable(Expr *IL) { |
||
1179 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1180 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1181 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1182 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1183 | "expected worksharing loop directive"); |
||
1184 | Data->getChildren()[IsLastIterVariableOffset] = IL; |
||
1185 | } |
||
1186 | void setLowerBoundVariable(Expr *LB) { |
||
1187 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1188 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1189 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1190 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1191 | "expected worksharing loop directive"); |
||
1192 | Data->getChildren()[LowerBoundVariableOffset] = LB; |
||
1193 | } |
||
1194 | void setUpperBoundVariable(Expr *UB) { |
||
1195 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1196 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1197 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1198 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1199 | "expected worksharing loop directive"); |
||
1200 | Data->getChildren()[UpperBoundVariableOffset] = UB; |
||
1201 | } |
||
1202 | void setStrideVariable(Expr *ST) { |
||
1203 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1204 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1205 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1206 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1207 | "expected worksharing loop directive"); |
||
1208 | Data->getChildren()[StrideVariableOffset] = ST; |
||
1209 | } |
||
1210 | void setEnsureUpperBound(Expr *EUB) { |
||
1211 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1212 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1213 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1214 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1215 | "expected worksharing loop directive"); |
||
1216 | Data->getChildren()[EnsureUpperBoundOffset] = EUB; |
||
1217 | } |
||
1218 | void setNextLowerBound(Expr *NLB) { |
||
1219 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1220 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1221 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1222 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1223 | "expected worksharing loop directive"); |
||
1224 | Data->getChildren()[NextLowerBoundOffset] = NLB; |
||
1225 | } |
||
1226 | void setNextUpperBound(Expr *NUB) { |
||
1227 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1228 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1229 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1230 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1231 | "expected worksharing loop directive"); |
||
1232 | Data->getChildren()[NextUpperBoundOffset] = NUB; |
||
1233 | } |
||
1234 | void setNumIterations(Expr *NI) { |
||
1235 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1236 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1237 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1238 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1239 | "expected worksharing loop directive"); |
||
1240 | Data->getChildren()[NumIterationsOffset] = NI; |
||
1241 | } |
||
1242 | void setPrevLowerBoundVariable(Expr *PrevLB) { |
||
1243 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1244 | "expected loop bound sharing directive"); |
||
1245 | Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; |
||
1246 | } |
||
1247 | void setPrevUpperBoundVariable(Expr *PrevUB) { |
||
1248 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1249 | "expected loop bound sharing directive"); |
||
1250 | Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; |
||
1251 | } |
||
1252 | void setDistInc(Expr *DistInc) { |
||
1253 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1254 | "expected loop bound sharing directive"); |
||
1255 | Data->getChildren()[DistIncOffset] = DistInc; |
||
1256 | } |
||
1257 | void setPrevEnsureUpperBound(Expr *PrevEUB) { |
||
1258 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1259 | "expected loop bound sharing directive"); |
||
1260 | Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; |
||
1261 | } |
||
1262 | void setCombinedLowerBoundVariable(Expr *CombLB) { |
||
1263 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1264 | "expected loop bound sharing directive"); |
||
1265 | Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; |
||
1266 | } |
||
1267 | void setCombinedUpperBoundVariable(Expr *CombUB) { |
||
1268 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1269 | "expected loop bound sharing directive"); |
||
1270 | Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; |
||
1271 | } |
||
1272 | void setCombinedEnsureUpperBound(Expr *CombEUB) { |
||
1273 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1274 | "expected loop bound sharing directive"); |
||
1275 | Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; |
||
1276 | } |
||
1277 | void setCombinedInit(Expr *CombInit) { |
||
1278 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1279 | "expected loop bound sharing directive"); |
||
1280 | Data->getChildren()[CombinedInitOffset] = CombInit; |
||
1281 | } |
||
1282 | void setCombinedCond(Expr *CombCond) { |
||
1283 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1284 | "expected loop bound sharing directive"); |
||
1285 | Data->getChildren()[CombinedConditionOffset] = CombCond; |
||
1286 | } |
||
1287 | void setCombinedNextLowerBound(Expr *CombNLB) { |
||
1288 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1289 | "expected loop bound sharing directive"); |
||
1290 | Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; |
||
1291 | } |
||
1292 | void setCombinedNextUpperBound(Expr *CombNUB) { |
||
1293 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1294 | "expected loop bound sharing directive"); |
||
1295 | Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; |
||
1296 | } |
||
1297 | void setCombinedDistCond(Expr *CombDistCond) { |
||
1298 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1299 | "expected loop bound distribute sharing directive"); |
||
1300 | Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; |
||
1301 | } |
||
1302 | void setCombinedParForInDistCond(Expr *CombParForInDistCond) { |
||
1303 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1304 | "expected loop bound distribute sharing directive"); |
||
1305 | Data->getChildren()[CombinedParForInDistConditionOffset] = |
||
1306 | CombParForInDistCond; |
||
1307 | } |
||
1308 | void setCounters(ArrayRef<Expr *> A); |
||
1309 | void setPrivateCounters(ArrayRef<Expr *> A); |
||
1310 | void setInits(ArrayRef<Expr *> A); |
||
1311 | void setUpdates(ArrayRef<Expr *> A); |
||
1312 | void setFinals(ArrayRef<Expr *> A); |
||
1313 | void setDependentCounters(ArrayRef<Expr *> A); |
||
1314 | void setDependentInits(ArrayRef<Expr *> A); |
||
1315 | void setFinalsConditions(ArrayRef<Expr *> A); |
||
1316 | |||
1317 | public: |
||
1318 | Expr *getIterationVariable() const { |
||
1319 | return cast<Expr>(Data->getChildren()[IterationVariableOffset]); |
||
1320 | } |
||
1321 | Expr *getLastIteration() const { |
||
1322 | return cast<Expr>(Data->getChildren()[LastIterationOffset]); |
||
1323 | } |
||
1324 | Expr *getCalcLastIteration() const { |
||
1325 | return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); |
||
1326 | } |
||
1327 | Expr *getPreCond() const { |
||
1328 | return cast<Expr>(Data->getChildren()[PreConditionOffset]); |
||
1329 | } |
||
1330 | Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } |
||
1331 | Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } |
||
1332 | Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } |
||
1333 | const Stmt *getPreInits() const { |
||
1334 | return Data->getChildren()[PreInitsOffset]; |
||
1335 | } |
||
1336 | Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } |
||
1337 | Expr *getIsLastIterVariable() const { |
||
1338 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1339 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1340 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1341 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1342 | "expected worksharing loop directive"); |
||
1343 | return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]); |
||
1344 | } |
||
1345 | Expr *getLowerBoundVariable() const { |
||
1346 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1347 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1348 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1349 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1350 | "expected worksharing loop directive"); |
||
1351 | return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]); |
||
1352 | } |
||
1353 | Expr *getUpperBoundVariable() const { |
||
1354 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1355 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1356 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1357 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1358 | "expected worksharing loop directive"); |
||
1359 | return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]); |
||
1360 | } |
||
1361 | Expr *getStrideVariable() const { |
||
1362 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1363 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1364 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1365 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1366 | "expected worksharing loop directive"); |
||
1367 | return cast<Expr>(Data->getChildren()[StrideVariableOffset]); |
||
1368 | } |
||
1369 | Expr *getEnsureUpperBound() const { |
||
1370 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1371 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1372 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1373 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1374 | "expected worksharing loop directive"); |
||
1375 | return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]); |
||
1376 | } |
||
1377 | Expr *getNextLowerBound() const { |
||
1378 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1379 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1380 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1381 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1382 | "expected worksharing loop directive"); |
||
1383 | return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]); |
||
1384 | } |
||
1385 | Expr *getNextUpperBound() const { |
||
1386 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1387 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1388 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1389 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1390 | "expected worksharing loop directive"); |
||
1391 | return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]); |
||
1392 | } |
||
1393 | Expr *getNumIterations() const { |
||
1394 | assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
||
1395 | isOpenMPGenericLoopDirective(getDirectiveKind()) || |
||
1396 | isOpenMPTaskLoopDirective(getDirectiveKind()) || |
||
1397 | isOpenMPDistributeDirective(getDirectiveKind())) && |
||
1398 | "expected worksharing loop directive"); |
||
1399 | return cast<Expr>(Data->getChildren()[NumIterationsOffset]); |
||
1400 | } |
||
1401 | Expr *getPrevLowerBoundVariable() const { |
||
1402 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1403 | "expected loop bound sharing directive"); |
||
1404 | return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); |
||
1405 | } |
||
1406 | Expr *getPrevUpperBoundVariable() const { |
||
1407 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1408 | "expected loop bound sharing directive"); |
||
1409 | return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); |
||
1410 | } |
||
1411 | Expr *getDistInc() const { |
||
1412 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1413 | "expected loop bound sharing directive"); |
||
1414 | return cast<Expr>(Data->getChildren()[DistIncOffset]); |
||
1415 | } |
||
1416 | Expr *getPrevEnsureUpperBound() const { |
||
1417 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1418 | "expected loop bound sharing directive"); |
||
1419 | return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); |
||
1420 | } |
||
1421 | Expr *getCombinedLowerBoundVariable() const { |
||
1422 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1423 | "expected loop bound sharing directive"); |
||
1424 | return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); |
||
1425 | } |
||
1426 | Expr *getCombinedUpperBoundVariable() const { |
||
1427 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1428 | "expected loop bound sharing directive"); |
||
1429 | return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); |
||
1430 | } |
||
1431 | Expr *getCombinedEnsureUpperBound() const { |
||
1432 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1433 | "expected loop bound sharing directive"); |
||
1434 | return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); |
||
1435 | } |
||
1436 | Expr *getCombinedInit() const { |
||
1437 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1438 | "expected loop bound sharing directive"); |
||
1439 | return cast<Expr>(Data->getChildren()[CombinedInitOffset]); |
||
1440 | } |
||
1441 | Expr *getCombinedCond() const { |
||
1442 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1443 | "expected loop bound sharing directive"); |
||
1444 | return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); |
||
1445 | } |
||
1446 | Expr *getCombinedNextLowerBound() const { |
||
1447 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1448 | "expected loop bound sharing directive"); |
||
1449 | return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); |
||
1450 | } |
||
1451 | Expr *getCombinedNextUpperBound() const { |
||
1452 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1453 | "expected loop bound sharing directive"); |
||
1454 | return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); |
||
1455 | } |
||
1456 | Expr *getCombinedDistCond() const { |
||
1457 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1458 | "expected loop bound distribute sharing directive"); |
||
1459 | return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); |
||
1460 | } |
||
1461 | Expr *getCombinedParForInDistCond() const { |
||
1462 | assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
||
1463 | "expected loop bound distribute sharing directive"); |
||
1464 | return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]); |
||
1465 | } |
||
1466 | Stmt *getBody(); |
||
1467 | const Stmt *getBody() const { |
||
1468 | return const_cast<OMPLoopDirective *>(this)->getBody(); |
||
1469 | } |
||
1470 | |||
1471 | ArrayRef<Expr *> counters() { return getCounters(); } |
||
1472 | |||
1473 | ArrayRef<Expr *> counters() const { |
||
1474 | return const_cast<OMPLoopDirective *>(this)->getCounters(); |
||
1475 | } |
||
1476 | |||
1477 | ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } |
||
1478 | |||
1479 | ArrayRef<Expr *> private_counters() const { |
||
1480 | return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); |
||
1481 | } |
||
1482 | |||
1483 | ArrayRef<Expr *> inits() { return getInits(); } |
||
1484 | |||
1485 | ArrayRef<Expr *> inits() const { |
||
1486 | return const_cast<OMPLoopDirective *>(this)->getInits(); |
||
1487 | } |
||
1488 | |||
1489 | ArrayRef<Expr *> updates() { return getUpdates(); } |
||
1490 | |||
1491 | ArrayRef<Expr *> updates() const { |
||
1492 | return const_cast<OMPLoopDirective *>(this)->getUpdates(); |
||
1493 | } |
||
1494 | |||
1495 | ArrayRef<Expr *> finals() { return getFinals(); } |
||
1496 | |||
1497 | ArrayRef<Expr *> finals() const { |
||
1498 | return const_cast<OMPLoopDirective *>(this)->getFinals(); |
||
1499 | } |
||
1500 | |||
1501 | ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } |
||
1502 | |||
1503 | ArrayRef<Expr *> dependent_counters() const { |
||
1504 | return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); |
||
1505 | } |
||
1506 | |||
1507 | ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } |
||
1508 | |||
1509 | ArrayRef<Expr *> dependent_inits() const { |
||
1510 | return const_cast<OMPLoopDirective *>(this)->getDependentInits(); |
||
1511 | } |
||
1512 | |||
1513 | ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } |
||
1514 | |||
1515 | ArrayRef<Expr *> finals_conditions() const { |
||
1516 | return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); |
||
1517 | } |
||
1518 | |||
1519 | static bool classof(const Stmt *T) { |
||
1520 | return T->getStmtClass() == OMPSimdDirectiveClass || |
||
1521 | T->getStmtClass() == OMPForDirectiveClass || |
||
1522 | T->getStmtClass() == OMPForSimdDirectiveClass || |
||
1523 | T->getStmtClass() == OMPParallelForDirectiveClass || |
||
1524 | T->getStmtClass() == OMPParallelForSimdDirectiveClass || |
||
1525 | T->getStmtClass() == OMPTaskLoopDirectiveClass || |
||
1526 | T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || |
||
1527 | T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass || |
||
1528 | T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass || |
||
1529 | T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || |
||
1530 | T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || |
||
1531 | T->getStmtClass() == OMPGenericLoopDirectiveClass || |
||
1532 | T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass || |
||
1533 | T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass || |
||
1534 | T->getStmtClass() == OMPParallelGenericLoopDirectiveClass || |
||
1535 | T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass || |
||
1536 | T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass || |
||
1537 | T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass || |
||
1538 | T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || |
||
1539 | T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || |
||
1540 | T->getStmtClass() == OMPDistributeDirectiveClass || |
||
1541 | T->getStmtClass() == OMPTargetParallelForDirectiveClass || |
||
1542 | T->getStmtClass() == OMPDistributeParallelForDirectiveClass || |
||
1543 | T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || |
||
1544 | T->getStmtClass() == OMPDistributeSimdDirectiveClass || |
||
1545 | T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || |
||
1546 | T->getStmtClass() == OMPTargetSimdDirectiveClass || |
||
1547 | T->getStmtClass() == OMPTeamsDistributeDirectiveClass || |
||
1548 | T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || |
||
1549 | T->getStmtClass() == |
||
1550 | OMPTeamsDistributeParallelForSimdDirectiveClass || |
||
1551 | T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || |
||
1552 | T->getStmtClass() == |
||
1553 | OMPTargetTeamsDistributeParallelForDirectiveClass || |
||
1554 | T->getStmtClass() == |
||
1555 | OMPTargetTeamsDistributeParallelForSimdDirectiveClass || |
||
1556 | T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || |
||
1557 | T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; |
||
1558 | } |
||
1559 | }; |
||
1560 | |||
1561 | /// This represents '#pragma omp simd' directive. |
||
1562 | /// |
||
1563 | /// \code |
||
1564 | /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) |
||
1565 | /// \endcode |
||
1566 | /// In this example directive '#pragma omp simd' has clauses 'private' |
||
1567 | /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and |
||
1568 | /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. |
||
1569 | /// |
||
1570 | class OMPSimdDirective : public OMPLoopDirective { |
||
1571 | friend class ASTStmtReader; |
||
1572 | friend class OMPExecutableDirective; |
||
1573 | /// Build directive with the given start and end location. |
||
1574 | /// |
||
1575 | /// \param StartLoc Starting location of the directive kind. |
||
1576 | /// \param EndLoc Ending location of the directive. |
||
1577 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1578 | /// |
||
1579 | OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
1580 | unsigned CollapsedNum) |
||
1581 | : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc, |
||
1582 | EndLoc, CollapsedNum) {} |
||
1583 | |||
1584 | /// Build an empty directive. |
||
1585 | /// |
||
1586 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1587 | /// |
||
1588 | explicit OMPSimdDirective(unsigned CollapsedNum) |
||
1589 | : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, |
||
1590 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
1591 | |||
1592 | public: |
||
1593 | /// Creates directive with a list of \a Clauses. |
||
1594 | /// |
||
1595 | /// \param C AST context. |
||
1596 | /// \param StartLoc Starting location of the directive kind. |
||
1597 | /// \param EndLoc Ending Location of the directive. |
||
1598 | /// \param CollapsedNum Number of collapsed loops. |
||
1599 | /// \param Clauses List of clauses. |
||
1600 | /// \param AssociatedStmt Statement, associated with the directive. |
||
1601 | /// \param Exprs Helper expressions for CodeGen. |
||
1602 | /// |
||
1603 | static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
1604 | SourceLocation EndLoc, unsigned CollapsedNum, |
||
1605 | ArrayRef<OMPClause *> Clauses, |
||
1606 | Stmt *AssociatedStmt, |
||
1607 | const HelperExprs &Exprs); |
||
1608 | |||
1609 | /// Creates an empty directive with the place |
||
1610 | /// for \a NumClauses clauses. |
||
1611 | /// |
||
1612 | /// \param C AST context. |
||
1613 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1614 | /// \param NumClauses Number of clauses. |
||
1615 | /// |
||
1616 | static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
||
1617 | unsigned CollapsedNum, EmptyShell); |
||
1618 | |||
1619 | static bool classof(const Stmt *T) { |
||
1620 | return T->getStmtClass() == OMPSimdDirectiveClass; |
||
1621 | } |
||
1622 | }; |
||
1623 | |||
1624 | /// This represents '#pragma omp for' directive. |
||
1625 | /// |
||
1626 | /// \code |
||
1627 | /// #pragma omp for private(a,b) reduction(+:c,d) |
||
1628 | /// \endcode |
||
1629 | /// In this example directive '#pragma omp for' has clauses 'private' with the |
||
1630 | /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' |
||
1631 | /// and 'd'. |
||
1632 | /// |
||
1633 | class OMPForDirective : public OMPLoopDirective { |
||
1634 | friend class ASTStmtReader; |
||
1635 | friend class OMPExecutableDirective; |
||
1636 | /// true if current directive has inner cancel directive. |
||
1637 | bool HasCancel = false; |
||
1638 | |||
1639 | /// Build directive with the given start and end location. |
||
1640 | /// |
||
1641 | /// \param StartLoc Starting location of the directive kind. |
||
1642 | /// \param EndLoc Ending location of the directive. |
||
1643 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1644 | /// |
||
1645 | OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
1646 | unsigned CollapsedNum) |
||
1647 | : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc, |
||
1648 | EndLoc, CollapsedNum) {} |
||
1649 | |||
1650 | /// Build an empty directive. |
||
1651 | /// |
||
1652 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1653 | /// |
||
1654 | explicit OMPForDirective(unsigned CollapsedNum) |
||
1655 | : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, |
||
1656 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
1657 | |||
1658 | /// Sets special task reduction descriptor. |
||
1659 | void setTaskReductionRefExpr(Expr *E) { |
||
1660 | Data->getChildren()[numLoopChildren(getLoopsNumber(), |
||
1661 | llvm::omp::OMPD_for)] = E; |
||
1662 | } |
||
1663 | |||
1664 | /// Set cancel state. |
||
1665 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
1666 | |||
1667 | public: |
||
1668 | /// Creates directive with a list of \a Clauses. |
||
1669 | /// |
||
1670 | /// \param C AST context. |
||
1671 | /// \param StartLoc Starting location of the directive kind. |
||
1672 | /// \param EndLoc Ending Location of the directive. |
||
1673 | /// \param CollapsedNum Number of collapsed loops. |
||
1674 | /// \param Clauses List of clauses. |
||
1675 | /// \param AssociatedStmt Statement, associated with the directive. |
||
1676 | /// \param Exprs Helper expressions for CodeGen. |
||
1677 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
1678 | /// taskgroup descriptor. |
||
1679 | /// \param HasCancel true if current directive has inner cancel directive. |
||
1680 | /// |
||
1681 | static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
1682 | SourceLocation EndLoc, unsigned CollapsedNum, |
||
1683 | ArrayRef<OMPClause *> Clauses, |
||
1684 | Stmt *AssociatedStmt, const HelperExprs &Exprs, |
||
1685 | Expr *TaskRedRef, bool HasCancel); |
||
1686 | |||
1687 | /// Creates an empty directive with the place |
||
1688 | /// for \a NumClauses clauses. |
||
1689 | /// |
||
1690 | /// \param C AST context. |
||
1691 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1692 | /// \param NumClauses Number of clauses. |
||
1693 | /// |
||
1694 | static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
||
1695 | unsigned CollapsedNum, EmptyShell); |
||
1696 | |||
1697 | /// Returns special task reduction reference expression. |
||
1698 | Expr *getTaskReductionRefExpr() { |
||
1699 | return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
||
1700 | getLoopsNumber(), llvm::omp::OMPD_for)]); |
||
1701 | } |
||
1702 | const Expr *getTaskReductionRefExpr() const { |
||
1703 | return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); |
||
1704 | } |
||
1705 | |||
1706 | /// Return true if current directive has inner cancel directive. |
||
1707 | bool hasCancel() const { return HasCancel; } |
||
1708 | |||
1709 | static bool classof(const Stmt *T) { |
||
1710 | return T->getStmtClass() == OMPForDirectiveClass; |
||
1711 | } |
||
1712 | }; |
||
1713 | |||
1714 | /// This represents '#pragma omp for simd' directive. |
||
1715 | /// |
||
1716 | /// \code |
||
1717 | /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) |
||
1718 | /// \endcode |
||
1719 | /// In this example directive '#pragma omp for simd' has clauses 'private' |
||
1720 | /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and |
||
1721 | /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. |
||
1722 | /// |
||
1723 | class OMPForSimdDirective : public OMPLoopDirective { |
||
1724 | friend class ASTStmtReader; |
||
1725 | friend class OMPExecutableDirective; |
||
1726 | /// Build directive with the given start and end location. |
||
1727 | /// |
||
1728 | /// \param StartLoc Starting location of the directive kind. |
||
1729 | /// \param EndLoc Ending location of the directive. |
||
1730 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1731 | /// |
||
1732 | OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
1733 | unsigned CollapsedNum) |
||
1734 | : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, |
||
1735 | StartLoc, EndLoc, CollapsedNum) {} |
||
1736 | |||
1737 | /// Build an empty directive. |
||
1738 | /// |
||
1739 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1740 | /// |
||
1741 | explicit OMPForSimdDirective(unsigned CollapsedNum) |
||
1742 | : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, |
||
1743 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
1744 | |||
1745 | public: |
||
1746 | /// Creates directive with a list of \a Clauses. |
||
1747 | /// |
||
1748 | /// \param C AST context. |
||
1749 | /// \param StartLoc Starting location of the directive kind. |
||
1750 | /// \param EndLoc Ending Location of the directive. |
||
1751 | /// \param CollapsedNum Number of collapsed loops. |
||
1752 | /// \param Clauses List of clauses. |
||
1753 | /// \param AssociatedStmt Statement, associated with the directive. |
||
1754 | /// \param Exprs Helper expressions for CodeGen. |
||
1755 | /// |
||
1756 | static OMPForSimdDirective * |
||
1757 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
1758 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
1759 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
1760 | |||
1761 | /// Creates an empty directive with the place |
||
1762 | /// for \a NumClauses clauses. |
||
1763 | /// |
||
1764 | /// \param C AST context. |
||
1765 | /// \param CollapsedNum Number of collapsed nested loops. |
||
1766 | /// \param NumClauses Number of clauses. |
||
1767 | /// |
||
1768 | static OMPForSimdDirective *CreateEmpty(const ASTContext &C, |
||
1769 | unsigned NumClauses, |
||
1770 | unsigned CollapsedNum, EmptyShell); |
||
1771 | |||
1772 | static bool classof(const Stmt *T) { |
||
1773 | return T->getStmtClass() == OMPForSimdDirectiveClass; |
||
1774 | } |
||
1775 | }; |
||
1776 | |||
1777 | /// This represents '#pragma omp sections' directive. |
||
1778 | /// |
||
1779 | /// \code |
||
1780 | /// #pragma omp sections private(a,b) reduction(+:c,d) |
||
1781 | /// \endcode |
||
1782 | /// In this example directive '#pragma omp sections' has clauses 'private' with |
||
1783 | /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables |
||
1784 | /// 'c' and 'd'. |
||
1785 | /// |
||
1786 | class OMPSectionsDirective : public OMPExecutableDirective { |
||
1787 | friend class ASTStmtReader; |
||
1788 | friend class OMPExecutableDirective; |
||
1789 | |||
1790 | /// true if current directive has inner cancel directive. |
||
1791 | bool HasCancel = false; |
||
1792 | |||
1793 | /// Build directive with the given start and end location. |
||
1794 | /// |
||
1795 | /// \param StartLoc Starting location of the directive kind. |
||
1796 | /// \param EndLoc Ending location of the directive. |
||
1797 | /// |
||
1798 | OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
1799 | : OMPExecutableDirective(OMPSectionsDirectiveClass, |
||
1800 | llvm::omp::OMPD_sections, StartLoc, EndLoc) {} |
||
1801 | |||
1802 | /// Build an empty directive. |
||
1803 | /// |
||
1804 | explicit OMPSectionsDirective() |
||
1805 | : OMPExecutableDirective(OMPSectionsDirectiveClass, |
||
1806 | llvm::omp::OMPD_sections, SourceLocation(), |
||
1807 | SourceLocation()) {} |
||
1808 | |||
1809 | /// Sets special task reduction descriptor. |
||
1810 | void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
||
1811 | |||
1812 | /// Set cancel state. |
||
1813 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
1814 | |||
1815 | public: |
||
1816 | /// Creates directive with a list of \a Clauses. |
||
1817 | /// |
||
1818 | /// \param C AST context. |
||
1819 | /// \param StartLoc Starting location of the directive kind. |
||
1820 | /// \param EndLoc Ending Location of the directive. |
||
1821 | /// \param Clauses List of clauses. |
||
1822 | /// \param AssociatedStmt Statement, associated with the directive. |
||
1823 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
1824 | /// taskgroup descriptor. |
||
1825 | /// \param HasCancel true if current directive has inner directive. |
||
1826 | /// |
||
1827 | static OMPSectionsDirective * |
||
1828 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
1829 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
||
1830 | bool HasCancel); |
||
1831 | |||
1832 | /// Creates an empty directive with the place for \a NumClauses |
||
1833 | /// clauses. |
||
1834 | /// |
||
1835 | /// \param C AST context. |
||
1836 | /// \param NumClauses Number of clauses. |
||
1837 | /// |
||
1838 | static OMPSectionsDirective *CreateEmpty(const ASTContext &C, |
||
1839 | unsigned NumClauses, EmptyShell); |
||
1840 | |||
1841 | /// Returns special task reduction reference expression. |
||
1842 | Expr *getTaskReductionRefExpr() { |
||
1843 | return cast_or_null<Expr>(Data->getChildren()[0]); |
||
1844 | } |
||
1845 | const Expr *getTaskReductionRefExpr() const { |
||
1846 | return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); |
||
1847 | } |
||
1848 | |||
1849 | /// Return true if current directive has inner cancel directive. |
||
1850 | bool hasCancel() const { return HasCancel; } |
||
1851 | |||
1852 | static bool classof(const Stmt *T) { |
||
1853 | return T->getStmtClass() == OMPSectionsDirectiveClass; |
||
1854 | } |
||
1855 | }; |
||
1856 | |||
1857 | /// This represents '#pragma omp section' directive. |
||
1858 | /// |
||
1859 | /// \code |
||
1860 | /// #pragma omp section |
||
1861 | /// \endcode |
||
1862 | /// |
||
1863 | class OMPSectionDirective : public OMPExecutableDirective { |
||
1864 | friend class ASTStmtReader; |
||
1865 | friend class OMPExecutableDirective; |
||
1866 | |||
1867 | /// true if current directive has inner cancel directive. |
||
1868 | bool HasCancel = false; |
||
1869 | |||
1870 | /// Build directive with the given start and end location. |
||
1871 | /// |
||
1872 | /// \param StartLoc Starting location of the directive kind. |
||
1873 | /// \param EndLoc Ending location of the directive. |
||
1874 | /// |
||
1875 | OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
1876 | : OMPExecutableDirective(OMPSectionDirectiveClass, |
||
1877 | llvm::omp::OMPD_section, StartLoc, EndLoc) {} |
||
1878 | |||
1879 | /// Build an empty directive. |
||
1880 | /// |
||
1881 | explicit OMPSectionDirective() |
||
1882 | : OMPExecutableDirective(OMPSectionDirectiveClass, |
||
1883 | llvm::omp::OMPD_section, SourceLocation(), |
||
1884 | SourceLocation()) {} |
||
1885 | |||
1886 | public: |
||
1887 | /// Creates directive. |
||
1888 | /// |
||
1889 | /// \param C AST context. |
||
1890 | /// \param StartLoc Starting location of the directive kind. |
||
1891 | /// \param EndLoc Ending Location of the directive. |
||
1892 | /// \param AssociatedStmt Statement, associated with the directive. |
||
1893 | /// \param HasCancel true if current directive has inner directive. |
||
1894 | /// |
||
1895 | static OMPSectionDirective *Create(const ASTContext &C, |
||
1896 | SourceLocation StartLoc, |
||
1897 | SourceLocation EndLoc, |
||
1898 | Stmt *AssociatedStmt, bool HasCancel); |
||
1899 | |||
1900 | /// Creates an empty directive. |
||
1901 | /// |
||
1902 | /// \param C AST context. |
||
1903 | /// |
||
1904 | static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
||
1905 | |||
1906 | /// Set cancel state. |
||
1907 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
1908 | |||
1909 | /// Return true if current directive has inner cancel directive. |
||
1910 | bool hasCancel() const { return HasCancel; } |
||
1911 | |||
1912 | static bool classof(const Stmt *T) { |
||
1913 | return T->getStmtClass() == OMPSectionDirectiveClass; |
||
1914 | } |
||
1915 | }; |
||
1916 | |||
1917 | /// This represents '#pragma omp single' directive. |
||
1918 | /// |
||
1919 | /// \code |
||
1920 | /// #pragma omp single private(a,b) copyprivate(c,d) |
||
1921 | /// \endcode |
||
1922 | /// In this example directive '#pragma omp single' has clauses 'private' with |
||
1923 | /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. |
||
1924 | /// |
||
1925 | class OMPSingleDirective : public OMPExecutableDirective { |
||
1926 | friend class ASTStmtReader; |
||
1927 | friend class OMPExecutableDirective; |
||
1928 | /// Build directive with the given start and end location. |
||
1929 | /// |
||
1930 | /// \param StartLoc Starting location of the directive kind. |
||
1931 | /// \param EndLoc Ending location of the directive. |
||
1932 | /// |
||
1933 | OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
1934 | : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, |
||
1935 | StartLoc, EndLoc) {} |
||
1936 | |||
1937 | /// Build an empty directive. |
||
1938 | /// |
||
1939 | explicit OMPSingleDirective() |
||
1940 | : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, |
||
1941 | SourceLocation(), SourceLocation()) {} |
||
1942 | |||
1943 | public: |
||
1944 | /// Creates directive with a list of \a Clauses. |
||
1945 | /// |
||
1946 | /// \param C AST context. |
||
1947 | /// \param StartLoc Starting location of the directive kind. |
||
1948 | /// \param EndLoc Ending Location of the directive. |
||
1949 | /// \param Clauses List of clauses. |
||
1950 | /// \param AssociatedStmt Statement, associated with the directive. |
||
1951 | /// |
||
1952 | static OMPSingleDirective * |
||
1953 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
1954 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
1955 | |||
1956 | /// Creates an empty directive with the place for \a NumClauses |
||
1957 | /// clauses. |
||
1958 | /// |
||
1959 | /// \param C AST context. |
||
1960 | /// \param NumClauses Number of clauses. |
||
1961 | /// |
||
1962 | static OMPSingleDirective *CreateEmpty(const ASTContext &C, |
||
1963 | unsigned NumClauses, EmptyShell); |
||
1964 | |||
1965 | static bool classof(const Stmt *T) { |
||
1966 | return T->getStmtClass() == OMPSingleDirectiveClass; |
||
1967 | } |
||
1968 | }; |
||
1969 | |||
1970 | /// This represents '#pragma omp master' directive. |
||
1971 | /// |
||
1972 | /// \code |
||
1973 | /// #pragma omp master |
||
1974 | /// \endcode |
||
1975 | /// |
||
1976 | class OMPMasterDirective : public OMPExecutableDirective { |
||
1977 | friend class ASTStmtReader; |
||
1978 | friend class OMPExecutableDirective; |
||
1979 | /// Build directive with the given start and end location. |
||
1980 | /// |
||
1981 | /// \param StartLoc Starting location of the directive kind. |
||
1982 | /// \param EndLoc Ending location of the directive. |
||
1983 | /// |
||
1984 | OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
1985 | : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, |
||
1986 | StartLoc, EndLoc) {} |
||
1987 | |||
1988 | /// Build an empty directive. |
||
1989 | /// |
||
1990 | explicit OMPMasterDirective() |
||
1991 | : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, |
||
1992 | SourceLocation(), SourceLocation()) {} |
||
1993 | |||
1994 | public: |
||
1995 | /// Creates directive. |
||
1996 | /// |
||
1997 | /// \param C AST context. |
||
1998 | /// \param StartLoc Starting location of the directive kind. |
||
1999 | /// \param EndLoc Ending Location of the directive. |
||
2000 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2001 | /// |
||
2002 | static OMPMasterDirective *Create(const ASTContext &C, |
||
2003 | SourceLocation StartLoc, |
||
2004 | SourceLocation EndLoc, |
||
2005 | Stmt *AssociatedStmt); |
||
2006 | |||
2007 | /// Creates an empty directive. |
||
2008 | /// |
||
2009 | /// \param C AST context. |
||
2010 | /// |
||
2011 | static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
||
2012 | |||
2013 | static bool classof(const Stmt *T) { |
||
2014 | return T->getStmtClass() == OMPMasterDirectiveClass; |
||
2015 | } |
||
2016 | }; |
||
2017 | |||
2018 | /// This represents '#pragma omp critical' directive. |
||
2019 | /// |
||
2020 | /// \code |
||
2021 | /// #pragma omp critical |
||
2022 | /// \endcode |
||
2023 | /// |
||
2024 | class OMPCriticalDirective : public OMPExecutableDirective { |
||
2025 | friend class ASTStmtReader; |
||
2026 | friend class OMPExecutableDirective; |
||
2027 | /// Name of the directive. |
||
2028 | DeclarationNameInfo DirName; |
||
2029 | /// Build directive with the given start and end location. |
||
2030 | /// |
||
2031 | /// \param Name Name of the directive. |
||
2032 | /// \param StartLoc Starting location of the directive kind. |
||
2033 | /// \param EndLoc Ending location of the directive. |
||
2034 | /// |
||
2035 | OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, |
||
2036 | SourceLocation EndLoc) |
||
2037 | : OMPExecutableDirective(OMPCriticalDirectiveClass, |
||
2038 | llvm::omp::OMPD_critical, StartLoc, EndLoc), |
||
2039 | DirName(Name) {} |
||
2040 | |||
2041 | /// Build an empty directive. |
||
2042 | /// |
||
2043 | explicit OMPCriticalDirective() |
||
2044 | : OMPExecutableDirective(OMPCriticalDirectiveClass, |
||
2045 | llvm::omp::OMPD_critical, SourceLocation(), |
||
2046 | SourceLocation()) {} |
||
2047 | |||
2048 | /// Set name of the directive. |
||
2049 | /// |
||
2050 | /// \param Name Name of the directive. |
||
2051 | /// |
||
2052 | void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } |
||
2053 | |||
2054 | public: |
||
2055 | /// Creates directive. |
||
2056 | /// |
||
2057 | /// \param C AST context. |
||
2058 | /// \param Name Name of the directive. |
||
2059 | /// \param StartLoc Starting location of the directive kind. |
||
2060 | /// \param EndLoc Ending Location of the directive. |
||
2061 | /// \param Clauses List of clauses. |
||
2062 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2063 | /// |
||
2064 | static OMPCriticalDirective * |
||
2065 | Create(const ASTContext &C, const DeclarationNameInfo &Name, |
||
2066 | SourceLocation StartLoc, SourceLocation EndLoc, |
||
2067 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
2068 | |||
2069 | /// Creates an empty directive. |
||
2070 | /// |
||
2071 | /// \param C AST context. |
||
2072 | /// \param NumClauses Number of clauses. |
||
2073 | /// |
||
2074 | static OMPCriticalDirective *CreateEmpty(const ASTContext &C, |
||
2075 | unsigned NumClauses, EmptyShell); |
||
2076 | |||
2077 | /// Return name of the directive. |
||
2078 | /// |
||
2079 | DeclarationNameInfo getDirectiveName() const { return DirName; } |
||
2080 | |||
2081 | static bool classof(const Stmt *T) { |
||
2082 | return T->getStmtClass() == OMPCriticalDirectiveClass; |
||
2083 | } |
||
2084 | }; |
||
2085 | |||
2086 | /// This represents '#pragma omp parallel for' directive. |
||
2087 | /// |
||
2088 | /// \code |
||
2089 | /// #pragma omp parallel for private(a,b) reduction(+:c,d) |
||
2090 | /// \endcode |
||
2091 | /// In this example directive '#pragma omp parallel for' has clauses 'private' |
||
2092 | /// with the variables 'a' and 'b' and 'reduction' with operator '+' and |
||
2093 | /// variables 'c' and 'd'. |
||
2094 | /// |
||
2095 | class OMPParallelForDirective : public OMPLoopDirective { |
||
2096 | friend class ASTStmtReader; |
||
2097 | friend class OMPExecutableDirective; |
||
2098 | |||
2099 | /// true if current region has inner cancel directive. |
||
2100 | bool HasCancel = false; |
||
2101 | |||
2102 | /// Build directive with the given start and end location. |
||
2103 | /// |
||
2104 | /// \param StartLoc Starting location of the directive kind. |
||
2105 | /// \param EndLoc Ending location of the directive. |
||
2106 | /// \param CollapsedNum Number of collapsed nested loops. |
||
2107 | /// |
||
2108 | OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
2109 | unsigned CollapsedNum) |
||
2110 | : OMPLoopDirective(OMPParallelForDirectiveClass, |
||
2111 | llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, |
||
2112 | CollapsedNum) {} |
||
2113 | |||
2114 | /// Build an empty directive. |
||
2115 | /// |
||
2116 | /// \param CollapsedNum Number of collapsed nested loops. |
||
2117 | /// |
||
2118 | explicit OMPParallelForDirective(unsigned CollapsedNum) |
||
2119 | : OMPLoopDirective(OMPParallelForDirectiveClass, |
||
2120 | llvm::omp::OMPD_parallel_for, SourceLocation(), |
||
2121 | SourceLocation(), CollapsedNum) {} |
||
2122 | |||
2123 | /// Sets special task reduction descriptor. |
||
2124 | void setTaskReductionRefExpr(Expr *E) { |
||
2125 | Data->getChildren()[numLoopChildren(getLoopsNumber(), |
||
2126 | llvm::omp::OMPD_parallel_for)] = E; |
||
2127 | } |
||
2128 | |||
2129 | /// Set cancel state. |
||
2130 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
2131 | |||
2132 | public: |
||
2133 | /// Creates directive with a list of \a Clauses. |
||
2134 | /// |
||
2135 | /// \param C AST context. |
||
2136 | /// \param StartLoc Starting location of the directive kind. |
||
2137 | /// \param EndLoc Ending Location of the directive. |
||
2138 | /// \param CollapsedNum Number of collapsed loops. |
||
2139 | /// \param Clauses List of clauses. |
||
2140 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2141 | /// \param Exprs Helper expressions for CodeGen. |
||
2142 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
2143 | /// taskgroup descriptor. |
||
2144 | /// \param HasCancel true if current directive has inner cancel directive. |
||
2145 | /// |
||
2146 | static OMPParallelForDirective * |
||
2147 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
2148 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
2149 | Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
||
2150 | bool HasCancel); |
||
2151 | |||
2152 | /// Creates an empty directive with the place |
||
2153 | /// for \a NumClauses clauses. |
||
2154 | /// |
||
2155 | /// \param C AST context. |
||
2156 | /// \param CollapsedNum Number of collapsed nested loops. |
||
2157 | /// \param NumClauses Number of clauses. |
||
2158 | /// |
||
2159 | static OMPParallelForDirective *CreateEmpty(const ASTContext &C, |
||
2160 | unsigned NumClauses, |
||
2161 | unsigned CollapsedNum, |
||
2162 | EmptyShell); |
||
2163 | |||
2164 | /// Returns special task reduction reference expression. |
||
2165 | Expr *getTaskReductionRefExpr() { |
||
2166 | return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
||
2167 | getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); |
||
2168 | } |
||
2169 | const Expr *getTaskReductionRefExpr() const { |
||
2170 | return const_cast<OMPParallelForDirective *>(this) |
||
2171 | ->getTaskReductionRefExpr(); |
||
2172 | } |
||
2173 | |||
2174 | /// Return true if current directive has inner cancel directive. |
||
2175 | bool hasCancel() const { return HasCancel; } |
||
2176 | |||
2177 | static bool classof(const Stmt *T) { |
||
2178 | return T->getStmtClass() == OMPParallelForDirectiveClass; |
||
2179 | } |
||
2180 | }; |
||
2181 | |||
2182 | /// This represents '#pragma omp parallel for simd' directive. |
||
2183 | /// |
||
2184 | /// \code |
||
2185 | /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) |
||
2186 | /// \endcode |
||
2187 | /// In this example directive '#pragma omp parallel for simd' has clauses |
||
2188 | /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' |
||
2189 | /// and linear step 's', 'reduction' with operator '+' and variables 'c' and |
||
2190 | /// 'd'. |
||
2191 | /// |
||
2192 | class OMPParallelForSimdDirective : public OMPLoopDirective { |
||
2193 | friend class ASTStmtReader; |
||
2194 | friend class OMPExecutableDirective; |
||
2195 | /// Build directive with the given start and end location. |
||
2196 | /// |
||
2197 | /// \param StartLoc Starting location of the directive kind. |
||
2198 | /// \param EndLoc Ending location of the directive. |
||
2199 | /// \param CollapsedNum Number of collapsed nested loops. |
||
2200 | /// |
||
2201 | OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
2202 | unsigned CollapsedNum) |
||
2203 | : OMPLoopDirective(OMPParallelForSimdDirectiveClass, |
||
2204 | llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, |
||
2205 | CollapsedNum) {} |
||
2206 | |||
2207 | /// Build an empty directive. |
||
2208 | /// |
||
2209 | /// \param CollapsedNum Number of collapsed nested loops. |
||
2210 | /// |
||
2211 | explicit OMPParallelForSimdDirective(unsigned CollapsedNum) |
||
2212 | : OMPLoopDirective(OMPParallelForSimdDirectiveClass, |
||
2213 | llvm::omp::OMPD_parallel_for_simd, SourceLocation(), |
||
2214 | SourceLocation(), CollapsedNum) {} |
||
2215 | |||
2216 | public: |
||
2217 | /// Creates directive with a list of \a Clauses. |
||
2218 | /// |
||
2219 | /// \param C AST context. |
||
2220 | /// \param StartLoc Starting location of the directive kind. |
||
2221 | /// \param EndLoc Ending Location of the directive. |
||
2222 | /// \param CollapsedNum Number of collapsed loops. |
||
2223 | /// \param Clauses List of clauses. |
||
2224 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2225 | /// \param Exprs Helper expressions for CodeGen. |
||
2226 | /// |
||
2227 | static OMPParallelForSimdDirective * |
||
2228 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
2229 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
2230 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
2231 | |||
2232 | /// Creates an empty directive with the place |
||
2233 | /// for \a NumClauses clauses. |
||
2234 | /// |
||
2235 | /// \param C AST context. |
||
2236 | /// \param CollapsedNum Number of collapsed nested loops. |
||
2237 | /// \param NumClauses Number of clauses. |
||
2238 | /// |
||
2239 | static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, |
||
2240 | unsigned NumClauses, |
||
2241 | unsigned CollapsedNum, |
||
2242 | EmptyShell); |
||
2243 | |||
2244 | static bool classof(const Stmt *T) { |
||
2245 | return T->getStmtClass() == OMPParallelForSimdDirectiveClass; |
||
2246 | } |
||
2247 | }; |
||
2248 | |||
2249 | /// This represents '#pragma omp parallel master' directive. |
||
2250 | /// |
||
2251 | /// \code |
||
2252 | /// #pragma omp parallel master private(a,b) |
||
2253 | /// \endcode |
||
2254 | /// In this example directive '#pragma omp parallel master' has clauses |
||
2255 | /// 'private' with the variables 'a' and 'b' |
||
2256 | /// |
||
2257 | class OMPParallelMasterDirective : public OMPExecutableDirective { |
||
2258 | friend class ASTStmtReader; |
||
2259 | friend class OMPExecutableDirective; |
||
2260 | |||
2261 | OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2262 | : OMPExecutableDirective(OMPParallelMasterDirectiveClass, |
||
2263 | llvm::omp::OMPD_parallel_master, StartLoc, |
||
2264 | EndLoc) {} |
||
2265 | |||
2266 | explicit OMPParallelMasterDirective() |
||
2267 | : OMPExecutableDirective(OMPParallelMasterDirectiveClass, |
||
2268 | llvm::omp::OMPD_parallel_master, |
||
2269 | SourceLocation(), SourceLocation()) {} |
||
2270 | |||
2271 | /// Sets special task reduction descriptor. |
||
2272 | void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
||
2273 | |||
2274 | public: |
||
2275 | /// Creates directive with a list of \a Clauses. |
||
2276 | /// |
||
2277 | /// \param C AST context. |
||
2278 | /// \param StartLoc Starting location of the directive kind. |
||
2279 | /// \param EndLoc Ending Location of the directive. |
||
2280 | /// \param Clauses List of clauses. |
||
2281 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2282 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
2283 | /// taskgroup descriptor. |
||
2284 | /// |
||
2285 | static OMPParallelMasterDirective * |
||
2286 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
2287 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); |
||
2288 | |||
2289 | /// Creates an empty directive with the place for \a NumClauses |
||
2290 | /// clauses. |
||
2291 | /// |
||
2292 | /// \param C AST context. |
||
2293 | /// \param NumClauses Number of clauses. |
||
2294 | /// |
||
2295 | static OMPParallelMasterDirective * |
||
2296 | CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); |
||
2297 | |||
2298 | /// Returns special task reduction reference expression. |
||
2299 | Expr *getTaskReductionRefExpr() { |
||
2300 | return cast_or_null<Expr>(Data->getChildren()[0]); |
||
2301 | } |
||
2302 | const Expr *getTaskReductionRefExpr() const { |
||
2303 | return const_cast<OMPParallelMasterDirective *>(this) |
||
2304 | ->getTaskReductionRefExpr(); |
||
2305 | } |
||
2306 | |||
2307 | static bool classof(const Stmt *T) { |
||
2308 | return T->getStmtClass() == OMPParallelMasterDirectiveClass; |
||
2309 | } |
||
2310 | }; |
||
2311 | |||
2312 | /// This represents '#pragma omp parallel masked' directive. |
||
2313 | /// |
||
2314 | /// \code |
||
2315 | /// #pragma omp parallel masked filter(tid) |
||
2316 | /// \endcode |
||
2317 | /// In this example directive '#pragma omp parallel masked' has a clause |
||
2318 | /// 'filter' with the variable tid |
||
2319 | /// |
||
2320 | class OMPParallelMaskedDirective final : public OMPExecutableDirective { |
||
2321 | friend class ASTStmtReader; |
||
2322 | friend class OMPExecutableDirective; |
||
2323 | |||
2324 | OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2325 | : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, |
||
2326 | llvm::omp::OMPD_parallel_masked, StartLoc, |
||
2327 | EndLoc) {} |
||
2328 | |||
2329 | explicit OMPParallelMaskedDirective() |
||
2330 | : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, |
||
2331 | llvm::omp::OMPD_parallel_masked, |
||
2332 | SourceLocation(), SourceLocation()) {} |
||
2333 | |||
2334 | /// Sets special task reduction descriptor. |
||
2335 | void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
||
2336 | |||
2337 | public: |
||
2338 | /// Creates directive with a list of \a Clauses. |
||
2339 | /// |
||
2340 | /// \param C AST context. |
||
2341 | /// \param StartLoc Starting location of the directive kind. |
||
2342 | /// \param EndLoc Ending Location of the directive. |
||
2343 | /// \param Clauses List of clauses. |
||
2344 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2345 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
2346 | /// taskgroup descriptor. |
||
2347 | /// |
||
2348 | static OMPParallelMaskedDirective * |
||
2349 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
2350 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); |
||
2351 | |||
2352 | /// Creates an empty directive with the place for \a NumClauses |
||
2353 | /// clauses. |
||
2354 | /// |
||
2355 | /// \param C AST context. |
||
2356 | /// \param NumClauses Number of clauses. |
||
2357 | /// |
||
2358 | static OMPParallelMaskedDirective * |
||
2359 | CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); |
||
2360 | |||
2361 | /// Returns special task reduction reference expression. |
||
2362 | Expr *getTaskReductionRefExpr() { |
||
2363 | return cast_or_null<Expr>(Data->getChildren()[0]); |
||
2364 | } |
||
2365 | const Expr *getTaskReductionRefExpr() const { |
||
2366 | return const_cast<OMPParallelMaskedDirective *>(this) |
||
2367 | ->getTaskReductionRefExpr(); |
||
2368 | } |
||
2369 | |||
2370 | static bool classof(const Stmt *T) { |
||
2371 | return T->getStmtClass() == OMPParallelMaskedDirectiveClass; |
||
2372 | } |
||
2373 | }; |
||
2374 | |||
2375 | /// This represents '#pragma omp parallel sections' directive. |
||
2376 | /// |
||
2377 | /// \code |
||
2378 | /// #pragma omp parallel sections private(a,b) reduction(+:c,d) |
||
2379 | /// \endcode |
||
2380 | /// In this example directive '#pragma omp parallel sections' has clauses |
||
2381 | /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' |
||
2382 | /// and variables 'c' and 'd'. |
||
2383 | /// |
||
2384 | class OMPParallelSectionsDirective : public OMPExecutableDirective { |
||
2385 | friend class ASTStmtReader; |
||
2386 | friend class OMPExecutableDirective; |
||
2387 | |||
2388 | /// true if current directive has inner cancel directive. |
||
2389 | bool HasCancel = false; |
||
2390 | |||
2391 | /// Build directive with the given start and end location. |
||
2392 | /// |
||
2393 | /// \param StartLoc Starting location of the directive kind. |
||
2394 | /// \param EndLoc Ending location of the directive. |
||
2395 | /// |
||
2396 | OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2397 | : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, |
||
2398 | llvm::omp::OMPD_parallel_sections, StartLoc, |
||
2399 | EndLoc) {} |
||
2400 | |||
2401 | /// Build an empty directive. |
||
2402 | /// |
||
2403 | explicit OMPParallelSectionsDirective() |
||
2404 | : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, |
||
2405 | llvm::omp::OMPD_parallel_sections, |
||
2406 | SourceLocation(), SourceLocation()) {} |
||
2407 | |||
2408 | /// Sets special task reduction descriptor. |
||
2409 | void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
||
2410 | |||
2411 | /// Set cancel state. |
||
2412 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
2413 | |||
2414 | public: |
||
2415 | /// Creates directive with a list of \a Clauses. |
||
2416 | /// |
||
2417 | /// \param C AST context. |
||
2418 | /// \param StartLoc Starting location of the directive kind. |
||
2419 | /// \param EndLoc Ending Location of the directive. |
||
2420 | /// \param Clauses List of clauses. |
||
2421 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2422 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
2423 | /// taskgroup descriptor. |
||
2424 | /// \param HasCancel true if current directive has inner cancel directive. |
||
2425 | /// |
||
2426 | static OMPParallelSectionsDirective * |
||
2427 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
2428 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
||
2429 | bool HasCancel); |
||
2430 | |||
2431 | /// Creates an empty directive with the place for \a NumClauses |
||
2432 | /// clauses. |
||
2433 | /// |
||
2434 | /// \param C AST context. |
||
2435 | /// \param NumClauses Number of clauses. |
||
2436 | /// |
||
2437 | static OMPParallelSectionsDirective * |
||
2438 | CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); |
||
2439 | |||
2440 | /// Returns special task reduction reference expression. |
||
2441 | Expr *getTaskReductionRefExpr() { |
||
2442 | return cast_or_null<Expr>(Data->getChildren()[0]); |
||
2443 | } |
||
2444 | const Expr *getTaskReductionRefExpr() const { |
||
2445 | return const_cast<OMPParallelSectionsDirective *>(this) |
||
2446 | ->getTaskReductionRefExpr(); |
||
2447 | } |
||
2448 | |||
2449 | /// Return true if current directive has inner cancel directive. |
||
2450 | bool hasCancel() const { return HasCancel; } |
||
2451 | |||
2452 | static bool classof(const Stmt *T) { |
||
2453 | return T->getStmtClass() == OMPParallelSectionsDirectiveClass; |
||
2454 | } |
||
2455 | }; |
||
2456 | |||
2457 | /// This represents '#pragma omp task' directive. |
||
2458 | /// |
||
2459 | /// \code |
||
2460 | /// #pragma omp task private(a,b) final(d) |
||
2461 | /// \endcode |
||
2462 | /// In this example directive '#pragma omp task' has clauses 'private' with the |
||
2463 | /// variables 'a' and 'b' and 'final' with condition 'd'. |
||
2464 | /// |
||
2465 | class OMPTaskDirective : public OMPExecutableDirective { |
||
2466 | friend class ASTStmtReader; |
||
2467 | friend class OMPExecutableDirective; |
||
2468 | /// true if this directive has inner cancel directive. |
||
2469 | bool HasCancel = false; |
||
2470 | |||
2471 | /// Build directive with the given start and end location. |
||
2472 | /// |
||
2473 | /// \param StartLoc Starting location of the directive kind. |
||
2474 | /// \param EndLoc Ending location of the directive. |
||
2475 | /// |
||
2476 | OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2477 | : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, |
||
2478 | StartLoc, EndLoc) {} |
||
2479 | |||
2480 | /// Build an empty directive. |
||
2481 | /// |
||
2482 | explicit OMPTaskDirective() |
||
2483 | : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, |
||
2484 | SourceLocation(), SourceLocation()) {} |
||
2485 | |||
2486 | /// Set cancel state. |
||
2487 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
2488 | |||
2489 | public: |
||
2490 | /// Creates directive with a list of \a Clauses. |
||
2491 | /// |
||
2492 | /// \param C AST context. |
||
2493 | /// \param StartLoc Starting location of the directive kind. |
||
2494 | /// \param EndLoc Ending Location of the directive. |
||
2495 | /// \param Clauses List of clauses. |
||
2496 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2497 | /// \param HasCancel true, if current directive has inner cancel directive. |
||
2498 | /// |
||
2499 | static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
2500 | SourceLocation EndLoc, |
||
2501 | ArrayRef<OMPClause *> Clauses, |
||
2502 | Stmt *AssociatedStmt, bool HasCancel); |
||
2503 | |||
2504 | /// Creates an empty directive with the place for \a NumClauses |
||
2505 | /// clauses. |
||
2506 | /// |
||
2507 | /// \param C AST context. |
||
2508 | /// \param NumClauses Number of clauses. |
||
2509 | /// |
||
2510 | static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
||
2511 | EmptyShell); |
||
2512 | |||
2513 | /// Return true if current directive has inner cancel directive. |
||
2514 | bool hasCancel() const { return HasCancel; } |
||
2515 | |||
2516 | static bool classof(const Stmt *T) { |
||
2517 | return T->getStmtClass() == OMPTaskDirectiveClass; |
||
2518 | } |
||
2519 | }; |
||
2520 | |||
2521 | /// This represents '#pragma omp taskyield' directive. |
||
2522 | /// |
||
2523 | /// \code |
||
2524 | /// #pragma omp taskyield |
||
2525 | /// \endcode |
||
2526 | /// |
||
2527 | class OMPTaskyieldDirective : public OMPExecutableDirective { |
||
2528 | friend class ASTStmtReader; |
||
2529 | friend class OMPExecutableDirective; |
||
2530 | /// Build directive with the given start and end location. |
||
2531 | /// |
||
2532 | /// \param StartLoc Starting location of the directive kind. |
||
2533 | /// \param EndLoc Ending location of the directive. |
||
2534 | /// |
||
2535 | OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2536 | : OMPExecutableDirective(OMPTaskyieldDirectiveClass, |
||
2537 | llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} |
||
2538 | |||
2539 | /// Build an empty directive. |
||
2540 | /// |
||
2541 | explicit OMPTaskyieldDirective() |
||
2542 | : OMPExecutableDirective(OMPTaskyieldDirectiveClass, |
||
2543 | llvm::omp::OMPD_taskyield, SourceLocation(), |
||
2544 | SourceLocation()) {} |
||
2545 | |||
2546 | public: |
||
2547 | /// Creates directive. |
||
2548 | /// |
||
2549 | /// \param C AST context. |
||
2550 | /// \param StartLoc Starting location of the directive kind. |
||
2551 | /// \param EndLoc Ending Location of the directive. |
||
2552 | /// |
||
2553 | static OMPTaskyieldDirective * |
||
2554 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); |
||
2555 | |||
2556 | /// Creates an empty directive. |
||
2557 | /// |
||
2558 | /// \param C AST context. |
||
2559 | /// |
||
2560 | static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
||
2561 | |||
2562 | static bool classof(const Stmt *T) { |
||
2563 | return T->getStmtClass() == OMPTaskyieldDirectiveClass; |
||
2564 | } |
||
2565 | }; |
||
2566 | |||
2567 | /// This represents '#pragma omp barrier' directive. |
||
2568 | /// |
||
2569 | /// \code |
||
2570 | /// #pragma omp barrier |
||
2571 | /// \endcode |
||
2572 | /// |
||
2573 | class OMPBarrierDirective : public OMPExecutableDirective { |
||
2574 | friend class ASTStmtReader; |
||
2575 | friend class OMPExecutableDirective; |
||
2576 | /// Build directive with the given start and end location. |
||
2577 | /// |
||
2578 | /// \param StartLoc Starting location of the directive kind. |
||
2579 | /// \param EndLoc Ending location of the directive. |
||
2580 | /// |
||
2581 | OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2582 | : OMPExecutableDirective(OMPBarrierDirectiveClass, |
||
2583 | llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} |
||
2584 | |||
2585 | /// Build an empty directive. |
||
2586 | /// |
||
2587 | explicit OMPBarrierDirective() |
||
2588 | : OMPExecutableDirective(OMPBarrierDirectiveClass, |
||
2589 | llvm::omp::OMPD_barrier, SourceLocation(), |
||
2590 | SourceLocation()) {} |
||
2591 | |||
2592 | public: |
||
2593 | /// Creates directive. |
||
2594 | /// |
||
2595 | /// \param C AST context. |
||
2596 | /// \param StartLoc Starting location of the directive kind. |
||
2597 | /// \param EndLoc Ending Location of the directive. |
||
2598 | /// |
||
2599 | static OMPBarrierDirective * |
||
2600 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); |
||
2601 | |||
2602 | /// Creates an empty directive. |
||
2603 | /// |
||
2604 | /// \param C AST context. |
||
2605 | /// |
||
2606 | static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
||
2607 | |||
2608 | static bool classof(const Stmt *T) { |
||
2609 | return T->getStmtClass() == OMPBarrierDirectiveClass; |
||
2610 | } |
||
2611 | }; |
||
2612 | |||
2613 | /// This represents '#pragma omp taskwait' directive. |
||
2614 | /// |
||
2615 | /// \code |
||
2616 | /// #pragma omp taskwait |
||
2617 | /// \endcode |
||
2618 | /// |
||
2619 | class OMPTaskwaitDirective : public OMPExecutableDirective { |
||
2620 | friend class ASTStmtReader; |
||
2621 | friend class OMPExecutableDirective; |
||
2622 | /// Build directive with the given start and end location. |
||
2623 | /// |
||
2624 | /// \param StartLoc Starting location of the directive kind. |
||
2625 | /// \param EndLoc Ending location of the directive. |
||
2626 | /// |
||
2627 | OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2628 | : OMPExecutableDirective(OMPTaskwaitDirectiveClass, |
||
2629 | llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} |
||
2630 | |||
2631 | /// Build an empty directive. |
||
2632 | /// |
||
2633 | explicit OMPTaskwaitDirective() |
||
2634 | : OMPExecutableDirective(OMPTaskwaitDirectiveClass, |
||
2635 | llvm::omp::OMPD_taskwait, SourceLocation(), |
||
2636 | SourceLocation()) {} |
||
2637 | |||
2638 | public: |
||
2639 | /// Creates directive. |
||
2640 | /// |
||
2641 | /// \param C AST context. |
||
2642 | /// \param StartLoc Starting location of the directive kind. |
||
2643 | /// \param EndLoc Ending Location of the directive. |
||
2644 | /// \param Clauses List of clauses. |
||
2645 | /// |
||
2646 | static OMPTaskwaitDirective *Create(const ASTContext &C, |
||
2647 | SourceLocation StartLoc, |
||
2648 | SourceLocation EndLoc, |
||
2649 | ArrayRef<OMPClause *> Clauses); |
||
2650 | |||
2651 | /// Creates an empty directive. |
||
2652 | /// |
||
2653 | /// \param C AST context. |
||
2654 | /// \param NumClauses Number of clauses. |
||
2655 | /// |
||
2656 | static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, |
||
2657 | unsigned NumClauses, EmptyShell); |
||
2658 | |||
2659 | static bool classof(const Stmt *T) { |
||
2660 | return T->getStmtClass() == OMPTaskwaitDirectiveClass; |
||
2661 | } |
||
2662 | }; |
||
2663 | |||
2664 | /// This represents '#pragma omp taskgroup' directive. |
||
2665 | /// |
||
2666 | /// \code |
||
2667 | /// #pragma omp taskgroup |
||
2668 | /// \endcode |
||
2669 | /// |
||
2670 | class OMPTaskgroupDirective : public OMPExecutableDirective { |
||
2671 | friend class ASTStmtReader; |
||
2672 | friend class OMPExecutableDirective; |
||
2673 | /// Build directive with the given start and end location. |
||
2674 | /// |
||
2675 | /// \param StartLoc Starting location of the directive kind. |
||
2676 | /// \param EndLoc Ending location of the directive. |
||
2677 | /// |
||
2678 | OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2679 | : OMPExecutableDirective(OMPTaskgroupDirectiveClass, |
||
2680 | llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} |
||
2681 | |||
2682 | /// Build an empty directive. |
||
2683 | /// |
||
2684 | explicit OMPTaskgroupDirective() |
||
2685 | : OMPExecutableDirective(OMPTaskgroupDirectiveClass, |
||
2686 | llvm::omp::OMPD_taskgroup, SourceLocation(), |
||
2687 | SourceLocation()) {} |
||
2688 | |||
2689 | /// Sets the task_reduction return variable. |
||
2690 | void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } |
||
2691 | |||
2692 | public: |
||
2693 | /// Creates directive. |
||
2694 | /// |
||
2695 | /// \param C AST context. |
||
2696 | /// \param StartLoc Starting location of the directive kind. |
||
2697 | /// \param EndLoc Ending Location of the directive. |
||
2698 | /// \param Clauses List of clauses. |
||
2699 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2700 | /// \param ReductionRef Reference to the task_reduction return variable. |
||
2701 | /// |
||
2702 | static OMPTaskgroupDirective * |
||
2703 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
2704 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, |
||
2705 | Expr *ReductionRef); |
||
2706 | |||
2707 | /// Creates an empty directive. |
||
2708 | /// |
||
2709 | /// \param C AST context. |
||
2710 | /// \param NumClauses Number of clauses. |
||
2711 | /// |
||
2712 | static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, |
||
2713 | unsigned NumClauses, EmptyShell); |
||
2714 | |||
2715 | |||
2716 | /// Returns reference to the task_reduction return variable. |
||
2717 | const Expr *getReductionRef() const { |
||
2718 | return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); |
||
2719 | } |
||
2720 | Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } |
||
2721 | |||
2722 | static bool classof(const Stmt *T) { |
||
2723 | return T->getStmtClass() == OMPTaskgroupDirectiveClass; |
||
2724 | } |
||
2725 | }; |
||
2726 | |||
2727 | /// This represents '#pragma omp flush' directive. |
||
2728 | /// |
||
2729 | /// \code |
||
2730 | /// #pragma omp flush(a,b) |
||
2731 | /// \endcode |
||
2732 | /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' |
||
2733 | /// and 'b'. |
||
2734 | /// 'omp flush' directive does not have clauses but have an optional list of |
||
2735 | /// variables to flush. This list of variables is stored within some fake clause |
||
2736 | /// FlushClause. |
||
2737 | class OMPFlushDirective : public OMPExecutableDirective { |
||
2738 | friend class ASTStmtReader; |
||
2739 | friend class OMPExecutableDirective; |
||
2740 | /// Build directive with the given start and end location. |
||
2741 | /// |
||
2742 | /// \param StartLoc Starting location of the directive kind. |
||
2743 | /// \param EndLoc Ending location of the directive. |
||
2744 | /// |
||
2745 | OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2746 | : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, |
||
2747 | StartLoc, EndLoc) {} |
||
2748 | |||
2749 | /// Build an empty directive. |
||
2750 | /// |
||
2751 | explicit OMPFlushDirective() |
||
2752 | : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, |
||
2753 | SourceLocation(), SourceLocation()) {} |
||
2754 | |||
2755 | public: |
||
2756 | /// Creates directive with a list of \a Clauses. |
||
2757 | /// |
||
2758 | /// \param C AST context. |
||
2759 | /// \param StartLoc Starting location of the directive kind. |
||
2760 | /// \param EndLoc Ending Location of the directive. |
||
2761 | /// \param Clauses List of clauses (only single OMPFlushClause clause is |
||
2762 | /// allowed). |
||
2763 | /// |
||
2764 | static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
2765 | SourceLocation EndLoc, |
||
2766 | ArrayRef<OMPClause *> Clauses); |
||
2767 | |||
2768 | /// Creates an empty directive with the place for \a NumClauses |
||
2769 | /// clauses. |
||
2770 | /// |
||
2771 | /// \param C AST context. |
||
2772 | /// \param NumClauses Number of clauses. |
||
2773 | /// |
||
2774 | static OMPFlushDirective *CreateEmpty(const ASTContext &C, |
||
2775 | unsigned NumClauses, EmptyShell); |
||
2776 | |||
2777 | static bool classof(const Stmt *T) { |
||
2778 | return T->getStmtClass() == OMPFlushDirectiveClass; |
||
2779 | } |
||
2780 | }; |
||
2781 | |||
2782 | /// This represents '#pragma omp depobj' directive. |
||
2783 | /// |
||
2784 | /// \code |
||
2785 | /// #pragma omp depobj(a) depend(in:x,y) |
||
2786 | /// \endcode |
||
2787 | /// In this example directive '#pragma omp depobj' initializes a depobj object |
||
2788 | /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. |
||
2789 | class OMPDepobjDirective final : public OMPExecutableDirective { |
||
2790 | friend class ASTStmtReader; |
||
2791 | friend class OMPExecutableDirective; |
||
2792 | |||
2793 | /// Build directive with the given start and end location. |
||
2794 | /// |
||
2795 | /// \param StartLoc Starting location of the directive kind. |
||
2796 | /// \param EndLoc Ending location of the directive. |
||
2797 | /// |
||
2798 | OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2799 | : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, |
||
2800 | StartLoc, EndLoc) {} |
||
2801 | |||
2802 | /// Build an empty directive. |
||
2803 | /// |
||
2804 | explicit OMPDepobjDirective() |
||
2805 | : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, |
||
2806 | SourceLocation(), SourceLocation()) {} |
||
2807 | |||
2808 | public: |
||
2809 | /// Creates directive with a list of \a Clauses. |
||
2810 | /// |
||
2811 | /// \param C AST context. |
||
2812 | /// \param StartLoc Starting location of the directive kind. |
||
2813 | /// \param EndLoc Ending Location of the directive. |
||
2814 | /// \param Clauses List of clauses. |
||
2815 | /// |
||
2816 | static OMPDepobjDirective *Create(const ASTContext &C, |
||
2817 | SourceLocation StartLoc, |
||
2818 | SourceLocation EndLoc, |
||
2819 | ArrayRef<OMPClause *> Clauses); |
||
2820 | |||
2821 | /// Creates an empty directive with the place for \a NumClauses |
||
2822 | /// clauses. |
||
2823 | /// |
||
2824 | /// \param C AST context. |
||
2825 | /// \param NumClauses Number of clauses. |
||
2826 | /// |
||
2827 | static OMPDepobjDirective *CreateEmpty(const ASTContext &C, |
||
2828 | unsigned NumClauses, EmptyShell); |
||
2829 | |||
2830 | static bool classof(const Stmt *T) { |
||
2831 | return T->getStmtClass() == OMPDepobjDirectiveClass; |
||
2832 | } |
||
2833 | }; |
||
2834 | |||
2835 | /// This represents '#pragma omp ordered' directive. |
||
2836 | /// |
||
2837 | /// \code |
||
2838 | /// #pragma omp ordered |
||
2839 | /// \endcode |
||
2840 | /// |
||
2841 | class OMPOrderedDirective : public OMPExecutableDirective { |
||
2842 | friend class ASTStmtReader; |
||
2843 | friend class OMPExecutableDirective; |
||
2844 | /// Build directive with the given start and end location. |
||
2845 | /// |
||
2846 | /// \param StartLoc Starting location of the directive kind. |
||
2847 | /// \param EndLoc Ending location of the directive. |
||
2848 | /// |
||
2849 | OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2850 | : OMPExecutableDirective(OMPOrderedDirectiveClass, |
||
2851 | llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} |
||
2852 | |||
2853 | /// Build an empty directive. |
||
2854 | /// |
||
2855 | explicit OMPOrderedDirective() |
||
2856 | : OMPExecutableDirective(OMPOrderedDirectiveClass, |
||
2857 | llvm::omp::OMPD_ordered, SourceLocation(), |
||
2858 | SourceLocation()) {} |
||
2859 | |||
2860 | public: |
||
2861 | /// Creates directive. |
||
2862 | /// |
||
2863 | /// \param C AST context. |
||
2864 | /// \param StartLoc Starting location of the directive kind. |
||
2865 | /// \param EndLoc Ending Location of the directive. |
||
2866 | /// \param Clauses List of clauses. |
||
2867 | /// \param AssociatedStmt Statement, associated with the directive. |
||
2868 | /// |
||
2869 | static OMPOrderedDirective * |
||
2870 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
2871 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
2872 | |||
2873 | /// Creates an empty directive. |
||
2874 | /// |
||
2875 | /// \param C AST context. |
||
2876 | /// \param NumClauses Number of clauses. |
||
2877 | /// \param IsStandalone true, if the standalone directive is created. |
||
2878 | /// |
||
2879 | static OMPOrderedDirective *CreateEmpty(const ASTContext &C, |
||
2880 | unsigned NumClauses, |
||
2881 | bool IsStandalone, EmptyShell); |
||
2882 | |||
2883 | static bool classof(const Stmt *T) { |
||
2884 | return T->getStmtClass() == OMPOrderedDirectiveClass; |
||
2885 | } |
||
2886 | }; |
||
2887 | |||
2888 | /// This represents '#pragma omp atomic' directive. |
||
2889 | /// |
||
2890 | /// \code |
||
2891 | /// #pragma omp atomic capture |
||
2892 | /// \endcode |
||
2893 | /// In this example directive '#pragma omp atomic' has clause 'capture'. |
||
2894 | /// |
||
2895 | class OMPAtomicDirective : public OMPExecutableDirective { |
||
2896 | friend class ASTStmtReader; |
||
2897 | friend class OMPExecutableDirective; |
||
2898 | |||
2899 | struct FlagTy { |
||
2900 | /// Used for 'atomic update' or 'atomic capture' constructs. They may |
||
2901 | /// have atomic expressions of forms: |
||
2902 | /// \code |
||
2903 | /// x = x binop expr; |
||
2904 | /// x = expr binop x; |
||
2905 | /// \endcode |
||
2906 | /// This field is 1 for the first form of the expression and 0 for the |
||
2907 | /// second. Required for correct codegen of non-associative operations (like |
||
2908 | /// << or >>). |
||
2909 | uint8_t IsXLHSInRHSPart : 1; |
||
2910 | /// Used for 'atomic update' or 'atomic capture' constructs. They may |
||
2911 | /// have atomic expressions of forms: |
||
2912 | /// \code |
||
2913 | /// v = x; <update x>; |
||
2914 | /// <update x>; v = x; |
||
2915 | /// \endcode |
||
2916 | /// This field is 1 for the first(postfix) form of the expression and 0 |
||
2917 | /// otherwise. |
||
2918 | uint8_t IsPostfixUpdate : 1; |
||
2919 | /// 1 if 'v' is updated only when the condition is false (compare capture |
||
2920 | /// only). |
||
2921 | uint8_t IsFailOnly : 1; |
||
2922 | } Flags; |
||
2923 | |||
2924 | /// Build directive with the given start and end location. |
||
2925 | /// |
||
2926 | /// \param StartLoc Starting location of the directive kind. |
||
2927 | /// \param EndLoc Ending location of the directive. |
||
2928 | /// |
||
2929 | OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
2930 | : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, |
||
2931 | StartLoc, EndLoc) {} |
||
2932 | |||
2933 | /// Build an empty directive. |
||
2934 | /// |
||
2935 | explicit OMPAtomicDirective() |
||
2936 | : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, |
||
2937 | SourceLocation(), SourceLocation()) {} |
||
2938 | |||
2939 | enum DataPositionTy : size_t { |
||
2940 | POS_X = 0, |
||
2941 | POS_V, |
||
2942 | POS_E, |
||
2943 | POS_UpdateExpr, |
||
2944 | POS_D, |
||
2945 | POS_Cond, |
||
2946 | POS_R, |
||
2947 | }; |
||
2948 | |||
2949 | /// Set 'x' part of the associated expression/statement. |
||
2950 | void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; } |
||
2951 | /// Set helper expression of the form |
||
2952 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
||
2953 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
||
2954 | void setUpdateExpr(Expr *UE) { |
||
2955 | Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; |
||
2956 | } |
||
2957 | /// Set 'v' part of the associated expression/statement. |
||
2958 | void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } |
||
2959 | /// Set 'r' part of the associated expression/statement. |
||
2960 | void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; } |
||
2961 | /// Set 'expr' part of the associated expression/statement. |
||
2962 | void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } |
||
2963 | /// Set 'd' part of the associated expression/statement. |
||
2964 | void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } |
||
2965 | /// Set conditional expression in `atomic compare`. |
||
2966 | void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } |
||
2967 | |||
2968 | public: |
||
2969 | struct Expressions { |
||
2970 | /// 'x' part of the associated expression/statement. |
||
2971 | Expr *X = nullptr; |
||
2972 | /// 'v' part of the associated expression/statement. |
||
2973 | Expr *V = nullptr; |
||
2974 | // 'r' part of the associated expression/statement. |
||
2975 | Expr *R = nullptr; |
||
2976 | /// 'expr' part of the associated expression/statement. |
||
2977 | Expr *E = nullptr; |
||
2978 | /// UE Helper expression of the form: |
||
2979 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
||
2980 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
||
2981 | Expr *UE = nullptr; |
||
2982 | /// 'd' part of the associated expression/statement. |
||
2983 | Expr *D = nullptr; |
||
2984 | /// Conditional expression in `atomic compare` construct. |
||
2985 | Expr *Cond = nullptr; |
||
2986 | /// True if UE has the first form and false if the second. |
||
2987 | bool IsXLHSInRHSPart; |
||
2988 | /// True if original value of 'x' must be stored in 'v', not an updated one. |
||
2989 | bool IsPostfixUpdate; |
||
2990 | /// True if 'v' is updated only when the condition is false (compare capture |
||
2991 | /// only). |
||
2992 | bool IsFailOnly; |
||
2993 | }; |
||
2994 | |||
2995 | /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' |
||
2996 | /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for |
||
2997 | /// detailed description of 'x', 'v' and 'expr'). |
||
2998 | /// |
||
2999 | /// \param C AST context. |
||
3000 | /// \param StartLoc Starting location of the directive kind. |
||
3001 | /// \param EndLoc Ending Location of the directive. |
||
3002 | /// \param Clauses List of clauses. |
||
3003 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3004 | /// \param Exprs Associated expressions or statements. |
||
3005 | static OMPAtomicDirective *Create(const ASTContext &C, |
||
3006 | SourceLocation StartLoc, |
||
3007 | SourceLocation EndLoc, |
||
3008 | ArrayRef<OMPClause *> Clauses, |
||
3009 | Stmt *AssociatedStmt, Expressions Exprs); |
||
3010 | |||
3011 | /// Creates an empty directive with the place for \a NumClauses |
||
3012 | /// clauses. |
||
3013 | /// |
||
3014 | /// \param C AST context. |
||
3015 | /// \param NumClauses Number of clauses. |
||
3016 | /// |
||
3017 | static OMPAtomicDirective *CreateEmpty(const ASTContext &C, |
||
3018 | unsigned NumClauses, EmptyShell); |
||
3019 | |||
3020 | /// Get 'x' part of the associated expression/statement. |
||
3021 | Expr *getX() { |
||
3022 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); |
||
3023 | } |
||
3024 | const Expr *getX() const { |
||
3025 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); |
||
3026 | } |
||
3027 | /// Get helper expression of the form |
||
3028 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
||
3029 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
||
3030 | Expr *getUpdateExpr() { |
||
3031 | return cast_or_null<Expr>( |
||
3032 | Data->getChildren()[DataPositionTy::POS_UpdateExpr]); |
||
3033 | } |
||
3034 | const Expr *getUpdateExpr() const { |
||
3035 | return cast_or_null<Expr>( |
||
3036 | Data->getChildren()[DataPositionTy::POS_UpdateExpr]); |
||
3037 | } |
||
3038 | /// Return true if helper update expression has form |
||
3039 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form |
||
3040 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
||
3041 | bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; } |
||
3042 | /// Return true if 'v' expression must be updated to original value of |
||
3043 | /// 'x', false if 'v' must be updated to the new value of 'x'. |
||
3044 | bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; } |
||
3045 | /// Return true if 'v' is updated only when the condition is evaluated false |
||
3046 | /// (compare capture only). |
||
3047 | bool isFailOnly() const { return Flags.IsFailOnly; } |
||
3048 | /// Get 'v' part of the associated expression/statement. |
||
3049 | Expr *getV() { |
||
3050 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); |
||
3051 | } |
||
3052 | const Expr *getV() const { |
||
3053 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); |
||
3054 | } |
||
3055 | /// Get 'r' part of the associated expression/statement. |
||
3056 | Expr *getR() { |
||
3057 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); |
||
3058 | } |
||
3059 | const Expr *getR() const { |
||
3060 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); |
||
3061 | } |
||
3062 | /// Get 'expr' part of the associated expression/statement. |
||
3063 | Expr *getExpr() { |
||
3064 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); |
||
3065 | } |
||
3066 | const Expr *getExpr() const { |
||
3067 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); |
||
3068 | } |
||
3069 | /// Get 'd' part of the associated expression/statement. |
||
3070 | Expr *getD() { |
||
3071 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); |
||
3072 | } |
||
3073 | Expr *getD() const { |
||
3074 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); |
||
3075 | } |
||
3076 | /// Get the 'cond' part of the source atomic expression. |
||
3077 | Expr *getCondExpr() { |
||
3078 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); |
||
3079 | } |
||
3080 | Expr *getCondExpr() const { |
||
3081 | return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); |
||
3082 | } |
||
3083 | |||
3084 | static bool classof(const Stmt *T) { |
||
3085 | return T->getStmtClass() == OMPAtomicDirectiveClass; |
||
3086 | } |
||
3087 | }; |
||
3088 | |||
3089 | /// This represents '#pragma omp target' directive. |
||
3090 | /// |
||
3091 | /// \code |
||
3092 | /// #pragma omp target if(a) |
||
3093 | /// \endcode |
||
3094 | /// In this example directive '#pragma omp target' has clause 'if' with |
||
3095 | /// condition 'a'. |
||
3096 | /// |
||
3097 | class OMPTargetDirective : public OMPExecutableDirective { |
||
3098 | friend class ASTStmtReader; |
||
3099 | friend class OMPExecutableDirective; |
||
3100 | /// Build directive with the given start and end location. |
||
3101 | /// |
||
3102 | /// \param StartLoc Starting location of the directive kind. |
||
3103 | /// \param EndLoc Ending location of the directive. |
||
3104 | /// |
||
3105 | OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3106 | : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, |
||
3107 | StartLoc, EndLoc) {} |
||
3108 | |||
3109 | /// Build an empty directive. |
||
3110 | /// |
||
3111 | explicit OMPTargetDirective() |
||
3112 | : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, |
||
3113 | SourceLocation(), SourceLocation()) {} |
||
3114 | |||
3115 | public: |
||
3116 | /// Creates directive with a list of \a Clauses. |
||
3117 | /// |
||
3118 | /// \param C AST context. |
||
3119 | /// \param StartLoc Starting location of the directive kind. |
||
3120 | /// \param EndLoc Ending Location of the directive. |
||
3121 | /// \param Clauses List of clauses. |
||
3122 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3123 | /// |
||
3124 | static OMPTargetDirective * |
||
3125 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3126 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
3127 | |||
3128 | /// Creates an empty directive with the place for \a NumClauses |
||
3129 | /// clauses. |
||
3130 | /// |
||
3131 | /// \param C AST context. |
||
3132 | /// \param NumClauses Number of clauses. |
||
3133 | /// |
||
3134 | static OMPTargetDirective *CreateEmpty(const ASTContext &C, |
||
3135 | unsigned NumClauses, EmptyShell); |
||
3136 | |||
3137 | static bool classof(const Stmt *T) { |
||
3138 | return T->getStmtClass() == OMPTargetDirectiveClass; |
||
3139 | } |
||
3140 | }; |
||
3141 | |||
3142 | /// This represents '#pragma omp target data' directive. |
||
3143 | /// |
||
3144 | /// \code |
||
3145 | /// #pragma omp target data device(0) if(a) map(b[:]) |
||
3146 | /// \endcode |
||
3147 | /// In this example directive '#pragma omp target data' has clauses 'device' |
||
3148 | /// with the value '0', 'if' with condition 'a' and 'map' with array |
||
3149 | /// section 'b[:]'. |
||
3150 | /// |
||
3151 | class OMPTargetDataDirective : public OMPExecutableDirective { |
||
3152 | friend class ASTStmtReader; |
||
3153 | friend class OMPExecutableDirective; |
||
3154 | /// Build directive with the given start and end location. |
||
3155 | /// |
||
3156 | /// \param StartLoc Starting location of the directive kind. |
||
3157 | /// \param EndLoc Ending Location of the directive. |
||
3158 | /// |
||
3159 | OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3160 | : OMPExecutableDirective(OMPTargetDataDirectiveClass, |
||
3161 | llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} |
||
3162 | |||
3163 | /// Build an empty directive. |
||
3164 | /// |
||
3165 | explicit OMPTargetDataDirective() |
||
3166 | : OMPExecutableDirective(OMPTargetDataDirectiveClass, |
||
3167 | llvm::omp::OMPD_target_data, SourceLocation(), |
||
3168 | SourceLocation()) {} |
||
3169 | |||
3170 | public: |
||
3171 | /// Creates directive with a list of \a Clauses. |
||
3172 | /// |
||
3173 | /// \param C AST context. |
||
3174 | /// \param StartLoc Starting location of the directive kind. |
||
3175 | /// \param EndLoc Ending Location of the directive. |
||
3176 | /// \param Clauses List of clauses. |
||
3177 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3178 | /// |
||
3179 | static OMPTargetDataDirective * |
||
3180 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3181 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
3182 | |||
3183 | /// Creates an empty directive with the place for \a N clauses. |
||
3184 | /// |
||
3185 | /// \param C AST context. |
||
3186 | /// \param N The number of clauses. |
||
3187 | /// |
||
3188 | static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, |
||
3189 | EmptyShell); |
||
3190 | |||
3191 | static bool classof(const Stmt *T) { |
||
3192 | return T->getStmtClass() == OMPTargetDataDirectiveClass; |
||
3193 | } |
||
3194 | }; |
||
3195 | |||
3196 | /// This represents '#pragma omp target enter data' directive. |
||
3197 | /// |
||
3198 | /// \code |
||
3199 | /// #pragma omp target enter data device(0) if(a) map(b[:]) |
||
3200 | /// \endcode |
||
3201 | /// In this example directive '#pragma omp target enter data' has clauses |
||
3202 | /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array |
||
3203 | /// section 'b[:]'. |
||
3204 | /// |
||
3205 | class OMPTargetEnterDataDirective : public OMPExecutableDirective { |
||
3206 | friend class ASTStmtReader; |
||
3207 | friend class OMPExecutableDirective; |
||
3208 | /// Build directive with the given start and end location. |
||
3209 | /// |
||
3210 | /// \param StartLoc Starting location of the directive kind. |
||
3211 | /// \param EndLoc Ending Location of the directive. |
||
3212 | /// |
||
3213 | OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3214 | : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, |
||
3215 | llvm::omp::OMPD_target_enter_data, StartLoc, |
||
3216 | EndLoc) {} |
||
3217 | |||
3218 | /// Build an empty directive. |
||
3219 | /// |
||
3220 | explicit OMPTargetEnterDataDirective() |
||
3221 | : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, |
||
3222 | llvm::omp::OMPD_target_enter_data, |
||
3223 | SourceLocation(), SourceLocation()) {} |
||
3224 | |||
3225 | public: |
||
3226 | /// Creates directive with a list of \a Clauses. |
||
3227 | /// |
||
3228 | /// \param C AST context. |
||
3229 | /// \param StartLoc Starting location of the directive kind. |
||
3230 | /// \param EndLoc Ending Location of the directive. |
||
3231 | /// \param Clauses List of clauses. |
||
3232 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3233 | /// |
||
3234 | static OMPTargetEnterDataDirective * |
||
3235 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3236 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
3237 | |||
3238 | /// Creates an empty directive with the place for \a N clauses. |
||
3239 | /// |
||
3240 | /// \param C AST context. |
||
3241 | /// \param N The number of clauses. |
||
3242 | /// |
||
3243 | static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, |
||
3244 | unsigned N, EmptyShell); |
||
3245 | |||
3246 | static bool classof(const Stmt *T) { |
||
3247 | return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; |
||
3248 | } |
||
3249 | }; |
||
3250 | |||
3251 | /// This represents '#pragma omp target exit data' directive. |
||
3252 | /// |
||
3253 | /// \code |
||
3254 | /// #pragma omp target exit data device(0) if(a) map(b[:]) |
||
3255 | /// \endcode |
||
3256 | /// In this example directive '#pragma omp target exit data' has clauses |
||
3257 | /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array |
||
3258 | /// section 'b[:]'. |
||
3259 | /// |
||
3260 | class OMPTargetExitDataDirective : public OMPExecutableDirective { |
||
3261 | friend class ASTStmtReader; |
||
3262 | friend class OMPExecutableDirective; |
||
3263 | /// Build directive with the given start and end location. |
||
3264 | /// |
||
3265 | /// \param StartLoc Starting location of the directive kind. |
||
3266 | /// \param EndLoc Ending Location of the directive. |
||
3267 | /// |
||
3268 | OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3269 | : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, |
||
3270 | llvm::omp::OMPD_target_exit_data, StartLoc, |
||
3271 | EndLoc) {} |
||
3272 | |||
3273 | /// Build an empty directive. |
||
3274 | /// |
||
3275 | explicit OMPTargetExitDataDirective() |
||
3276 | : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, |
||
3277 | llvm::omp::OMPD_target_exit_data, |
||
3278 | SourceLocation(), SourceLocation()) {} |
||
3279 | |||
3280 | public: |
||
3281 | /// Creates directive with a list of \a Clauses. |
||
3282 | /// |
||
3283 | /// \param C AST context. |
||
3284 | /// \param StartLoc Starting location of the directive kind. |
||
3285 | /// \param EndLoc Ending Location of the directive. |
||
3286 | /// \param Clauses List of clauses. |
||
3287 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3288 | /// |
||
3289 | static OMPTargetExitDataDirective * |
||
3290 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3291 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
3292 | |||
3293 | /// Creates an empty directive with the place for \a N clauses. |
||
3294 | /// |
||
3295 | /// \param C AST context. |
||
3296 | /// \param N The number of clauses. |
||
3297 | /// |
||
3298 | static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, |
||
3299 | unsigned N, EmptyShell); |
||
3300 | |||
3301 | static bool classof(const Stmt *T) { |
||
3302 | return T->getStmtClass() == OMPTargetExitDataDirectiveClass; |
||
3303 | } |
||
3304 | }; |
||
3305 | |||
3306 | /// This represents '#pragma omp target parallel' directive. |
||
3307 | /// |
||
3308 | /// \code |
||
3309 | /// #pragma omp target parallel if(a) |
||
3310 | /// \endcode |
||
3311 | /// In this example directive '#pragma omp target parallel' has clause 'if' with |
||
3312 | /// condition 'a'. |
||
3313 | /// |
||
3314 | class OMPTargetParallelDirective : public OMPExecutableDirective { |
||
3315 | friend class ASTStmtReader; |
||
3316 | friend class OMPExecutableDirective; |
||
3317 | /// true if the construct has inner cancel directive. |
||
3318 | bool HasCancel = false; |
||
3319 | |||
3320 | /// Build directive with the given start and end location. |
||
3321 | /// |
||
3322 | /// \param StartLoc Starting location of the directive kind. |
||
3323 | /// \param EndLoc Ending location of the directive. |
||
3324 | /// |
||
3325 | OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3326 | : OMPExecutableDirective(OMPTargetParallelDirectiveClass, |
||
3327 | llvm::omp::OMPD_target_parallel, StartLoc, |
||
3328 | EndLoc) {} |
||
3329 | |||
3330 | /// Build an empty directive. |
||
3331 | /// |
||
3332 | explicit OMPTargetParallelDirective() |
||
3333 | : OMPExecutableDirective(OMPTargetParallelDirectiveClass, |
||
3334 | llvm::omp::OMPD_target_parallel, |
||
3335 | SourceLocation(), SourceLocation()) {} |
||
3336 | |||
3337 | /// Sets special task reduction descriptor. |
||
3338 | void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
||
3339 | /// Set cancel state. |
||
3340 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
3341 | |||
3342 | public: |
||
3343 | /// Creates directive with a list of \a Clauses. |
||
3344 | /// |
||
3345 | /// \param C AST context. |
||
3346 | /// \param StartLoc Starting location of the directive kind. |
||
3347 | /// \param EndLoc Ending Location of the directive. |
||
3348 | /// \param Clauses List of clauses. |
||
3349 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3350 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
3351 | /// taskgroup descriptor. |
||
3352 | /// \param HasCancel true if this directive has inner cancel directive. |
||
3353 | /// |
||
3354 | static OMPTargetParallelDirective * |
||
3355 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3356 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
||
3357 | bool HasCancel); |
||
3358 | |||
3359 | /// Creates an empty directive with the place for \a NumClauses |
||
3360 | /// clauses. |
||
3361 | /// |
||
3362 | /// \param C AST context. |
||
3363 | /// \param NumClauses Number of clauses. |
||
3364 | /// |
||
3365 | static OMPTargetParallelDirective * |
||
3366 | CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); |
||
3367 | |||
3368 | /// Returns special task reduction reference expression. |
||
3369 | Expr *getTaskReductionRefExpr() { |
||
3370 | return cast_or_null<Expr>(Data->getChildren()[0]); |
||
3371 | } |
||
3372 | const Expr *getTaskReductionRefExpr() const { |
||
3373 | return const_cast<OMPTargetParallelDirective *>(this) |
||
3374 | ->getTaskReductionRefExpr(); |
||
3375 | } |
||
3376 | |||
3377 | /// Return true if current directive has inner cancel directive. |
||
3378 | bool hasCancel() const { return HasCancel; } |
||
3379 | |||
3380 | static bool classof(const Stmt *T) { |
||
3381 | return T->getStmtClass() == OMPTargetParallelDirectiveClass; |
||
3382 | } |
||
3383 | }; |
||
3384 | |||
3385 | /// This represents '#pragma omp target parallel for' directive. |
||
3386 | /// |
||
3387 | /// \code |
||
3388 | /// #pragma omp target parallel for private(a,b) reduction(+:c,d) |
||
3389 | /// \endcode |
||
3390 | /// In this example directive '#pragma omp target parallel for' has clauses |
||
3391 | /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' |
||
3392 | /// and variables 'c' and 'd'. |
||
3393 | /// |
||
3394 | class OMPTargetParallelForDirective : public OMPLoopDirective { |
||
3395 | friend class ASTStmtReader; |
||
3396 | friend class OMPExecutableDirective; |
||
3397 | |||
3398 | /// true if current region has inner cancel directive. |
||
3399 | bool HasCancel = false; |
||
3400 | |||
3401 | /// Build directive with the given start and end location. |
||
3402 | /// |
||
3403 | /// \param StartLoc Starting location of the directive kind. |
||
3404 | /// \param EndLoc Ending location of the directive. |
||
3405 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3406 | /// |
||
3407 | OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
3408 | unsigned CollapsedNum) |
||
3409 | : OMPLoopDirective(OMPTargetParallelForDirectiveClass, |
||
3410 | llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, |
||
3411 | CollapsedNum) {} |
||
3412 | |||
3413 | /// Build an empty directive. |
||
3414 | /// |
||
3415 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3416 | /// |
||
3417 | explicit OMPTargetParallelForDirective(unsigned CollapsedNum) |
||
3418 | : OMPLoopDirective(OMPTargetParallelForDirectiveClass, |
||
3419 | llvm::omp::OMPD_target_parallel_for, SourceLocation(), |
||
3420 | SourceLocation(), CollapsedNum) {} |
||
3421 | |||
3422 | /// Sets special task reduction descriptor. |
||
3423 | void setTaskReductionRefExpr(Expr *E) { |
||
3424 | Data->getChildren()[numLoopChildren( |
||
3425 | getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; |
||
3426 | } |
||
3427 | |||
3428 | /// Set cancel state. |
||
3429 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
3430 | |||
3431 | public: |
||
3432 | /// Creates directive with a list of \a Clauses. |
||
3433 | /// |
||
3434 | /// \param C AST context. |
||
3435 | /// \param StartLoc Starting location of the directive kind. |
||
3436 | /// \param EndLoc Ending Location of the directive. |
||
3437 | /// \param CollapsedNum Number of collapsed loops. |
||
3438 | /// \param Clauses List of clauses. |
||
3439 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3440 | /// \param Exprs Helper expressions for CodeGen. |
||
3441 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
3442 | /// taskgroup descriptor. |
||
3443 | /// \param HasCancel true if current directive has inner cancel directive. |
||
3444 | /// |
||
3445 | static OMPTargetParallelForDirective * |
||
3446 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3447 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
3448 | Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
||
3449 | bool HasCancel); |
||
3450 | |||
3451 | /// Creates an empty directive with the place |
||
3452 | /// for \a NumClauses clauses. |
||
3453 | /// |
||
3454 | /// \param C AST context. |
||
3455 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3456 | /// \param NumClauses Number of clauses. |
||
3457 | /// |
||
3458 | static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, |
||
3459 | unsigned NumClauses, |
||
3460 | unsigned CollapsedNum, |
||
3461 | EmptyShell); |
||
3462 | |||
3463 | /// Returns special task reduction reference expression. |
||
3464 | Expr *getTaskReductionRefExpr() { |
||
3465 | return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
||
3466 | getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); |
||
3467 | } |
||
3468 | const Expr *getTaskReductionRefExpr() const { |
||
3469 | return const_cast<OMPTargetParallelForDirective *>(this) |
||
3470 | ->getTaskReductionRefExpr(); |
||
3471 | } |
||
3472 | |||
3473 | /// Return true if current directive has inner cancel directive. |
||
3474 | bool hasCancel() const { return HasCancel; } |
||
3475 | |||
3476 | static bool classof(const Stmt *T) { |
||
3477 | return T->getStmtClass() == OMPTargetParallelForDirectiveClass; |
||
3478 | } |
||
3479 | }; |
||
3480 | |||
3481 | /// This represents '#pragma omp teams' directive. |
||
3482 | /// |
||
3483 | /// \code |
||
3484 | /// #pragma omp teams if(a) |
||
3485 | /// \endcode |
||
3486 | /// In this example directive '#pragma omp teams' has clause 'if' with |
||
3487 | /// condition 'a'. |
||
3488 | /// |
||
3489 | class OMPTeamsDirective : public OMPExecutableDirective { |
||
3490 | friend class ASTStmtReader; |
||
3491 | friend class OMPExecutableDirective; |
||
3492 | /// Build directive with the given start and end location. |
||
3493 | /// |
||
3494 | /// \param StartLoc Starting location of the directive kind. |
||
3495 | /// \param EndLoc Ending location of the directive. |
||
3496 | /// |
||
3497 | OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3498 | : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, |
||
3499 | StartLoc, EndLoc) {} |
||
3500 | |||
3501 | /// Build an empty directive. |
||
3502 | /// |
||
3503 | explicit OMPTeamsDirective() |
||
3504 | : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, |
||
3505 | SourceLocation(), SourceLocation()) {} |
||
3506 | |||
3507 | public: |
||
3508 | /// Creates directive with a list of \a Clauses. |
||
3509 | /// |
||
3510 | /// \param C AST context. |
||
3511 | /// \param StartLoc Starting location of the directive kind. |
||
3512 | /// \param EndLoc Ending Location of the directive. |
||
3513 | /// \param Clauses List of clauses. |
||
3514 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3515 | /// |
||
3516 | static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
3517 | SourceLocation EndLoc, |
||
3518 | ArrayRef<OMPClause *> Clauses, |
||
3519 | Stmt *AssociatedStmt); |
||
3520 | |||
3521 | /// Creates an empty directive with the place for \a NumClauses |
||
3522 | /// clauses. |
||
3523 | /// |
||
3524 | /// \param C AST context. |
||
3525 | /// \param NumClauses Number of clauses. |
||
3526 | /// |
||
3527 | static OMPTeamsDirective *CreateEmpty(const ASTContext &C, |
||
3528 | unsigned NumClauses, EmptyShell); |
||
3529 | |||
3530 | static bool classof(const Stmt *T) { |
||
3531 | return T->getStmtClass() == OMPTeamsDirectiveClass; |
||
3532 | } |
||
3533 | }; |
||
3534 | |||
3535 | /// This represents '#pragma omp cancellation point' directive. |
||
3536 | /// |
||
3537 | /// \code |
||
3538 | /// #pragma omp cancellation point for |
||
3539 | /// \endcode |
||
3540 | /// |
||
3541 | /// In this example a cancellation point is created for innermost 'for' region. |
||
3542 | class OMPCancellationPointDirective : public OMPExecutableDirective { |
||
3543 | friend class ASTStmtReader; |
||
3544 | friend class OMPExecutableDirective; |
||
3545 | OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; |
||
3546 | /// Build directive with the given start and end location. |
||
3547 | /// |
||
3548 | /// \param StartLoc Starting location of the directive kind. |
||
3549 | /// \param EndLoc Ending location of the directive. |
||
3550 | /// statements and child expressions. |
||
3551 | /// |
||
3552 | OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3553 | : OMPExecutableDirective(OMPCancellationPointDirectiveClass, |
||
3554 | llvm::omp::OMPD_cancellation_point, StartLoc, |
||
3555 | EndLoc) {} |
||
3556 | |||
3557 | /// Build an empty directive. |
||
3558 | explicit OMPCancellationPointDirective() |
||
3559 | : OMPExecutableDirective(OMPCancellationPointDirectiveClass, |
||
3560 | llvm::omp::OMPD_cancellation_point, |
||
3561 | SourceLocation(), SourceLocation()) {} |
||
3562 | |||
3563 | /// Set cancel region for current cancellation point. |
||
3564 | /// \param CR Cancellation region. |
||
3565 | void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } |
||
3566 | |||
3567 | public: |
||
3568 | /// Creates directive. |
||
3569 | /// |
||
3570 | /// \param C AST context. |
||
3571 | /// \param StartLoc Starting location of the directive kind. |
||
3572 | /// \param EndLoc Ending Location of the directive. |
||
3573 | /// |
||
3574 | static OMPCancellationPointDirective * |
||
3575 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3576 | OpenMPDirectiveKind CancelRegion); |
||
3577 | |||
3578 | /// Creates an empty directive. |
||
3579 | /// |
||
3580 | /// \param C AST context. |
||
3581 | /// |
||
3582 | static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, |
||
3583 | EmptyShell); |
||
3584 | |||
3585 | /// Get cancellation region for the current cancellation point. |
||
3586 | OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } |
||
3587 | |||
3588 | static bool classof(const Stmt *T) { |
||
3589 | return T->getStmtClass() == OMPCancellationPointDirectiveClass; |
||
3590 | } |
||
3591 | }; |
||
3592 | |||
3593 | /// This represents '#pragma omp cancel' directive. |
||
3594 | /// |
||
3595 | /// \code |
||
3596 | /// #pragma omp cancel for |
||
3597 | /// \endcode |
||
3598 | /// |
||
3599 | /// In this example a cancel is created for innermost 'for' region. |
||
3600 | class OMPCancelDirective : public OMPExecutableDirective { |
||
3601 | friend class ASTStmtReader; |
||
3602 | friend class OMPExecutableDirective; |
||
3603 | OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; |
||
3604 | /// Build directive with the given start and end location. |
||
3605 | /// |
||
3606 | /// \param StartLoc Starting location of the directive kind. |
||
3607 | /// \param EndLoc Ending location of the directive. |
||
3608 | /// |
||
3609 | OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
3610 | : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, |
||
3611 | StartLoc, EndLoc) {} |
||
3612 | |||
3613 | /// Build an empty directive. |
||
3614 | /// |
||
3615 | explicit OMPCancelDirective() |
||
3616 | : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, |
||
3617 | SourceLocation(), SourceLocation()) {} |
||
3618 | |||
3619 | /// Set cancel region for current cancellation point. |
||
3620 | /// \param CR Cancellation region. |
||
3621 | void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } |
||
3622 | |||
3623 | public: |
||
3624 | /// Creates directive. |
||
3625 | /// |
||
3626 | /// \param C AST context. |
||
3627 | /// \param StartLoc Starting location of the directive kind. |
||
3628 | /// \param EndLoc Ending Location of the directive. |
||
3629 | /// \param Clauses List of clauses. |
||
3630 | /// |
||
3631 | static OMPCancelDirective * |
||
3632 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3633 | ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); |
||
3634 | |||
3635 | /// Creates an empty directive. |
||
3636 | /// |
||
3637 | /// \param C AST context. |
||
3638 | /// \param NumClauses Number of clauses. |
||
3639 | /// |
||
3640 | static OMPCancelDirective *CreateEmpty(const ASTContext &C, |
||
3641 | unsigned NumClauses, EmptyShell); |
||
3642 | |||
3643 | /// Get cancellation region for the current cancellation point. |
||
3644 | OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } |
||
3645 | |||
3646 | static bool classof(const Stmt *T) { |
||
3647 | return T->getStmtClass() == OMPCancelDirectiveClass; |
||
3648 | } |
||
3649 | }; |
||
3650 | |||
3651 | /// This represents '#pragma omp taskloop' directive. |
||
3652 | /// |
||
3653 | /// \code |
||
3654 | /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) |
||
3655 | /// \endcode |
||
3656 | /// In this example directive '#pragma omp taskloop' has clauses 'private' |
||
3657 | /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and |
||
3658 | /// 'num_tasks' with expression 'num'. |
||
3659 | /// |
||
3660 | class OMPTaskLoopDirective : public OMPLoopDirective { |
||
3661 | friend class ASTStmtReader; |
||
3662 | friend class OMPExecutableDirective; |
||
3663 | /// true if the construct has inner cancel directive. |
||
3664 | bool HasCancel = false; |
||
3665 | |||
3666 | /// Build directive with the given start and end location. |
||
3667 | /// |
||
3668 | /// \param StartLoc Starting location of the directive kind. |
||
3669 | /// \param EndLoc Ending location of the directive. |
||
3670 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3671 | /// |
||
3672 | OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
3673 | unsigned CollapsedNum) |
||
3674 | : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, |
||
3675 | StartLoc, EndLoc, CollapsedNum) {} |
||
3676 | |||
3677 | /// Build an empty directive. |
||
3678 | /// |
||
3679 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3680 | /// |
||
3681 | explicit OMPTaskLoopDirective(unsigned CollapsedNum) |
||
3682 | : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, |
||
3683 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
3684 | |||
3685 | /// Set cancel state. |
||
3686 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
3687 | |||
3688 | public: |
||
3689 | /// Creates directive with a list of \a Clauses. |
||
3690 | /// |
||
3691 | /// \param C AST context. |
||
3692 | /// \param StartLoc Starting location of the directive kind. |
||
3693 | /// \param EndLoc Ending Location of the directive. |
||
3694 | /// \param CollapsedNum Number of collapsed loops. |
||
3695 | /// \param Clauses List of clauses. |
||
3696 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3697 | /// \param Exprs Helper expressions for CodeGen. |
||
3698 | /// \param HasCancel true if this directive has inner cancel directive. |
||
3699 | /// |
||
3700 | static OMPTaskLoopDirective * |
||
3701 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3702 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
3703 | Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
||
3704 | |||
3705 | /// Creates an empty directive with the place |
||
3706 | /// for \a NumClauses clauses. |
||
3707 | /// |
||
3708 | /// \param C AST context. |
||
3709 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3710 | /// \param NumClauses Number of clauses. |
||
3711 | /// |
||
3712 | static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, |
||
3713 | unsigned NumClauses, |
||
3714 | unsigned CollapsedNum, EmptyShell); |
||
3715 | |||
3716 | /// Return true if current directive has inner cancel directive. |
||
3717 | bool hasCancel() const { return HasCancel; } |
||
3718 | |||
3719 | static bool classof(const Stmt *T) { |
||
3720 | return T->getStmtClass() == OMPTaskLoopDirectiveClass; |
||
3721 | } |
||
3722 | }; |
||
3723 | |||
3724 | /// This represents '#pragma omp taskloop simd' directive. |
||
3725 | /// |
||
3726 | /// \code |
||
3727 | /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) |
||
3728 | /// \endcode |
||
3729 | /// In this example directive '#pragma omp taskloop simd' has clauses 'private' |
||
3730 | /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and |
||
3731 | /// 'num_tasks' with expression 'num'. |
||
3732 | /// |
||
3733 | class OMPTaskLoopSimdDirective : public OMPLoopDirective { |
||
3734 | friend class ASTStmtReader; |
||
3735 | friend class OMPExecutableDirective; |
||
3736 | /// Build directive with the given start and end location. |
||
3737 | /// |
||
3738 | /// \param StartLoc Starting location of the directive kind. |
||
3739 | /// \param EndLoc Ending location of the directive. |
||
3740 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3741 | /// |
||
3742 | OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
3743 | unsigned CollapsedNum) |
||
3744 | : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, |
||
3745 | llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, |
||
3746 | CollapsedNum) {} |
||
3747 | |||
3748 | /// Build an empty directive. |
||
3749 | /// |
||
3750 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3751 | /// |
||
3752 | explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) |
||
3753 | : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, |
||
3754 | llvm::omp::OMPD_taskloop_simd, SourceLocation(), |
||
3755 | SourceLocation(), CollapsedNum) {} |
||
3756 | |||
3757 | public: |
||
3758 | /// Creates directive with a list of \a Clauses. |
||
3759 | /// |
||
3760 | /// \param C AST context. |
||
3761 | /// \param StartLoc Starting location of the directive kind. |
||
3762 | /// \param EndLoc Ending Location of the directive. |
||
3763 | /// \param CollapsedNum Number of collapsed loops. |
||
3764 | /// \param Clauses List of clauses. |
||
3765 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3766 | /// \param Exprs Helper expressions for CodeGen. |
||
3767 | /// |
||
3768 | static OMPTaskLoopSimdDirective * |
||
3769 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3770 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
3771 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
3772 | |||
3773 | /// Creates an empty directive with the place |
||
3774 | /// for \a NumClauses clauses. |
||
3775 | /// |
||
3776 | /// \param C AST context. |
||
3777 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3778 | /// \param NumClauses Number of clauses. |
||
3779 | /// |
||
3780 | static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, |
||
3781 | unsigned NumClauses, |
||
3782 | unsigned CollapsedNum, |
||
3783 | EmptyShell); |
||
3784 | |||
3785 | static bool classof(const Stmt *T) { |
||
3786 | return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; |
||
3787 | } |
||
3788 | }; |
||
3789 | |||
3790 | /// This represents '#pragma omp master taskloop' directive. |
||
3791 | /// |
||
3792 | /// \code |
||
3793 | /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) |
||
3794 | /// \endcode |
||
3795 | /// In this example directive '#pragma omp master taskloop' has clauses |
||
3796 | /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
||
3797 | /// and 'num_tasks' with expression 'num'. |
||
3798 | /// |
||
3799 | class OMPMasterTaskLoopDirective : public OMPLoopDirective { |
||
3800 | friend class ASTStmtReader; |
||
3801 | friend class OMPExecutableDirective; |
||
3802 | /// true if the construct has inner cancel directive. |
||
3803 | bool HasCancel = false; |
||
3804 | |||
3805 | /// Build directive with the given start and end location. |
||
3806 | /// |
||
3807 | /// \param StartLoc Starting location of the directive kind. |
||
3808 | /// \param EndLoc Ending location of the directive. |
||
3809 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3810 | /// |
||
3811 | OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
3812 | unsigned CollapsedNum) |
||
3813 | : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, |
||
3814 | llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, |
||
3815 | CollapsedNum) {} |
||
3816 | |||
3817 | /// Build an empty directive. |
||
3818 | /// |
||
3819 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3820 | /// |
||
3821 | explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) |
||
3822 | : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, |
||
3823 | llvm::omp::OMPD_master_taskloop, SourceLocation(), |
||
3824 | SourceLocation(), CollapsedNum) {} |
||
3825 | |||
3826 | /// Set cancel state. |
||
3827 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
3828 | |||
3829 | public: |
||
3830 | /// Creates directive with a list of \a Clauses. |
||
3831 | /// |
||
3832 | /// \param C AST context. |
||
3833 | /// \param StartLoc Starting location of the directive kind. |
||
3834 | /// \param EndLoc Ending Location of the directive. |
||
3835 | /// \param CollapsedNum Number of collapsed loops. |
||
3836 | /// \param Clauses List of clauses. |
||
3837 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3838 | /// \param Exprs Helper expressions for CodeGen. |
||
3839 | /// \param HasCancel true if this directive has inner cancel directive. |
||
3840 | /// |
||
3841 | static OMPMasterTaskLoopDirective * |
||
3842 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3843 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
3844 | Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
||
3845 | |||
3846 | /// Creates an empty directive with the place |
||
3847 | /// for \a NumClauses clauses. |
||
3848 | /// |
||
3849 | /// \param C AST context. |
||
3850 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3851 | /// \param NumClauses Number of clauses. |
||
3852 | /// |
||
3853 | static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, |
||
3854 | unsigned NumClauses, |
||
3855 | unsigned CollapsedNum, |
||
3856 | EmptyShell); |
||
3857 | |||
3858 | /// Return true if current directive has inner cancel directive. |
||
3859 | bool hasCancel() const { return HasCancel; } |
||
3860 | |||
3861 | static bool classof(const Stmt *T) { |
||
3862 | return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; |
||
3863 | } |
||
3864 | }; |
||
3865 | |||
3866 | /// This represents '#pragma omp masked taskloop' directive. |
||
3867 | /// |
||
3868 | /// \code |
||
3869 | /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num) |
||
3870 | /// \endcode |
||
3871 | /// In this example directive '#pragma omp masked taskloop' has clauses |
||
3872 | /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
||
3873 | /// and 'num_tasks' with expression 'num'. |
||
3874 | /// |
||
3875 | class OMPMaskedTaskLoopDirective final : public OMPLoopDirective { |
||
3876 | friend class ASTStmtReader; |
||
3877 | friend class OMPExecutableDirective; |
||
3878 | /// true if the construct has inner cancel directive. |
||
3879 | bool HasCancel = false; |
||
3880 | |||
3881 | /// Build directive with the given start and end location. |
||
3882 | /// |
||
3883 | /// \param StartLoc Starting location of the directive kind. |
||
3884 | /// \param EndLoc Ending location of the directive. |
||
3885 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3886 | /// |
||
3887 | OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
3888 | unsigned CollapsedNum) |
||
3889 | : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, |
||
3890 | llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc, |
||
3891 | CollapsedNum) {} |
||
3892 | |||
3893 | /// Build an empty directive. |
||
3894 | /// |
||
3895 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3896 | /// |
||
3897 | explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum) |
||
3898 | : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, |
||
3899 | llvm::omp::OMPD_masked_taskloop, SourceLocation(), |
||
3900 | SourceLocation(), CollapsedNum) {} |
||
3901 | |||
3902 | /// Set cancel state. |
||
3903 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
3904 | |||
3905 | public: |
||
3906 | /// Creates directive with a list of \a Clauses. |
||
3907 | /// |
||
3908 | /// \param C AST context. |
||
3909 | /// \param StartLoc Starting location of the directive kind. |
||
3910 | /// \param EndLoc Ending Location of the directive. |
||
3911 | /// \param CollapsedNum Number of collapsed loops. |
||
3912 | /// \param Clauses List of clauses. |
||
3913 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3914 | /// \param Exprs Helper expressions for CodeGen. |
||
3915 | /// \param HasCancel true if this directive has inner cancel directive. |
||
3916 | /// |
||
3917 | static OMPMaskedTaskLoopDirective * |
||
3918 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3919 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
3920 | Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
||
3921 | |||
3922 | /// Creates an empty directive with the place |
||
3923 | /// for \a NumClauses clauses. |
||
3924 | /// |
||
3925 | /// \param C AST context. |
||
3926 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3927 | /// \param NumClauses Number of clauses. |
||
3928 | /// |
||
3929 | static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, |
||
3930 | unsigned NumClauses, |
||
3931 | unsigned CollapsedNum, |
||
3932 | EmptyShell); |
||
3933 | |||
3934 | /// Return true if current directive has inner cancel directive. |
||
3935 | bool hasCancel() const { return HasCancel; } |
||
3936 | |||
3937 | static bool classof(const Stmt *T) { |
||
3938 | return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass; |
||
3939 | } |
||
3940 | }; |
||
3941 | |||
3942 | /// This represents '#pragma omp master taskloop simd' directive. |
||
3943 | /// |
||
3944 | /// \code |
||
3945 | /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) |
||
3946 | /// \endcode |
||
3947 | /// In this example directive '#pragma omp master taskloop simd' has clauses |
||
3948 | /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
||
3949 | /// and 'num_tasks' with expression 'num'. |
||
3950 | /// |
||
3951 | class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { |
||
3952 | friend class ASTStmtReader; |
||
3953 | friend class OMPExecutableDirective; |
||
3954 | /// Build directive with the given start and end location. |
||
3955 | /// |
||
3956 | /// \param StartLoc Starting location of the directive kind. |
||
3957 | /// \param EndLoc Ending location of the directive. |
||
3958 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3959 | /// |
||
3960 | OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
3961 | unsigned CollapsedNum) |
||
3962 | : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, |
||
3963 | llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, |
||
3964 | CollapsedNum) {} |
||
3965 | |||
3966 | /// Build an empty directive. |
||
3967 | /// |
||
3968 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3969 | /// |
||
3970 | explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) |
||
3971 | : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, |
||
3972 | llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), |
||
3973 | SourceLocation(), CollapsedNum) {} |
||
3974 | |||
3975 | public: |
||
3976 | /// Creates directive with a list of \p Clauses. |
||
3977 | /// |
||
3978 | /// \param C AST context. |
||
3979 | /// \param StartLoc Starting location of the directive kind. |
||
3980 | /// \param EndLoc Ending Location of the directive. |
||
3981 | /// \param CollapsedNum Number of collapsed loops. |
||
3982 | /// \param Clauses List of clauses. |
||
3983 | /// \param AssociatedStmt Statement, associated with the directive. |
||
3984 | /// \param Exprs Helper expressions for CodeGen. |
||
3985 | /// |
||
3986 | static OMPMasterTaskLoopSimdDirective * |
||
3987 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
3988 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
3989 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
3990 | |||
3991 | /// Creates an empty directive with the place for \p NumClauses clauses. |
||
3992 | /// |
||
3993 | /// \param C AST context. |
||
3994 | /// \param CollapsedNum Number of collapsed nested loops. |
||
3995 | /// \param NumClauses Number of clauses. |
||
3996 | /// |
||
3997 | static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, |
||
3998 | unsigned NumClauses, |
||
3999 | unsigned CollapsedNum, |
||
4000 | EmptyShell); |
||
4001 | |||
4002 | static bool classof(const Stmt *T) { |
||
4003 | return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; |
||
4004 | } |
||
4005 | }; |
||
4006 | |||
4007 | /// This represents '#pragma omp masked taskloop simd' directive. |
||
4008 | /// |
||
4009 | /// \code |
||
4010 | /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num) |
||
4011 | /// \endcode |
||
4012 | /// In this example directive '#pragma omp masked taskloop simd' has clauses |
||
4013 | /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
||
4014 | /// and 'num_tasks' with expression 'num'. |
||
4015 | /// |
||
4016 | class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective { |
||
4017 | friend class ASTStmtReader; |
||
4018 | friend class OMPExecutableDirective; |
||
4019 | /// Build directive with the given start and end location. |
||
4020 | /// |
||
4021 | /// \param StartLoc Starting location of the directive kind. |
||
4022 | /// \param EndLoc Ending location of the directive. |
||
4023 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4024 | /// |
||
4025 | OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
4026 | unsigned CollapsedNum) |
||
4027 | : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, |
||
4028 | llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc, |
||
4029 | CollapsedNum) {} |
||
4030 | |||
4031 | /// Build an empty directive. |
||
4032 | /// |
||
4033 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4034 | /// |
||
4035 | explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum) |
||
4036 | : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, |
||
4037 | llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(), |
||
4038 | SourceLocation(), CollapsedNum) {} |
||
4039 | |||
4040 | public: |
||
4041 | /// Creates directive with a list of \p Clauses. |
||
4042 | /// |
||
4043 | /// \param C AST context. |
||
4044 | /// \param StartLoc Starting location of the directive kind. |
||
4045 | /// \param EndLoc Ending Location of the directive. |
||
4046 | /// \param CollapsedNum Number of collapsed loops. |
||
4047 | /// \param Clauses List of clauses. |
||
4048 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4049 | /// \param Exprs Helper expressions for CodeGen. |
||
4050 | /// |
||
4051 | static OMPMaskedTaskLoopSimdDirective * |
||
4052 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4053 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4054 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4055 | |||
4056 | /// Creates an empty directive with the place for \p NumClauses clauses. |
||
4057 | /// |
||
4058 | /// \param C AST context. |
||
4059 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4060 | /// \param NumClauses Number of clauses. |
||
4061 | /// |
||
4062 | static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, |
||
4063 | unsigned NumClauses, |
||
4064 | unsigned CollapsedNum, |
||
4065 | EmptyShell); |
||
4066 | |||
4067 | static bool classof(const Stmt *T) { |
||
4068 | return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass; |
||
4069 | } |
||
4070 | }; |
||
4071 | |||
4072 | /// This represents '#pragma omp parallel master taskloop' directive. |
||
4073 | /// |
||
4074 | /// \code |
||
4075 | /// #pragma omp parallel master taskloop private(a,b) grainsize(val) |
||
4076 | /// num_tasks(num) |
||
4077 | /// \endcode |
||
4078 | /// In this example directive '#pragma omp parallel master taskloop' has clauses |
||
4079 | /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
||
4080 | /// and 'num_tasks' with expression 'num'. |
||
4081 | /// |
||
4082 | class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { |
||
4083 | friend class ASTStmtReader; |
||
4084 | friend class OMPExecutableDirective; |
||
4085 | /// true if the construct has inner cancel directive. |
||
4086 | bool HasCancel = false; |
||
4087 | |||
4088 | /// Build directive with the given start and end location. |
||
4089 | /// |
||
4090 | /// \param StartLoc Starting location of the directive kind. |
||
4091 | /// \param EndLoc Ending location of the directive. |
||
4092 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4093 | /// |
||
4094 | OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, |
||
4095 | SourceLocation EndLoc, |
||
4096 | unsigned CollapsedNum) |
||
4097 | : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, |
||
4098 | llvm::omp::OMPD_parallel_master_taskloop, StartLoc, |
||
4099 | EndLoc, CollapsedNum) {} |
||
4100 | |||
4101 | /// Build an empty directive. |
||
4102 | /// |
||
4103 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4104 | /// |
||
4105 | explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) |
||
4106 | : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, |
||
4107 | llvm::omp::OMPD_parallel_master_taskloop, |
||
4108 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4109 | |||
4110 | /// Set cancel state. |
||
4111 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
4112 | |||
4113 | public: |
||
4114 | /// Creates directive with a list of \a Clauses. |
||
4115 | /// |
||
4116 | /// \param C AST context. |
||
4117 | /// \param StartLoc Starting location of the directive kind. |
||
4118 | /// \param EndLoc Ending Location of the directive. |
||
4119 | /// \param CollapsedNum Number of collapsed loops. |
||
4120 | /// \param Clauses List of clauses. |
||
4121 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4122 | /// \param Exprs Helper expressions for CodeGen. |
||
4123 | /// \param HasCancel true if this directive has inner cancel directive. |
||
4124 | /// |
||
4125 | static OMPParallelMasterTaskLoopDirective * |
||
4126 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4127 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4128 | Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
||
4129 | |||
4130 | /// Creates an empty directive with the place |
||
4131 | /// for \a NumClauses clauses. |
||
4132 | /// |
||
4133 | /// \param C AST context. |
||
4134 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4135 | /// \param NumClauses Number of clauses. |
||
4136 | /// |
||
4137 | static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, |
||
4138 | unsigned NumClauses, |
||
4139 | unsigned CollapsedNum, |
||
4140 | EmptyShell); |
||
4141 | |||
4142 | /// Return true if current directive has inner cancel directive. |
||
4143 | bool hasCancel() const { return HasCancel; } |
||
4144 | |||
4145 | static bool classof(const Stmt *T) { |
||
4146 | return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; |
||
4147 | } |
||
4148 | }; |
||
4149 | |||
4150 | /// This represents '#pragma omp parallel masked taskloop' directive. |
||
4151 | /// |
||
4152 | /// \code |
||
4153 | /// #pragma omp parallel masked taskloop private(a,b) grainsize(val) |
||
4154 | /// num_tasks(num) |
||
4155 | /// \endcode |
||
4156 | /// In this example directive '#pragma omp parallel masked taskloop' has clauses |
||
4157 | /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
||
4158 | /// and 'num_tasks' with expression 'num'. |
||
4159 | /// |
||
4160 | class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective { |
||
4161 | friend class ASTStmtReader; |
||
4162 | friend class OMPExecutableDirective; |
||
4163 | /// true if the construct has inner cancel directive. |
||
4164 | bool HasCancel = false; |
||
4165 | |||
4166 | /// Build directive with the given start and end location. |
||
4167 | /// |
||
4168 | /// \param StartLoc Starting location of the directive kind. |
||
4169 | /// \param EndLoc Ending location of the directive. |
||
4170 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4171 | /// |
||
4172 | OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc, |
||
4173 | SourceLocation EndLoc, |
||
4174 | unsigned CollapsedNum) |
||
4175 | : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, |
||
4176 | llvm::omp::OMPD_parallel_masked_taskloop, StartLoc, |
||
4177 | EndLoc, CollapsedNum) {} |
||
4178 | |||
4179 | /// Build an empty directive. |
||
4180 | /// |
||
4181 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4182 | /// |
||
4183 | explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum) |
||
4184 | : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, |
||
4185 | llvm::omp::OMPD_parallel_masked_taskloop, |
||
4186 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4187 | |||
4188 | /// Set cancel state. |
||
4189 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
4190 | |||
4191 | public: |
||
4192 | /// Creates directive with a list of \a Clauses. |
||
4193 | /// |
||
4194 | /// \param C AST context. |
||
4195 | /// \param StartLoc Starting location of the directive kind. |
||
4196 | /// \param EndLoc Ending Location of the directive. |
||
4197 | /// \param CollapsedNum Number of collapsed loops. |
||
4198 | /// \param Clauses List of clauses. |
||
4199 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4200 | /// \param Exprs Helper expressions for CodeGen. |
||
4201 | /// \param HasCancel true if this directive has inner cancel directive. |
||
4202 | /// |
||
4203 | static OMPParallelMaskedTaskLoopDirective * |
||
4204 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4205 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4206 | Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
||
4207 | |||
4208 | /// Creates an empty directive with the place |
||
4209 | /// for \a NumClauses clauses. |
||
4210 | /// |
||
4211 | /// \param C AST context. |
||
4212 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4213 | /// \param NumClauses Number of clauses. |
||
4214 | /// |
||
4215 | static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, |
||
4216 | unsigned NumClauses, |
||
4217 | unsigned CollapsedNum, |
||
4218 | EmptyShell); |
||
4219 | |||
4220 | /// Return true if current directive has inner cancel directive. |
||
4221 | bool hasCancel() const { return HasCancel; } |
||
4222 | |||
4223 | static bool classof(const Stmt *T) { |
||
4224 | return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass; |
||
4225 | } |
||
4226 | }; |
||
4227 | |||
4228 | /// This represents '#pragma omp parallel master taskloop simd' directive. |
||
4229 | /// |
||
4230 | /// \code |
||
4231 | /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) |
||
4232 | /// num_tasks(num) |
||
4233 | /// \endcode |
||
4234 | /// In this example directive '#pragma omp parallel master taskloop simd' has |
||
4235 | /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with |
||
4236 | /// expression 'val' and 'num_tasks' with expression 'num'. |
||
4237 | /// |
||
4238 | class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { |
||
4239 | friend class ASTStmtReader; |
||
4240 | friend class OMPExecutableDirective; |
||
4241 | /// Build directive with the given start and end location. |
||
4242 | /// |
||
4243 | /// \param StartLoc Starting location of the directive kind. |
||
4244 | /// \param EndLoc Ending location of the directive. |
||
4245 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4246 | /// |
||
4247 | OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, |
||
4248 | SourceLocation EndLoc, |
||
4249 | unsigned CollapsedNum) |
||
4250 | : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, |
||
4251 | llvm::omp::OMPD_parallel_master_taskloop_simd, |
||
4252 | StartLoc, EndLoc, CollapsedNum) {} |
||
4253 | |||
4254 | /// Build an empty directive. |
||
4255 | /// |
||
4256 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4257 | /// |
||
4258 | explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) |
||
4259 | : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, |
||
4260 | llvm::omp::OMPD_parallel_master_taskloop_simd, |
||
4261 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4262 | |||
4263 | public: |
||
4264 | /// Creates directive with a list of \p Clauses. |
||
4265 | /// |
||
4266 | /// \param C AST context. |
||
4267 | /// \param StartLoc Starting location of the directive kind. |
||
4268 | /// \param EndLoc Ending Location of the directive. |
||
4269 | /// \param CollapsedNum Number of collapsed loops. |
||
4270 | /// \param Clauses List of clauses. |
||
4271 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4272 | /// \param Exprs Helper expressions for CodeGen. |
||
4273 | /// |
||
4274 | static OMPParallelMasterTaskLoopSimdDirective * |
||
4275 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4276 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4277 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4278 | |||
4279 | /// Creates an empty directive with the place |
||
4280 | /// for \a NumClauses clauses. |
||
4281 | /// |
||
4282 | /// \param C AST context. |
||
4283 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4284 | /// \param NumClauses Number of clauses. |
||
4285 | /// |
||
4286 | static OMPParallelMasterTaskLoopSimdDirective * |
||
4287 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
4288 | EmptyShell); |
||
4289 | |||
4290 | static bool classof(const Stmt *T) { |
||
4291 | return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; |
||
4292 | } |
||
4293 | }; |
||
4294 | |||
4295 | /// This represents '#pragma omp parallel masked taskloop simd' directive. |
||
4296 | /// |
||
4297 | /// \code |
||
4298 | /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val) |
||
4299 | /// num_tasks(num) |
||
4300 | /// \endcode |
||
4301 | /// In this example directive '#pragma omp parallel masked taskloop simd' has |
||
4302 | /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with |
||
4303 | /// expression 'val' and 'num_tasks' with expression 'num'. |
||
4304 | /// |
||
4305 | class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective { |
||
4306 | friend class ASTStmtReader; |
||
4307 | friend class OMPExecutableDirective; |
||
4308 | /// Build directive with the given start and end location. |
||
4309 | /// |
||
4310 | /// \param StartLoc Starting location of the directive kind. |
||
4311 | /// \param EndLoc Ending location of the directive. |
||
4312 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4313 | /// |
||
4314 | OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc, |
||
4315 | SourceLocation EndLoc, |
||
4316 | unsigned CollapsedNum) |
||
4317 | : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, |
||
4318 | llvm::omp::OMPD_parallel_masked_taskloop_simd, |
||
4319 | StartLoc, EndLoc, CollapsedNum) {} |
||
4320 | |||
4321 | /// Build an empty directive. |
||
4322 | /// |
||
4323 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4324 | /// |
||
4325 | explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum) |
||
4326 | : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, |
||
4327 | llvm::omp::OMPD_parallel_masked_taskloop_simd, |
||
4328 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4329 | |||
4330 | public: |
||
4331 | /// Creates directive with a list of \p Clauses. |
||
4332 | /// |
||
4333 | /// \param C AST context. |
||
4334 | /// \param StartLoc Starting location of the directive kind. |
||
4335 | /// \param EndLoc Ending Location of the directive. |
||
4336 | /// \param CollapsedNum Number of collapsed loops. |
||
4337 | /// \param Clauses List of clauses. |
||
4338 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4339 | /// \param Exprs Helper expressions for CodeGen. |
||
4340 | /// |
||
4341 | static OMPParallelMaskedTaskLoopSimdDirective * |
||
4342 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4343 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4344 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4345 | |||
4346 | /// Creates an empty directive with the place |
||
4347 | /// for \a NumClauses clauses. |
||
4348 | /// |
||
4349 | /// \param C AST context. |
||
4350 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4351 | /// \param NumClauses Number of clauses. |
||
4352 | /// |
||
4353 | static OMPParallelMaskedTaskLoopSimdDirective * |
||
4354 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
4355 | EmptyShell); |
||
4356 | |||
4357 | static bool classof(const Stmt *T) { |
||
4358 | return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass; |
||
4359 | } |
||
4360 | }; |
||
4361 | |||
4362 | /// This represents '#pragma omp distribute' directive. |
||
4363 | /// |
||
4364 | /// \code |
||
4365 | /// #pragma omp distribute private(a,b) |
||
4366 | /// \endcode |
||
4367 | /// In this example directive '#pragma omp distribute' has clauses 'private' |
||
4368 | /// with the variables 'a' and 'b' |
||
4369 | /// |
||
4370 | class OMPDistributeDirective : public OMPLoopDirective { |
||
4371 | friend class ASTStmtReader; |
||
4372 | friend class OMPExecutableDirective; |
||
4373 | |||
4374 | /// Build directive with the given start and end location. |
||
4375 | /// |
||
4376 | /// \param StartLoc Starting location of the directive kind. |
||
4377 | /// \param EndLoc Ending location of the directive. |
||
4378 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4379 | /// |
||
4380 | OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
4381 | unsigned CollapsedNum) |
||
4382 | : OMPLoopDirective(OMPDistributeDirectiveClass, |
||
4383 | llvm::omp::OMPD_distribute, StartLoc, EndLoc, |
||
4384 | CollapsedNum) {} |
||
4385 | |||
4386 | /// Build an empty directive. |
||
4387 | /// |
||
4388 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4389 | /// |
||
4390 | explicit OMPDistributeDirective(unsigned CollapsedNum) |
||
4391 | : OMPLoopDirective(OMPDistributeDirectiveClass, |
||
4392 | llvm::omp::OMPD_distribute, SourceLocation(), |
||
4393 | SourceLocation(), CollapsedNum) {} |
||
4394 | |||
4395 | public: |
||
4396 | /// Creates directive with a list of \a Clauses. |
||
4397 | /// |
||
4398 | /// \param C AST context. |
||
4399 | /// \param StartLoc Starting location of the directive kind. |
||
4400 | /// \param EndLoc Ending Location of the directive. |
||
4401 | /// \param CollapsedNum Number of collapsed loops. |
||
4402 | /// \param Clauses List of clauses. |
||
4403 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4404 | /// \param Exprs Helper expressions for CodeGen. |
||
4405 | /// |
||
4406 | static OMPDistributeDirective * |
||
4407 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4408 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4409 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4410 | |||
4411 | /// Creates an empty directive with the place |
||
4412 | /// for \a NumClauses clauses. |
||
4413 | /// |
||
4414 | /// \param C AST context. |
||
4415 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4416 | /// \param NumClauses Number of clauses. |
||
4417 | /// |
||
4418 | static OMPDistributeDirective *CreateEmpty(const ASTContext &C, |
||
4419 | unsigned NumClauses, |
||
4420 | unsigned CollapsedNum, EmptyShell); |
||
4421 | |||
4422 | static bool classof(const Stmt *T) { |
||
4423 | return T->getStmtClass() == OMPDistributeDirectiveClass; |
||
4424 | } |
||
4425 | }; |
||
4426 | |||
4427 | /// This represents '#pragma omp target update' directive. |
||
4428 | /// |
||
4429 | /// \code |
||
4430 | /// #pragma omp target update to(a) from(b) device(1) |
||
4431 | /// \endcode |
||
4432 | /// In this example directive '#pragma omp target update' has clause 'to' with |
||
4433 | /// argument 'a', clause 'from' with argument 'b' and clause 'device' with |
||
4434 | /// argument '1'. |
||
4435 | /// |
||
4436 | class OMPTargetUpdateDirective : public OMPExecutableDirective { |
||
4437 | friend class ASTStmtReader; |
||
4438 | friend class OMPExecutableDirective; |
||
4439 | /// Build directive with the given start and end location. |
||
4440 | /// |
||
4441 | /// \param StartLoc Starting location of the directive kind. |
||
4442 | /// \param EndLoc Ending Location of the directive. |
||
4443 | /// |
||
4444 | OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
4445 | : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, |
||
4446 | llvm::omp::OMPD_target_update, StartLoc, |
||
4447 | EndLoc) {} |
||
4448 | |||
4449 | /// Build an empty directive. |
||
4450 | /// |
||
4451 | explicit OMPTargetUpdateDirective() |
||
4452 | : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, |
||
4453 | llvm::omp::OMPD_target_update, SourceLocation(), |
||
4454 | SourceLocation()) {} |
||
4455 | |||
4456 | public: |
||
4457 | /// Creates directive with a list of \a Clauses. |
||
4458 | /// |
||
4459 | /// \param C AST context. |
||
4460 | /// \param StartLoc Starting location of the directive kind. |
||
4461 | /// \param EndLoc Ending Location of the directive. |
||
4462 | /// \param Clauses List of clauses. |
||
4463 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4464 | /// |
||
4465 | static OMPTargetUpdateDirective * |
||
4466 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4467 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
4468 | |||
4469 | /// Creates an empty directive with the place for \a NumClauses |
||
4470 | /// clauses. |
||
4471 | /// |
||
4472 | /// \param C AST context. |
||
4473 | /// \param NumClauses The number of clauses. |
||
4474 | /// |
||
4475 | static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, |
||
4476 | unsigned NumClauses, EmptyShell); |
||
4477 | |||
4478 | static bool classof(const Stmt *T) { |
||
4479 | return T->getStmtClass() == OMPTargetUpdateDirectiveClass; |
||
4480 | } |
||
4481 | }; |
||
4482 | |||
4483 | /// This represents '#pragma omp distribute parallel for' composite |
||
4484 | /// directive. |
||
4485 | /// |
||
4486 | /// \code |
||
4487 | /// #pragma omp distribute parallel for private(a,b) |
||
4488 | /// \endcode |
||
4489 | /// In this example directive '#pragma omp distribute parallel for' has clause |
||
4490 | /// 'private' with the variables 'a' and 'b' |
||
4491 | /// |
||
4492 | class OMPDistributeParallelForDirective : public OMPLoopDirective { |
||
4493 | friend class ASTStmtReader; |
||
4494 | friend class OMPExecutableDirective; |
||
4495 | /// true if the construct has inner cancel directive. |
||
4496 | bool HasCancel = false; |
||
4497 | |||
4498 | /// Build directive with the given start and end location. |
||
4499 | /// |
||
4500 | /// \param StartLoc Starting location of the directive kind. |
||
4501 | /// \param EndLoc Ending location of the directive. |
||
4502 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4503 | /// |
||
4504 | OMPDistributeParallelForDirective(SourceLocation StartLoc, |
||
4505 | SourceLocation EndLoc, |
||
4506 | unsigned CollapsedNum) |
||
4507 | : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, |
||
4508 | llvm::omp::OMPD_distribute_parallel_for, StartLoc, |
||
4509 | EndLoc, CollapsedNum) {} |
||
4510 | |||
4511 | /// Build an empty directive. |
||
4512 | /// |
||
4513 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4514 | /// |
||
4515 | explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) |
||
4516 | : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, |
||
4517 | llvm::omp::OMPD_distribute_parallel_for, |
||
4518 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4519 | |||
4520 | /// Sets special task reduction descriptor. |
||
4521 | void setTaskReductionRefExpr(Expr *E) { |
||
4522 | Data->getChildren()[numLoopChildren( |
||
4523 | getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; |
||
4524 | } |
||
4525 | |||
4526 | /// Set cancel state. |
||
4527 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
4528 | |||
4529 | public: |
||
4530 | /// Creates directive with a list of \a Clauses. |
||
4531 | /// |
||
4532 | /// \param C AST context. |
||
4533 | /// \param StartLoc Starting location of the directive kind. |
||
4534 | /// \param EndLoc Ending Location of the directive. |
||
4535 | /// \param CollapsedNum Number of collapsed loops. |
||
4536 | /// \param Clauses List of clauses. |
||
4537 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4538 | /// \param Exprs Helper expressions for CodeGen. |
||
4539 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
4540 | /// taskgroup descriptor. |
||
4541 | /// \param HasCancel true if this directive has inner cancel directive. |
||
4542 | /// |
||
4543 | static OMPDistributeParallelForDirective * |
||
4544 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4545 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4546 | Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
||
4547 | bool HasCancel); |
||
4548 | |||
4549 | /// Creates an empty directive with the place |
||
4550 | /// for \a NumClauses clauses. |
||
4551 | /// |
||
4552 | /// \param C AST context. |
||
4553 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4554 | /// \param NumClauses Number of clauses. |
||
4555 | /// |
||
4556 | static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, |
||
4557 | unsigned NumClauses, |
||
4558 | unsigned CollapsedNum, |
||
4559 | EmptyShell); |
||
4560 | |||
4561 | /// Returns special task reduction reference expression. |
||
4562 | Expr *getTaskReductionRefExpr() { |
||
4563 | return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
||
4564 | getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); |
||
4565 | } |
||
4566 | const Expr *getTaskReductionRefExpr() const { |
||
4567 | return const_cast<OMPDistributeParallelForDirective *>(this) |
||
4568 | ->getTaskReductionRefExpr(); |
||
4569 | } |
||
4570 | |||
4571 | /// Return true if current directive has inner cancel directive. |
||
4572 | bool hasCancel() const { return HasCancel; } |
||
4573 | |||
4574 | static bool classof(const Stmt *T) { |
||
4575 | return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; |
||
4576 | } |
||
4577 | }; |
||
4578 | |||
4579 | /// This represents '#pragma omp distribute parallel for simd' composite |
||
4580 | /// directive. |
||
4581 | /// |
||
4582 | /// \code |
||
4583 | /// #pragma omp distribute parallel for simd private(x) |
||
4584 | /// \endcode |
||
4585 | /// In this example directive '#pragma omp distribute parallel for simd' has |
||
4586 | /// clause 'private' with the variables 'x' |
||
4587 | /// |
||
4588 | class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { |
||
4589 | friend class ASTStmtReader; |
||
4590 | friend class OMPExecutableDirective; |
||
4591 | |||
4592 | /// Build directive with the given start and end location. |
||
4593 | /// |
||
4594 | /// \param StartLoc Starting location of the directive kind. |
||
4595 | /// \param EndLoc Ending location of the directive. |
||
4596 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4597 | /// |
||
4598 | OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, |
||
4599 | SourceLocation EndLoc, |
||
4600 | unsigned CollapsedNum) |
||
4601 | : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, |
||
4602 | llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, |
||
4603 | EndLoc, CollapsedNum) {} |
||
4604 | |||
4605 | /// Build an empty directive. |
||
4606 | /// |
||
4607 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4608 | /// |
||
4609 | explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) |
||
4610 | : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, |
||
4611 | llvm::omp::OMPD_distribute_parallel_for_simd, |
||
4612 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4613 | |||
4614 | public: |
||
4615 | /// Creates directive with a list of \a Clauses. |
||
4616 | /// |
||
4617 | /// \param C AST context. |
||
4618 | /// \param StartLoc Starting location of the directive kind. |
||
4619 | /// \param EndLoc Ending Location of the directive. |
||
4620 | /// \param CollapsedNum Number of collapsed loops. |
||
4621 | /// \param Clauses List of clauses. |
||
4622 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4623 | /// \param Exprs Helper expressions for CodeGen. |
||
4624 | /// |
||
4625 | static OMPDistributeParallelForSimdDirective *Create( |
||
4626 | const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4627 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4628 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4629 | |||
4630 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
4631 | /// |
||
4632 | /// \param C AST context. |
||
4633 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4634 | /// \param NumClauses Number of clauses. |
||
4635 | /// |
||
4636 | static OMPDistributeParallelForSimdDirective *CreateEmpty( |
||
4637 | const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
4638 | EmptyShell); |
||
4639 | |||
4640 | static bool classof(const Stmt *T) { |
||
4641 | return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; |
||
4642 | } |
||
4643 | }; |
||
4644 | |||
4645 | /// This represents '#pragma omp distribute simd' composite directive. |
||
4646 | /// |
||
4647 | /// \code |
||
4648 | /// #pragma omp distribute simd private(x) |
||
4649 | /// \endcode |
||
4650 | /// In this example directive '#pragma omp distribute simd' has clause |
||
4651 | /// 'private' with the variables 'x' |
||
4652 | /// |
||
4653 | class OMPDistributeSimdDirective final : public OMPLoopDirective { |
||
4654 | friend class ASTStmtReader; |
||
4655 | friend class OMPExecutableDirective; |
||
4656 | |||
4657 | /// Build directive with the given start and end location. |
||
4658 | /// |
||
4659 | /// \param StartLoc Starting location of the directive kind. |
||
4660 | /// \param EndLoc Ending location of the directive. |
||
4661 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4662 | /// |
||
4663 | OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
4664 | unsigned CollapsedNum) |
||
4665 | : OMPLoopDirective(OMPDistributeSimdDirectiveClass, |
||
4666 | llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, |
||
4667 | CollapsedNum) {} |
||
4668 | |||
4669 | /// Build an empty directive. |
||
4670 | /// |
||
4671 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4672 | /// |
||
4673 | explicit OMPDistributeSimdDirective(unsigned CollapsedNum) |
||
4674 | : OMPLoopDirective(OMPDistributeSimdDirectiveClass, |
||
4675 | llvm::omp::OMPD_distribute_simd, SourceLocation(), |
||
4676 | SourceLocation(), CollapsedNum) {} |
||
4677 | |||
4678 | public: |
||
4679 | /// Creates directive with a list of \a Clauses. |
||
4680 | /// |
||
4681 | /// \param C AST context. |
||
4682 | /// \param StartLoc Starting location of the directive kind. |
||
4683 | /// \param EndLoc Ending Location of the directive. |
||
4684 | /// \param CollapsedNum Number of collapsed loops. |
||
4685 | /// \param Clauses List of clauses. |
||
4686 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4687 | /// \param Exprs Helper expressions for CodeGen. |
||
4688 | /// |
||
4689 | static OMPDistributeSimdDirective * |
||
4690 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4691 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4692 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4693 | |||
4694 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
4695 | /// |
||
4696 | /// \param C AST context. |
||
4697 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4698 | /// \param NumClauses Number of clauses. |
||
4699 | /// |
||
4700 | static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, |
||
4701 | unsigned NumClauses, |
||
4702 | unsigned CollapsedNum, |
||
4703 | EmptyShell); |
||
4704 | |||
4705 | static bool classof(const Stmt *T) { |
||
4706 | return T->getStmtClass() == OMPDistributeSimdDirectiveClass; |
||
4707 | } |
||
4708 | }; |
||
4709 | |||
4710 | /// This represents '#pragma omp target parallel for simd' directive. |
||
4711 | /// |
||
4712 | /// \code |
||
4713 | /// #pragma omp target parallel for simd private(a) map(b) safelen(c) |
||
4714 | /// \endcode |
||
4715 | /// In this example directive '#pragma omp target parallel for simd' has clauses |
||
4716 | /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' |
||
4717 | /// with the variable 'c'. |
||
4718 | /// |
||
4719 | class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { |
||
4720 | friend class ASTStmtReader; |
||
4721 | friend class OMPExecutableDirective; |
||
4722 | |||
4723 | /// Build directive with the given start and end location. |
||
4724 | /// |
||
4725 | /// \param StartLoc Starting location of the directive kind. |
||
4726 | /// \param EndLoc Ending location of the directive. |
||
4727 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4728 | /// |
||
4729 | OMPTargetParallelForSimdDirective(SourceLocation StartLoc, |
||
4730 | SourceLocation EndLoc, |
||
4731 | unsigned CollapsedNum) |
||
4732 | : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, |
||
4733 | llvm::omp::OMPD_target_parallel_for_simd, StartLoc, |
||
4734 | EndLoc, CollapsedNum) {} |
||
4735 | |||
4736 | /// Build an empty directive. |
||
4737 | /// |
||
4738 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4739 | /// |
||
4740 | explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) |
||
4741 | : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, |
||
4742 | llvm::omp::OMPD_target_parallel_for_simd, |
||
4743 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4744 | |||
4745 | public: |
||
4746 | /// Creates directive with a list of \a Clauses. |
||
4747 | /// |
||
4748 | /// \param C AST context. |
||
4749 | /// \param StartLoc Starting location of the directive kind. |
||
4750 | /// \param EndLoc Ending Location of the directive. |
||
4751 | /// \param CollapsedNum Number of collapsed loops. |
||
4752 | /// \param Clauses List of clauses. |
||
4753 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4754 | /// \param Exprs Helper expressions for CodeGen. |
||
4755 | /// |
||
4756 | static OMPTargetParallelForSimdDirective * |
||
4757 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4758 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4759 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4760 | |||
4761 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
4762 | /// |
||
4763 | /// \param C AST context. |
||
4764 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4765 | /// \param NumClauses Number of clauses. |
||
4766 | /// |
||
4767 | static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, |
||
4768 | unsigned NumClauses, |
||
4769 | unsigned CollapsedNum, |
||
4770 | EmptyShell); |
||
4771 | |||
4772 | static bool classof(const Stmt *T) { |
||
4773 | return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; |
||
4774 | } |
||
4775 | }; |
||
4776 | |||
4777 | /// This represents '#pragma omp target simd' directive. |
||
4778 | /// |
||
4779 | /// \code |
||
4780 | /// #pragma omp target simd private(a) map(b) safelen(c) |
||
4781 | /// \endcode |
||
4782 | /// In this example directive '#pragma omp target simd' has clauses 'private' |
||
4783 | /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with |
||
4784 | /// the variable 'c'. |
||
4785 | /// |
||
4786 | class OMPTargetSimdDirective final : public OMPLoopDirective { |
||
4787 | friend class ASTStmtReader; |
||
4788 | friend class OMPExecutableDirective; |
||
4789 | |||
4790 | /// Build directive with the given start and end location. |
||
4791 | /// |
||
4792 | /// \param StartLoc Starting location of the directive kind. |
||
4793 | /// \param EndLoc Ending location of the directive. |
||
4794 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4795 | /// |
||
4796 | OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
4797 | unsigned CollapsedNum) |
||
4798 | : OMPLoopDirective(OMPTargetSimdDirectiveClass, |
||
4799 | llvm::omp::OMPD_target_simd, StartLoc, EndLoc, |
||
4800 | CollapsedNum) {} |
||
4801 | |||
4802 | /// Build an empty directive. |
||
4803 | /// |
||
4804 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4805 | /// |
||
4806 | explicit OMPTargetSimdDirective(unsigned CollapsedNum) |
||
4807 | : OMPLoopDirective(OMPTargetSimdDirectiveClass, |
||
4808 | llvm::omp::OMPD_target_simd, SourceLocation(), |
||
4809 | SourceLocation(), CollapsedNum) {} |
||
4810 | |||
4811 | public: |
||
4812 | /// Creates directive with a list of \a Clauses. |
||
4813 | /// |
||
4814 | /// \param C AST context. |
||
4815 | /// \param StartLoc Starting location of the directive kind. |
||
4816 | /// \param EndLoc Ending Location of the directive. |
||
4817 | /// \param CollapsedNum Number of collapsed loops. |
||
4818 | /// \param Clauses List of clauses. |
||
4819 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4820 | /// \param Exprs Helper expressions for CodeGen. |
||
4821 | /// |
||
4822 | static OMPTargetSimdDirective * |
||
4823 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4824 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4825 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4826 | |||
4827 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
4828 | /// |
||
4829 | /// \param C AST context. |
||
4830 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4831 | /// \param NumClauses Number of clauses. |
||
4832 | /// |
||
4833 | static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, |
||
4834 | unsigned NumClauses, |
||
4835 | unsigned CollapsedNum, |
||
4836 | EmptyShell); |
||
4837 | |||
4838 | static bool classof(const Stmt *T) { |
||
4839 | return T->getStmtClass() == OMPTargetSimdDirectiveClass; |
||
4840 | } |
||
4841 | }; |
||
4842 | |||
4843 | /// This represents '#pragma omp teams distribute' directive. |
||
4844 | /// |
||
4845 | /// \code |
||
4846 | /// #pragma omp teams distribute private(a,b) |
||
4847 | /// \endcode |
||
4848 | /// In this example directive '#pragma omp teams distribute' has clauses |
||
4849 | /// 'private' with the variables 'a' and 'b' |
||
4850 | /// |
||
4851 | class OMPTeamsDistributeDirective final : public OMPLoopDirective { |
||
4852 | friend class ASTStmtReader; |
||
4853 | friend class OMPExecutableDirective; |
||
4854 | |||
4855 | /// Build directive with the given start and end location. |
||
4856 | /// |
||
4857 | /// \param StartLoc Starting location of the directive kind. |
||
4858 | /// \param EndLoc Ending location of the directive. |
||
4859 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4860 | /// |
||
4861 | OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
4862 | unsigned CollapsedNum) |
||
4863 | : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, |
||
4864 | llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, |
||
4865 | CollapsedNum) {} |
||
4866 | |||
4867 | /// Build an empty directive. |
||
4868 | /// |
||
4869 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4870 | /// |
||
4871 | explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) |
||
4872 | : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, |
||
4873 | llvm::omp::OMPD_teams_distribute, SourceLocation(), |
||
4874 | SourceLocation(), CollapsedNum) {} |
||
4875 | |||
4876 | public: |
||
4877 | /// Creates directive with a list of \a Clauses. |
||
4878 | /// |
||
4879 | /// \param C AST context. |
||
4880 | /// \param StartLoc Starting location of the directive kind. |
||
4881 | /// \param EndLoc Ending Location of the directive. |
||
4882 | /// \param CollapsedNum Number of collapsed loops. |
||
4883 | /// \param Clauses List of clauses. |
||
4884 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4885 | /// \param Exprs Helper expressions for CodeGen. |
||
4886 | /// |
||
4887 | static OMPTeamsDistributeDirective * |
||
4888 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4889 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4890 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4891 | |||
4892 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
4893 | /// |
||
4894 | /// \param C AST context. |
||
4895 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4896 | /// \param NumClauses Number of clauses. |
||
4897 | /// |
||
4898 | static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, |
||
4899 | unsigned NumClauses, |
||
4900 | unsigned CollapsedNum, |
||
4901 | EmptyShell); |
||
4902 | |||
4903 | static bool classof(const Stmt *T) { |
||
4904 | return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; |
||
4905 | } |
||
4906 | }; |
||
4907 | |||
4908 | /// This represents '#pragma omp teams distribute simd' |
||
4909 | /// combined directive. |
||
4910 | /// |
||
4911 | /// \code |
||
4912 | /// #pragma omp teams distribute simd private(a,b) |
||
4913 | /// \endcode |
||
4914 | /// In this example directive '#pragma omp teams distribute simd' |
||
4915 | /// has clause 'private' with the variables 'a' and 'b' |
||
4916 | /// |
||
4917 | class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { |
||
4918 | friend class ASTStmtReader; |
||
4919 | friend class OMPExecutableDirective; |
||
4920 | |||
4921 | /// Build directive with the given start and end location. |
||
4922 | /// |
||
4923 | /// \param StartLoc Starting location of the directive kind. |
||
4924 | /// \param EndLoc Ending location of the directive. |
||
4925 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4926 | /// |
||
4927 | OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, |
||
4928 | SourceLocation EndLoc, unsigned CollapsedNum) |
||
4929 | : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, |
||
4930 | llvm::omp::OMPD_teams_distribute_simd, StartLoc, |
||
4931 | EndLoc, CollapsedNum) {} |
||
4932 | |||
4933 | /// Build an empty directive. |
||
4934 | /// |
||
4935 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4936 | /// |
||
4937 | explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) |
||
4938 | : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, |
||
4939 | llvm::omp::OMPD_teams_distribute_simd, |
||
4940 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
4941 | |||
4942 | public: |
||
4943 | /// Creates directive with a list of \a Clauses. |
||
4944 | /// |
||
4945 | /// \param C AST context. |
||
4946 | /// \param StartLoc Starting location of the directive kind. |
||
4947 | /// \param EndLoc Ending Location of the directive. |
||
4948 | /// \param CollapsedNum Number of collapsed loops. |
||
4949 | /// \param Clauses List of clauses. |
||
4950 | /// \param AssociatedStmt Statement, associated with the directive. |
||
4951 | /// \param Exprs Helper expressions for CodeGen. |
||
4952 | /// |
||
4953 | static OMPTeamsDistributeSimdDirective * |
||
4954 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
4955 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
4956 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
4957 | |||
4958 | /// Creates an empty directive with the place |
||
4959 | /// for \a NumClauses clauses. |
||
4960 | /// |
||
4961 | /// \param C AST context. |
||
4962 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4963 | /// \param NumClauses Number of clauses. |
||
4964 | /// |
||
4965 | static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, |
||
4966 | unsigned NumClauses, |
||
4967 | unsigned CollapsedNum, |
||
4968 | EmptyShell); |
||
4969 | |||
4970 | static bool classof(const Stmt *T) { |
||
4971 | return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; |
||
4972 | } |
||
4973 | }; |
||
4974 | |||
4975 | /// This represents '#pragma omp teams distribute parallel for simd' composite |
||
4976 | /// directive. |
||
4977 | /// |
||
4978 | /// \code |
||
4979 | /// #pragma omp teams distribute parallel for simd private(x) |
||
4980 | /// \endcode |
||
4981 | /// In this example directive '#pragma omp teams distribute parallel for simd' |
||
4982 | /// has clause 'private' with the variables 'x' |
||
4983 | /// |
||
4984 | class OMPTeamsDistributeParallelForSimdDirective final |
||
4985 | : public OMPLoopDirective { |
||
4986 | friend class ASTStmtReader; |
||
4987 | friend class OMPExecutableDirective; |
||
4988 | |||
4989 | /// Build directive with the given start and end location. |
||
4990 | /// |
||
4991 | /// \param StartLoc Starting location of the directive kind. |
||
4992 | /// \param EndLoc Ending location of the directive. |
||
4993 | /// \param CollapsedNum Number of collapsed nested loops. |
||
4994 | /// |
||
4995 | OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, |
||
4996 | SourceLocation EndLoc, |
||
4997 | unsigned CollapsedNum) |
||
4998 | : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, |
||
4999 | llvm::omp::OMPD_teams_distribute_parallel_for_simd, |
||
5000 | StartLoc, EndLoc, CollapsedNum) {} |
||
5001 | |||
5002 | /// Build an empty directive. |
||
5003 | /// |
||
5004 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5005 | /// |
||
5006 | explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) |
||
5007 | : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, |
||
5008 | llvm::omp::OMPD_teams_distribute_parallel_for_simd, |
||
5009 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
5010 | |||
5011 | public: |
||
5012 | /// Creates directive with a list of \a Clauses. |
||
5013 | /// |
||
5014 | /// \param C AST context. |
||
5015 | /// \param StartLoc Starting location of the directive kind. |
||
5016 | /// \param EndLoc Ending Location of the directive. |
||
5017 | /// \param CollapsedNum Number of collapsed loops. |
||
5018 | /// \param Clauses List of clauses. |
||
5019 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5020 | /// \param Exprs Helper expressions for CodeGen. |
||
5021 | /// |
||
5022 | static OMPTeamsDistributeParallelForSimdDirective * |
||
5023 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5024 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
5025 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
5026 | |||
5027 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
5028 | /// |
||
5029 | /// \param C AST context. |
||
5030 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5031 | /// \param NumClauses Number of clauses. |
||
5032 | /// |
||
5033 | static OMPTeamsDistributeParallelForSimdDirective * |
||
5034 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
5035 | EmptyShell); |
||
5036 | |||
5037 | static bool classof(const Stmt *T) { |
||
5038 | return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; |
||
5039 | } |
||
5040 | }; |
||
5041 | |||
5042 | /// This represents '#pragma omp teams distribute parallel for' composite |
||
5043 | /// directive. |
||
5044 | /// |
||
5045 | /// \code |
||
5046 | /// #pragma omp teams distribute parallel for private(x) |
||
5047 | /// \endcode |
||
5048 | /// In this example directive '#pragma omp teams distribute parallel for' |
||
5049 | /// has clause 'private' with the variables 'x' |
||
5050 | /// |
||
5051 | class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { |
||
5052 | friend class ASTStmtReader; |
||
5053 | friend class OMPExecutableDirective; |
||
5054 | /// true if the construct has inner cancel directive. |
||
5055 | bool HasCancel = false; |
||
5056 | |||
5057 | /// Build directive with the given start and end location. |
||
5058 | /// |
||
5059 | /// \param StartLoc Starting location of the directive kind. |
||
5060 | /// \param EndLoc Ending location of the directive. |
||
5061 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5062 | /// |
||
5063 | OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, |
||
5064 | SourceLocation EndLoc, |
||
5065 | unsigned CollapsedNum) |
||
5066 | : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, |
||
5067 | llvm::omp::OMPD_teams_distribute_parallel_for, |
||
5068 | StartLoc, EndLoc, CollapsedNum) {} |
||
5069 | |||
5070 | /// Build an empty directive. |
||
5071 | /// |
||
5072 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5073 | /// |
||
5074 | explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) |
||
5075 | : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, |
||
5076 | llvm::omp::OMPD_teams_distribute_parallel_for, |
||
5077 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
5078 | |||
5079 | /// Sets special task reduction descriptor. |
||
5080 | void setTaskReductionRefExpr(Expr *E) { |
||
5081 | Data->getChildren()[numLoopChildren( |
||
5082 | getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; |
||
5083 | } |
||
5084 | |||
5085 | /// Set cancel state. |
||
5086 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
5087 | |||
5088 | public: |
||
5089 | /// Creates directive with a list of \a Clauses. |
||
5090 | /// |
||
5091 | /// \param C AST context. |
||
5092 | /// \param StartLoc Starting location of the directive kind. |
||
5093 | /// \param EndLoc Ending Location of the directive. |
||
5094 | /// \param CollapsedNum Number of collapsed loops. |
||
5095 | /// \param Clauses List of clauses. |
||
5096 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5097 | /// \param Exprs Helper expressions for CodeGen. |
||
5098 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
5099 | /// taskgroup descriptor. |
||
5100 | /// \param HasCancel true if this directive has inner cancel directive. |
||
5101 | /// |
||
5102 | static OMPTeamsDistributeParallelForDirective * |
||
5103 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5104 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
5105 | Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
||
5106 | bool HasCancel); |
||
5107 | |||
5108 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
5109 | /// |
||
5110 | /// \param C AST context. |
||
5111 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5112 | /// \param NumClauses Number of clauses. |
||
5113 | /// |
||
5114 | static OMPTeamsDistributeParallelForDirective * |
||
5115 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
5116 | EmptyShell); |
||
5117 | |||
5118 | /// Returns special task reduction reference expression. |
||
5119 | Expr *getTaskReductionRefExpr() { |
||
5120 | return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
||
5121 | getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); |
||
5122 | } |
||
5123 | const Expr *getTaskReductionRefExpr() const { |
||
5124 | return const_cast<OMPTeamsDistributeParallelForDirective *>(this) |
||
5125 | ->getTaskReductionRefExpr(); |
||
5126 | } |
||
5127 | |||
5128 | /// Return true if current directive has inner cancel directive. |
||
5129 | bool hasCancel() const { return HasCancel; } |
||
5130 | |||
5131 | static bool classof(const Stmt *T) { |
||
5132 | return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; |
||
5133 | } |
||
5134 | }; |
||
5135 | |||
5136 | /// This represents '#pragma omp target teams' directive. |
||
5137 | /// |
||
5138 | /// \code |
||
5139 | /// #pragma omp target teams if(a>0) |
||
5140 | /// \endcode |
||
5141 | /// In this example directive '#pragma omp target teams' has clause 'if' with |
||
5142 | /// condition 'a>0'. |
||
5143 | /// |
||
5144 | class OMPTargetTeamsDirective final : public OMPExecutableDirective { |
||
5145 | friend class ASTStmtReader; |
||
5146 | friend class OMPExecutableDirective; |
||
5147 | /// Build directive with the given start and end location. |
||
5148 | /// |
||
5149 | /// \param StartLoc Starting location of the directive kind. |
||
5150 | /// \param EndLoc Ending location of the directive. |
||
5151 | /// |
||
5152 | OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
5153 | : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, |
||
5154 | llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { |
||
5155 | } |
||
5156 | |||
5157 | /// Build an empty directive. |
||
5158 | /// |
||
5159 | explicit OMPTargetTeamsDirective() |
||
5160 | : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, |
||
5161 | llvm::omp::OMPD_target_teams, SourceLocation(), |
||
5162 | SourceLocation()) {} |
||
5163 | |||
5164 | public: |
||
5165 | /// Creates directive with a list of \a Clauses. |
||
5166 | /// |
||
5167 | /// \param C AST context. |
||
5168 | /// \param StartLoc Starting location of the directive kind. |
||
5169 | /// \param EndLoc Ending Location of the directive. |
||
5170 | /// \param Clauses List of clauses. |
||
5171 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5172 | /// |
||
5173 | static OMPTargetTeamsDirective *Create(const ASTContext &C, |
||
5174 | SourceLocation StartLoc, |
||
5175 | SourceLocation EndLoc, |
||
5176 | ArrayRef<OMPClause *> Clauses, |
||
5177 | Stmt *AssociatedStmt); |
||
5178 | |||
5179 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
5180 | /// |
||
5181 | /// \param C AST context. |
||
5182 | /// \param NumClauses Number of clauses. |
||
5183 | /// |
||
5184 | static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, |
||
5185 | unsigned NumClauses, EmptyShell); |
||
5186 | |||
5187 | static bool classof(const Stmt *T) { |
||
5188 | return T->getStmtClass() == OMPTargetTeamsDirectiveClass; |
||
5189 | } |
||
5190 | }; |
||
5191 | |||
5192 | /// This represents '#pragma omp target teams distribute' combined directive. |
||
5193 | /// |
||
5194 | /// \code |
||
5195 | /// #pragma omp target teams distribute private(x) |
||
5196 | /// \endcode |
||
5197 | /// In this example directive '#pragma omp target teams distribute' has clause |
||
5198 | /// 'private' with the variables 'x' |
||
5199 | /// |
||
5200 | class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { |
||
5201 | friend class ASTStmtReader; |
||
5202 | friend class OMPExecutableDirective; |
||
5203 | |||
5204 | /// Build directive with the given start and end location. |
||
5205 | /// |
||
5206 | /// \param StartLoc Starting location of the directive kind. |
||
5207 | /// \param EndLoc Ending location of the directive. |
||
5208 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5209 | /// |
||
5210 | OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, |
||
5211 | SourceLocation EndLoc, |
||
5212 | unsigned CollapsedNum) |
||
5213 | : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, |
||
5214 | llvm::omp::OMPD_target_teams_distribute, StartLoc, |
||
5215 | EndLoc, CollapsedNum) {} |
||
5216 | |||
5217 | /// Build an empty directive. |
||
5218 | /// |
||
5219 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5220 | /// |
||
5221 | explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) |
||
5222 | : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, |
||
5223 | llvm::omp::OMPD_target_teams_distribute, |
||
5224 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
5225 | |||
5226 | public: |
||
5227 | /// Creates directive with a list of \a Clauses. |
||
5228 | /// |
||
5229 | /// \param C AST context. |
||
5230 | /// \param StartLoc Starting location of the directive kind. |
||
5231 | /// \param EndLoc Ending Location of the directive. |
||
5232 | /// \param CollapsedNum Number of collapsed loops. |
||
5233 | /// \param Clauses List of clauses. |
||
5234 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5235 | /// \param Exprs Helper expressions for CodeGen. |
||
5236 | /// |
||
5237 | static OMPTargetTeamsDistributeDirective * |
||
5238 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5239 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
5240 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
5241 | |||
5242 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
5243 | /// |
||
5244 | /// \param C AST context. |
||
5245 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5246 | /// \param NumClauses Number of clauses. |
||
5247 | /// |
||
5248 | static OMPTargetTeamsDistributeDirective * |
||
5249 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
5250 | EmptyShell); |
||
5251 | |||
5252 | static bool classof(const Stmt *T) { |
||
5253 | return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; |
||
5254 | } |
||
5255 | }; |
||
5256 | |||
5257 | /// This represents '#pragma omp target teams distribute parallel for' combined |
||
5258 | /// directive. |
||
5259 | /// |
||
5260 | /// \code |
||
5261 | /// #pragma omp target teams distribute parallel for private(x) |
||
5262 | /// \endcode |
||
5263 | /// In this example directive '#pragma omp target teams distribute parallel |
||
5264 | /// for' has clause 'private' with the variables 'x' |
||
5265 | /// |
||
5266 | class OMPTargetTeamsDistributeParallelForDirective final |
||
5267 | : public OMPLoopDirective { |
||
5268 | friend class ASTStmtReader; |
||
5269 | friend class OMPExecutableDirective; |
||
5270 | /// true if the construct has inner cancel directive. |
||
5271 | bool HasCancel = false; |
||
5272 | |||
5273 | /// Build directive with the given start and end location. |
||
5274 | /// |
||
5275 | /// \param StartLoc Starting location of the directive kind. |
||
5276 | /// \param EndLoc Ending location of the directive. |
||
5277 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5278 | /// |
||
5279 | OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, |
||
5280 | SourceLocation EndLoc, |
||
5281 | unsigned CollapsedNum) |
||
5282 | : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, |
||
5283 | llvm::omp::OMPD_target_teams_distribute_parallel_for, |
||
5284 | StartLoc, EndLoc, CollapsedNum) {} |
||
5285 | |||
5286 | /// Build an empty directive. |
||
5287 | /// |
||
5288 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5289 | /// |
||
5290 | explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) |
||
5291 | : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, |
||
5292 | llvm::omp::OMPD_target_teams_distribute_parallel_for, |
||
5293 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
5294 | |||
5295 | /// Sets special task reduction descriptor. |
||
5296 | void setTaskReductionRefExpr(Expr *E) { |
||
5297 | Data->getChildren()[numLoopChildren( |
||
5298 | getLoopsNumber(), |
||
5299 | llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; |
||
5300 | } |
||
5301 | |||
5302 | /// Set cancel state. |
||
5303 | void setHasCancel(bool Has) { HasCancel = Has; } |
||
5304 | |||
5305 | public: |
||
5306 | /// Creates directive with a list of \a Clauses. |
||
5307 | /// |
||
5308 | /// \param C AST context. |
||
5309 | /// \param StartLoc Starting location of the directive kind. |
||
5310 | /// \param EndLoc Ending Location of the directive. |
||
5311 | /// \param CollapsedNum Number of collapsed loops. |
||
5312 | /// \param Clauses List of clauses. |
||
5313 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5314 | /// \param Exprs Helper expressions for CodeGen. |
||
5315 | /// \param TaskRedRef Task reduction special reference expression to handle |
||
5316 | /// taskgroup descriptor. |
||
5317 | /// \param HasCancel true if this directive has inner cancel directive. |
||
5318 | /// |
||
5319 | static OMPTargetTeamsDistributeParallelForDirective * |
||
5320 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5321 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
5322 | Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
||
5323 | bool HasCancel); |
||
5324 | |||
5325 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
5326 | /// |
||
5327 | /// \param C AST context. |
||
5328 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5329 | /// \param NumClauses Number of clauses. |
||
5330 | /// |
||
5331 | static OMPTargetTeamsDistributeParallelForDirective * |
||
5332 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
5333 | EmptyShell); |
||
5334 | |||
5335 | /// Returns special task reduction reference expression. |
||
5336 | Expr *getTaskReductionRefExpr() { |
||
5337 | return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
||
5338 | getLoopsNumber(), |
||
5339 | llvm::omp::OMPD_target_teams_distribute_parallel_for)]); |
||
5340 | } |
||
5341 | const Expr *getTaskReductionRefExpr() const { |
||
5342 | return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) |
||
5343 | ->getTaskReductionRefExpr(); |
||
5344 | } |
||
5345 | |||
5346 | /// Return true if current directive has inner cancel directive. |
||
5347 | bool hasCancel() const { return HasCancel; } |
||
5348 | |||
5349 | static bool classof(const Stmt *T) { |
||
5350 | return T->getStmtClass() == |
||
5351 | OMPTargetTeamsDistributeParallelForDirectiveClass; |
||
5352 | } |
||
5353 | }; |
||
5354 | |||
5355 | /// This represents '#pragma omp target teams distribute parallel for simd' |
||
5356 | /// combined directive. |
||
5357 | /// |
||
5358 | /// \code |
||
5359 | /// #pragma omp target teams distribute parallel for simd private(x) |
||
5360 | /// \endcode |
||
5361 | /// In this example directive '#pragma omp target teams distribute parallel |
||
5362 | /// for simd' has clause 'private' with the variables 'x' |
||
5363 | /// |
||
5364 | class OMPTargetTeamsDistributeParallelForSimdDirective final |
||
5365 | : public OMPLoopDirective { |
||
5366 | friend class ASTStmtReader; |
||
5367 | friend class OMPExecutableDirective; |
||
5368 | |||
5369 | /// Build directive with the given start and end location. |
||
5370 | /// |
||
5371 | /// \param StartLoc Starting location of the directive kind. |
||
5372 | /// \param EndLoc Ending location of the directive. |
||
5373 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5374 | /// |
||
5375 | OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, |
||
5376 | SourceLocation EndLoc, |
||
5377 | unsigned CollapsedNum) |
||
5378 | : OMPLoopDirective( |
||
5379 | OMPTargetTeamsDistributeParallelForSimdDirectiveClass, |
||
5380 | llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, |
||
5381 | EndLoc, CollapsedNum) {} |
||
5382 | |||
5383 | /// Build an empty directive. |
||
5384 | /// |
||
5385 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5386 | /// |
||
5387 | explicit OMPTargetTeamsDistributeParallelForSimdDirective( |
||
5388 | unsigned CollapsedNum) |
||
5389 | : OMPLoopDirective( |
||
5390 | OMPTargetTeamsDistributeParallelForSimdDirectiveClass, |
||
5391 | llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, |
||
5392 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
5393 | |||
5394 | public: |
||
5395 | /// Creates directive with a list of \a Clauses. |
||
5396 | /// |
||
5397 | /// \param C AST context. |
||
5398 | /// \param StartLoc Starting location of the directive kind. |
||
5399 | /// \param EndLoc Ending Location of the directive. |
||
5400 | /// \param CollapsedNum Number of collapsed loops. |
||
5401 | /// \param Clauses List of clauses. |
||
5402 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5403 | /// \param Exprs Helper expressions for CodeGen. |
||
5404 | /// |
||
5405 | static OMPTargetTeamsDistributeParallelForSimdDirective * |
||
5406 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5407 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
5408 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
5409 | |||
5410 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
5411 | /// |
||
5412 | /// \param C AST context. |
||
5413 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5414 | /// \param NumClauses Number of clauses. |
||
5415 | /// |
||
5416 | static OMPTargetTeamsDistributeParallelForSimdDirective * |
||
5417 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
5418 | EmptyShell); |
||
5419 | |||
5420 | static bool classof(const Stmt *T) { |
||
5421 | return T->getStmtClass() == |
||
5422 | OMPTargetTeamsDistributeParallelForSimdDirectiveClass; |
||
5423 | } |
||
5424 | }; |
||
5425 | |||
5426 | /// This represents '#pragma omp target teams distribute simd' combined |
||
5427 | /// directive. |
||
5428 | /// |
||
5429 | /// \code |
||
5430 | /// #pragma omp target teams distribute simd private(x) |
||
5431 | /// \endcode |
||
5432 | /// In this example directive '#pragma omp target teams distribute simd' |
||
5433 | /// has clause 'private' with the variables 'x' |
||
5434 | /// |
||
5435 | class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { |
||
5436 | friend class ASTStmtReader; |
||
5437 | friend class OMPExecutableDirective; |
||
5438 | |||
5439 | /// Build directive with the given start and end location. |
||
5440 | /// |
||
5441 | /// \param StartLoc Starting location of the directive kind. |
||
5442 | /// \param EndLoc Ending location of the directive. |
||
5443 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5444 | /// |
||
5445 | OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, |
||
5446 | SourceLocation EndLoc, |
||
5447 | unsigned CollapsedNum) |
||
5448 | : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, |
||
5449 | llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, |
||
5450 | EndLoc, CollapsedNum) {} |
||
5451 | |||
5452 | /// Build an empty directive. |
||
5453 | /// |
||
5454 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5455 | /// |
||
5456 | explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) |
||
5457 | : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, |
||
5458 | llvm::omp::OMPD_target_teams_distribute_simd, |
||
5459 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
5460 | |||
5461 | public: |
||
5462 | /// Creates directive with a list of \a Clauses. |
||
5463 | /// |
||
5464 | /// \param C AST context. |
||
5465 | /// \param StartLoc Starting location of the directive kind. |
||
5466 | /// \param EndLoc Ending Location of the directive. |
||
5467 | /// \param CollapsedNum Number of collapsed loops. |
||
5468 | /// \param Clauses List of clauses. |
||
5469 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5470 | /// \param Exprs Helper expressions for CodeGen. |
||
5471 | /// |
||
5472 | static OMPTargetTeamsDistributeSimdDirective * |
||
5473 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5474 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
5475 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
5476 | |||
5477 | /// Creates an empty directive with the place for \a NumClauses clauses. |
||
5478 | /// |
||
5479 | /// \param C AST context. |
||
5480 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5481 | /// \param NumClauses Number of clauses. |
||
5482 | /// |
||
5483 | static OMPTargetTeamsDistributeSimdDirective * |
||
5484 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
5485 | EmptyShell); |
||
5486 | |||
5487 | static bool classof(const Stmt *T) { |
||
5488 | return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; |
||
5489 | } |
||
5490 | }; |
||
5491 | |||
5492 | /// This represents the '#pragma omp tile' loop transformation directive. |
||
5493 | class OMPTileDirective final : public OMPLoopTransformationDirective { |
||
5494 | friend class ASTStmtReader; |
||
5495 | friend class OMPExecutableDirective; |
||
5496 | |||
5497 | /// Default list of offsets. |
||
5498 | enum { |
||
5499 | PreInitsOffset = 0, |
||
5500 | TransformedStmtOffset, |
||
5501 | }; |
||
5502 | |||
5503 | explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
5504 | unsigned NumLoops) |
||
5505 | : OMPLoopTransformationDirective(OMPTileDirectiveClass, |
||
5506 | llvm::omp::OMPD_tile, StartLoc, EndLoc, |
||
5507 | NumLoops) { |
||
5508 | setNumGeneratedLoops(3 * NumLoops); |
||
5509 | } |
||
5510 | |||
5511 | void setPreInits(Stmt *PreInits) { |
||
5512 | Data->getChildren()[PreInitsOffset] = PreInits; |
||
5513 | } |
||
5514 | |||
5515 | void setTransformedStmt(Stmt *S) { |
||
5516 | Data->getChildren()[TransformedStmtOffset] = S; |
||
5517 | } |
||
5518 | |||
5519 | public: |
||
5520 | /// Create a new AST node representation for '#pragma omp tile'. |
||
5521 | /// |
||
5522 | /// \param C Context of the AST. |
||
5523 | /// \param StartLoc Location of the introducer (e.g. the 'omp' token). |
||
5524 | /// \param EndLoc Location of the directive's end (e.g. the tok::eod). |
||
5525 | /// \param Clauses The directive's clauses. |
||
5526 | /// \param NumLoops Number of associated loops (number of items in the |
||
5527 | /// 'sizes' clause). |
||
5528 | /// \param AssociatedStmt The outermost associated loop. |
||
5529 | /// \param TransformedStmt The loop nest after tiling, or nullptr in |
||
5530 | /// dependent contexts. |
||
5531 | /// \param PreInits Helper preinits statements for the loop nest. |
||
5532 | static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
5533 | SourceLocation EndLoc, |
||
5534 | ArrayRef<OMPClause *> Clauses, |
||
5535 | unsigned NumLoops, Stmt *AssociatedStmt, |
||
5536 | Stmt *TransformedStmt, Stmt *PreInits); |
||
5537 | |||
5538 | /// Build an empty '#pragma omp tile' AST node for deserialization. |
||
5539 | /// |
||
5540 | /// \param C Context of the AST. |
||
5541 | /// \param NumClauses Number of clauses to allocate. |
||
5542 | /// \param NumLoops Number of associated loops to allocate. |
||
5543 | static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
||
5544 | unsigned NumLoops); |
||
5545 | |||
5546 | /// Gets/sets the associated loops after tiling. |
||
5547 | /// |
||
5548 | /// This is in de-sugared format stored as a CompoundStmt. |
||
5549 | /// |
||
5550 | /// \code |
||
5551 | /// for (...) |
||
5552 | /// ... |
||
5553 | /// \endcode |
||
5554 | /// |
||
5555 | /// Note that if the generated loops a become associated loops of another |
||
5556 | /// directive, they may need to be hoisted before them. |
||
5557 | Stmt *getTransformedStmt() const { |
||
5558 | return Data->getChildren()[TransformedStmtOffset]; |
||
5559 | } |
||
5560 | |||
5561 | /// Return preinits statement. |
||
5562 | Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } |
||
5563 | |||
5564 | static bool classof(const Stmt *T) { |
||
5565 | return T->getStmtClass() == OMPTileDirectiveClass; |
||
5566 | } |
||
5567 | }; |
||
5568 | |||
5569 | /// This represents the '#pragma omp unroll' loop transformation directive. |
||
5570 | /// |
||
5571 | /// \code |
||
5572 | /// #pragma omp unroll |
||
5573 | /// for (int i = 0; i < 64; ++i) |
||
5574 | /// \endcode |
||
5575 | class OMPUnrollDirective final : public OMPLoopTransformationDirective { |
||
5576 | friend class ASTStmtReader; |
||
5577 | friend class OMPExecutableDirective; |
||
5578 | |||
5579 | /// Default list of offsets. |
||
5580 | enum { |
||
5581 | PreInitsOffset = 0, |
||
5582 | TransformedStmtOffset, |
||
5583 | }; |
||
5584 | |||
5585 | explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
5586 | : OMPLoopTransformationDirective(OMPUnrollDirectiveClass, |
||
5587 | llvm::omp::OMPD_unroll, StartLoc, EndLoc, |
||
5588 | 1) {} |
||
5589 | |||
5590 | /// Set the pre-init statements. |
||
5591 | void setPreInits(Stmt *PreInits) { |
||
5592 | Data->getChildren()[PreInitsOffset] = PreInits; |
||
5593 | } |
||
5594 | |||
5595 | /// Set the de-sugared statement. |
||
5596 | void setTransformedStmt(Stmt *S) { |
||
5597 | Data->getChildren()[TransformedStmtOffset] = S; |
||
5598 | } |
||
5599 | |||
5600 | public: |
||
5601 | /// Create a new AST node representation for '#pragma omp unroll'. |
||
5602 | /// |
||
5603 | /// \param C Context of the AST. |
||
5604 | /// \param StartLoc Location of the introducer (e.g. the 'omp' token). |
||
5605 | /// \param EndLoc Location of the directive's end (e.g. the tok::eod). |
||
5606 | /// \param Clauses The directive's clauses. |
||
5607 | /// \param AssociatedStmt The outermost associated loop. |
||
5608 | /// \param TransformedStmt The loop nest after tiling, or nullptr in |
||
5609 | /// dependent contexts. |
||
5610 | /// \param PreInits Helper preinits statements for the loop nest. |
||
5611 | static OMPUnrollDirective * |
||
5612 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5613 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, |
||
5614 | unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits); |
||
5615 | |||
5616 | /// Build an empty '#pragma omp unroll' AST node for deserialization. |
||
5617 | /// |
||
5618 | /// \param C Context of the AST. |
||
5619 | /// \param NumClauses Number of clauses to allocate. |
||
5620 | static OMPUnrollDirective *CreateEmpty(const ASTContext &C, |
||
5621 | unsigned NumClauses); |
||
5622 | |||
5623 | /// Get the de-sugared associated loops after unrolling. |
||
5624 | /// |
||
5625 | /// This is only used if the unrolled loop becomes an associated loop of |
||
5626 | /// another directive, otherwise the loop is emitted directly using loop |
||
5627 | /// transformation metadata. When the unrolled loop cannot be used by another |
||
5628 | /// directive (e.g. because of the full clause), the transformed stmt can also |
||
5629 | /// be nullptr. |
||
5630 | Stmt *getTransformedStmt() const { |
||
5631 | return Data->getChildren()[TransformedStmtOffset]; |
||
5632 | } |
||
5633 | |||
5634 | /// Return the pre-init statements. |
||
5635 | Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } |
||
5636 | |||
5637 | static bool classof(const Stmt *T) { |
||
5638 | return T->getStmtClass() == OMPUnrollDirectiveClass; |
||
5639 | } |
||
5640 | }; |
||
5641 | |||
5642 | /// This represents '#pragma omp scan' directive. |
||
5643 | /// |
||
5644 | /// \code |
||
5645 | /// #pragma omp scan inclusive(a) |
||
5646 | /// \endcode |
||
5647 | /// In this example directive '#pragma omp scan' has clause 'inclusive' with |
||
5648 | /// list item 'a'. |
||
5649 | class OMPScanDirective final : public OMPExecutableDirective { |
||
5650 | friend class ASTStmtReader; |
||
5651 | friend class OMPExecutableDirective; |
||
5652 | /// Build directive with the given start and end location. |
||
5653 | /// |
||
5654 | /// \param StartLoc Starting location of the directive kind. |
||
5655 | /// \param EndLoc Ending location of the directive. |
||
5656 | /// |
||
5657 | OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
5658 | : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, |
||
5659 | StartLoc, EndLoc) {} |
||
5660 | |||
5661 | /// Build an empty directive. |
||
5662 | /// |
||
5663 | explicit OMPScanDirective() |
||
5664 | : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, |
||
5665 | SourceLocation(), SourceLocation()) {} |
||
5666 | |||
5667 | public: |
||
5668 | /// Creates directive with a list of \a Clauses. |
||
5669 | /// |
||
5670 | /// \param C AST context. |
||
5671 | /// \param StartLoc Starting location of the directive kind. |
||
5672 | /// \param EndLoc Ending Location of the directive. |
||
5673 | /// \param Clauses List of clauses (only single OMPFlushClause clause is |
||
5674 | /// allowed). |
||
5675 | /// |
||
5676 | static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
5677 | SourceLocation EndLoc, |
||
5678 | ArrayRef<OMPClause *> Clauses); |
||
5679 | |||
5680 | /// Creates an empty directive with the place for \a NumClauses |
||
5681 | /// clauses. |
||
5682 | /// |
||
5683 | /// \param C AST context. |
||
5684 | /// \param NumClauses Number of clauses. |
||
5685 | /// |
||
5686 | static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
||
5687 | EmptyShell); |
||
5688 | |||
5689 | static bool classof(const Stmt *T) { |
||
5690 | return T->getStmtClass() == OMPScanDirectiveClass; |
||
5691 | } |
||
5692 | }; |
||
5693 | |||
5694 | /// This represents '#pragma omp interop' directive. |
||
5695 | /// |
||
5696 | /// \code |
||
5697 | /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait |
||
5698 | /// \endcode |
||
5699 | /// In this example directive '#pragma omp interop' has |
||
5700 | /// clauses 'init', 'device', 'depend' and 'nowait'. |
||
5701 | /// |
||
5702 | class OMPInteropDirective final : public OMPExecutableDirective { |
||
5703 | friend class ASTStmtReader; |
||
5704 | friend class OMPExecutableDirective; |
||
5705 | |||
5706 | /// Build directive with the given start and end location. |
||
5707 | /// |
||
5708 | /// \param StartLoc Starting location of the directive. |
||
5709 | /// \param EndLoc Ending location of the directive. |
||
5710 | /// |
||
5711 | OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
5712 | : OMPExecutableDirective(OMPInteropDirectiveClass, |
||
5713 | llvm::omp::OMPD_interop, StartLoc, EndLoc) {} |
||
5714 | |||
5715 | /// Build an empty directive. |
||
5716 | /// |
||
5717 | explicit OMPInteropDirective() |
||
5718 | : OMPExecutableDirective(OMPInteropDirectiveClass, |
||
5719 | llvm::omp::OMPD_interop, SourceLocation(), |
||
5720 | SourceLocation()) {} |
||
5721 | |||
5722 | public: |
||
5723 | /// Creates directive. |
||
5724 | /// |
||
5725 | /// \param C AST context. |
||
5726 | /// \param StartLoc Starting location of the directive. |
||
5727 | /// \param EndLoc Ending Location of the directive. |
||
5728 | /// \param Clauses The directive's clauses. |
||
5729 | /// |
||
5730 | static OMPInteropDirective *Create(const ASTContext &C, |
||
5731 | SourceLocation StartLoc, |
||
5732 | SourceLocation EndLoc, |
||
5733 | ArrayRef<OMPClause *> Clauses); |
||
5734 | |||
5735 | /// Creates an empty directive. |
||
5736 | /// |
||
5737 | /// \param C AST context. |
||
5738 | /// |
||
5739 | static OMPInteropDirective *CreateEmpty(const ASTContext &C, |
||
5740 | unsigned NumClauses, EmptyShell); |
||
5741 | |||
5742 | static bool classof(const Stmt *T) { |
||
5743 | return T->getStmtClass() == OMPInteropDirectiveClass; |
||
5744 | } |
||
5745 | }; |
||
5746 | |||
5747 | /// This represents '#pragma omp dispatch' directive. |
||
5748 | /// |
||
5749 | /// \code |
||
5750 | /// #pragma omp dispatch device(dnum) |
||
5751 | /// \endcode |
||
5752 | /// This example shows a directive '#pragma omp dispatch' with a |
||
5753 | /// device clause with variable 'dnum'. |
||
5754 | /// |
||
5755 | class OMPDispatchDirective final : public OMPExecutableDirective { |
||
5756 | friend class ASTStmtReader; |
||
5757 | friend class OMPExecutableDirective; |
||
5758 | |||
5759 | /// The location of the target-call. |
||
5760 | SourceLocation TargetCallLoc; |
||
5761 | |||
5762 | /// Set the location of the target-call. |
||
5763 | void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } |
||
5764 | |||
5765 | /// Build directive with the given start and end location. |
||
5766 | /// |
||
5767 | /// \param StartLoc Starting location of the directive kind. |
||
5768 | /// \param EndLoc Ending location of the directive. |
||
5769 | /// |
||
5770 | OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
5771 | : OMPExecutableDirective(OMPDispatchDirectiveClass, |
||
5772 | llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} |
||
5773 | |||
5774 | /// Build an empty directive. |
||
5775 | /// |
||
5776 | explicit OMPDispatchDirective() |
||
5777 | : OMPExecutableDirective(OMPDispatchDirectiveClass, |
||
5778 | llvm::omp::OMPD_dispatch, SourceLocation(), |
||
5779 | SourceLocation()) {} |
||
5780 | |||
5781 | public: |
||
5782 | /// Creates directive with a list of \a Clauses. |
||
5783 | /// |
||
5784 | /// \param C AST context. |
||
5785 | /// \param StartLoc Starting location of the directive kind. |
||
5786 | /// \param EndLoc Ending Location of the directive. |
||
5787 | /// \param Clauses List of clauses. |
||
5788 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5789 | /// \param TargetCallLoc Location of the target-call. |
||
5790 | /// |
||
5791 | static OMPDispatchDirective * |
||
5792 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5793 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, |
||
5794 | SourceLocation TargetCallLoc); |
||
5795 | |||
5796 | /// Creates an empty directive with the place for \a NumClauses |
||
5797 | /// clauses. |
||
5798 | /// |
||
5799 | /// \param C AST context. |
||
5800 | /// \param NumClauses Number of clauses. |
||
5801 | /// |
||
5802 | static OMPDispatchDirective *CreateEmpty(const ASTContext &C, |
||
5803 | unsigned NumClauses, EmptyShell); |
||
5804 | |||
5805 | /// Return location of target-call. |
||
5806 | SourceLocation getTargetCallLoc() const { return TargetCallLoc; } |
||
5807 | |||
5808 | static bool classof(const Stmt *T) { |
||
5809 | return T->getStmtClass() == OMPDispatchDirectiveClass; |
||
5810 | } |
||
5811 | }; |
||
5812 | |||
5813 | /// This represents '#pragma omp masked' directive. |
||
5814 | /// \code |
||
5815 | /// #pragma omp masked filter(tid) |
||
5816 | /// \endcode |
||
5817 | /// This example shows a directive '#pragma omp masked' with a filter clause |
||
5818 | /// with variable 'tid'. |
||
5819 | /// |
||
5820 | class OMPMaskedDirective final : public OMPExecutableDirective { |
||
5821 | friend class ASTStmtReader; |
||
5822 | friend class OMPExecutableDirective; |
||
5823 | |||
5824 | /// Build directive with the given start and end location. |
||
5825 | /// |
||
5826 | /// \param StartLoc Starting location of the directive kind. |
||
5827 | /// \param EndLoc Ending location of the directive. |
||
5828 | /// |
||
5829 | OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
5830 | : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, |
||
5831 | StartLoc, EndLoc) {} |
||
5832 | |||
5833 | /// Build an empty directive. |
||
5834 | /// |
||
5835 | explicit OMPMaskedDirective() |
||
5836 | : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, |
||
5837 | SourceLocation(), SourceLocation()) {} |
||
5838 | |||
5839 | public: |
||
5840 | /// Creates directive. |
||
5841 | /// |
||
5842 | /// \param C AST context. |
||
5843 | /// \param StartLoc Starting location of the directive kind. |
||
5844 | /// \param EndLoc Ending Location of the directive. |
||
5845 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5846 | /// |
||
5847 | static OMPMaskedDirective * |
||
5848 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5849 | ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
||
5850 | |||
5851 | /// Creates an empty directive. |
||
5852 | /// |
||
5853 | /// \param C AST context. |
||
5854 | /// |
||
5855 | static OMPMaskedDirective *CreateEmpty(const ASTContext &C, |
||
5856 | unsigned NumClauses, EmptyShell); |
||
5857 | |||
5858 | static bool classof(const Stmt *T) { |
||
5859 | return T->getStmtClass() == OMPMaskedDirectiveClass; |
||
5860 | } |
||
5861 | }; |
||
5862 | |||
5863 | /// This represents '#pragma omp metadirective' directive. |
||
5864 | /// |
||
5865 | /// \code |
||
5866 | /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) |
||
5867 | /// \endcode |
||
5868 | /// In this example directive '#pragma omp metadirective' has clauses 'when' |
||
5869 | /// with a dynamic user condition to check if a variable 'N > 10' |
||
5870 | /// |
||
5871 | class OMPMetaDirective final : public OMPExecutableDirective { |
||
5872 | friend class ASTStmtReader; |
||
5873 | friend class OMPExecutableDirective; |
||
5874 | Stmt *IfStmt; |
||
5875 | |||
5876 | OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
5877 | : OMPExecutableDirective(OMPMetaDirectiveClass, |
||
5878 | llvm::omp::OMPD_metadirective, StartLoc, |
||
5879 | EndLoc) {} |
||
5880 | explicit OMPMetaDirective() |
||
5881 | : OMPExecutableDirective(OMPMetaDirectiveClass, |
||
5882 | llvm::omp::OMPD_metadirective, SourceLocation(), |
||
5883 | SourceLocation()) {} |
||
5884 | |||
5885 | void setIfStmt(Stmt *S) { IfStmt = S; } |
||
5886 | |||
5887 | public: |
||
5888 | static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
5889 | SourceLocation EndLoc, |
||
5890 | ArrayRef<OMPClause *> Clauses, |
||
5891 | Stmt *AssociatedStmt, Stmt *IfStmt); |
||
5892 | static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
||
5893 | EmptyShell); |
||
5894 | Stmt *getIfStmt() const { return IfStmt; } |
||
5895 | |||
5896 | static bool classof(const Stmt *T) { |
||
5897 | return T->getStmtClass() == OMPMetaDirectiveClass; |
||
5898 | } |
||
5899 | }; |
||
5900 | |||
5901 | /// This represents '#pragma omp loop' directive. |
||
5902 | /// |
||
5903 | /// \code |
||
5904 | /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) |
||
5905 | /// \endcode |
||
5906 | /// In this example directive '#pragma omp loop' has |
||
5907 | /// clauses 'private' with the variables 'a' and 'b', 'binding' with |
||
5908 | /// modifier 'parallel' and 'order(concurrent). |
||
5909 | /// |
||
5910 | class OMPGenericLoopDirective final : public OMPLoopDirective { |
||
5911 | friend class ASTStmtReader; |
||
5912 | friend class OMPExecutableDirective; |
||
5913 | /// Build directive with the given start and end location. |
||
5914 | /// |
||
5915 | /// \param StartLoc Starting location of the directive kind. |
||
5916 | /// \param EndLoc Ending location of the directive. |
||
5917 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5918 | /// |
||
5919 | OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
5920 | unsigned CollapsedNum) |
||
5921 | : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, |
||
5922 | StartLoc, EndLoc, CollapsedNum) {} |
||
5923 | |||
5924 | /// Build an empty directive. |
||
5925 | /// |
||
5926 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5927 | /// |
||
5928 | explicit OMPGenericLoopDirective(unsigned CollapsedNum) |
||
5929 | : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, |
||
5930 | SourceLocation(), SourceLocation(), CollapsedNum) {} |
||
5931 | |||
5932 | public: |
||
5933 | /// Creates directive with a list of \p Clauses. |
||
5934 | /// |
||
5935 | /// \param C AST context. |
||
5936 | /// \param StartLoc Starting location of the directive kind. |
||
5937 | /// \param EndLoc Ending Location of the directive. |
||
5938 | /// \param CollapsedNum Number of collapsed loops. |
||
5939 | /// \param Clauses List of clauses. |
||
5940 | /// \param AssociatedStmt Statement, associated with the directive. |
||
5941 | /// \param Exprs Helper expressions for CodeGen. |
||
5942 | /// |
||
5943 | static OMPGenericLoopDirective * |
||
5944 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
5945 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
5946 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
5947 | |||
5948 | /// Creates an empty directive with a place for \a NumClauses clauses. |
||
5949 | /// |
||
5950 | /// \param C AST context. |
||
5951 | /// \param NumClauses Number of clauses. |
||
5952 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5953 | /// |
||
5954 | static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, |
||
5955 | unsigned NumClauses, |
||
5956 | unsigned CollapsedNum, |
||
5957 | EmptyShell); |
||
5958 | |||
5959 | static bool classof(const Stmt *T) { |
||
5960 | return T->getStmtClass() == OMPGenericLoopDirectiveClass; |
||
5961 | } |
||
5962 | }; |
||
5963 | |||
5964 | /// This represents '#pragma omp teams loop' directive. |
||
5965 | /// |
||
5966 | /// \code |
||
5967 | /// #pragma omp teams loop private(a,b) order(concurrent) |
||
5968 | /// \endcode |
||
5969 | /// In this example directive '#pragma omp teams loop' has |
||
5970 | /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). |
||
5971 | /// |
||
5972 | class OMPTeamsGenericLoopDirective final : public OMPLoopDirective { |
||
5973 | friend class ASTStmtReader; |
||
5974 | friend class OMPExecutableDirective; |
||
5975 | /// Build directive with the given start and end location. |
||
5976 | /// |
||
5977 | /// \param StartLoc Starting location of the directive kind. |
||
5978 | /// \param EndLoc Ending location of the directive. |
||
5979 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5980 | /// |
||
5981 | OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
||
5982 | unsigned CollapsedNum) |
||
5983 | : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, |
||
5984 | llvm::omp::OMPD_teams_loop, StartLoc, EndLoc, |
||
5985 | CollapsedNum) {} |
||
5986 | |||
5987 | /// Build an empty directive. |
||
5988 | /// |
||
5989 | /// \param CollapsedNum Number of collapsed nested loops. |
||
5990 | /// |
||
5991 | explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum) |
||
5992 | : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, |
||
5993 | llvm::omp::OMPD_teams_loop, SourceLocation(), |
||
5994 | SourceLocation(), CollapsedNum) {} |
||
5995 | |||
5996 | public: |
||
5997 | /// Creates directive with a list of \p Clauses. |
||
5998 | /// |
||
5999 | /// \param C AST context. |
||
6000 | /// \param StartLoc Starting location of the directive kind. |
||
6001 | /// \param EndLoc Ending Location of the directive. |
||
6002 | /// \param CollapsedNum Number of collapsed loops. |
||
6003 | /// \param Clauses List of clauses. |
||
6004 | /// \param AssociatedStmt Statement, associated with the directive. |
||
6005 | /// \param Exprs Helper expressions for CodeGen. |
||
6006 | /// |
||
6007 | static OMPTeamsGenericLoopDirective * |
||
6008 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
6009 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
6010 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
6011 | |||
6012 | /// Creates an empty directive with the place |
||
6013 | /// for \a NumClauses clauses. |
||
6014 | /// |
||
6015 | /// \param C AST context. |
||
6016 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6017 | /// \param NumClauses Number of clauses. |
||
6018 | /// |
||
6019 | static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, |
||
6020 | unsigned NumClauses, |
||
6021 | unsigned CollapsedNum, |
||
6022 | EmptyShell); |
||
6023 | |||
6024 | static bool classof(const Stmt *T) { |
||
6025 | return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass; |
||
6026 | } |
||
6027 | }; |
||
6028 | |||
6029 | /// This represents '#pragma omp target teams loop' directive. |
||
6030 | /// |
||
6031 | /// \code |
||
6032 | /// #pragma omp target teams loop private(a,b) order(concurrent) |
||
6033 | /// \endcode |
||
6034 | /// In this example directive '#pragma omp target teams loop' has |
||
6035 | /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). |
||
6036 | /// |
||
6037 | class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { |
||
6038 | friend class ASTStmtReader; |
||
6039 | friend class OMPExecutableDirective; |
||
6040 | /// Build directive with the given start and end location. |
||
6041 | /// |
||
6042 | /// \param StartLoc Starting location of the directive kind. |
||
6043 | /// \param EndLoc Ending location of the directive. |
||
6044 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6045 | /// |
||
6046 | OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc, |
||
6047 | SourceLocation EndLoc, |
||
6048 | unsigned CollapsedNum) |
||
6049 | : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, |
||
6050 | llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc, |
||
6051 | CollapsedNum) {} |
||
6052 | |||
6053 | /// Build an empty directive. |
||
6054 | /// |
||
6055 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6056 | /// |
||
6057 | explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum) |
||
6058 | : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, |
||
6059 | llvm::omp::OMPD_target_teams_loop, SourceLocation(), |
||
6060 | SourceLocation(), CollapsedNum) {} |
||
6061 | |||
6062 | public: |
||
6063 | /// Creates directive with a list of \p Clauses. |
||
6064 | /// |
||
6065 | /// \param C AST context. |
||
6066 | /// \param StartLoc Starting location of the directive kind. |
||
6067 | /// \param EndLoc Ending Location of the directive. |
||
6068 | /// \param CollapsedNum Number of collapsed loops. |
||
6069 | /// \param Clauses List of clauses. |
||
6070 | /// \param AssociatedStmt Statement, associated with the directive. |
||
6071 | /// \param Exprs Helper expressions for CodeGen. |
||
6072 | /// |
||
6073 | static OMPTargetTeamsGenericLoopDirective * |
||
6074 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
6075 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
6076 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
6077 | |||
6078 | /// Creates an empty directive with the place |
||
6079 | /// for \a NumClauses clauses. |
||
6080 | /// |
||
6081 | /// \param C AST context. |
||
6082 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6083 | /// \param NumClauses Number of clauses. |
||
6084 | /// |
||
6085 | static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, |
||
6086 | unsigned NumClauses, |
||
6087 | unsigned CollapsedNum, |
||
6088 | EmptyShell); |
||
6089 | |||
6090 | static bool classof(const Stmt *T) { |
||
6091 | return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass; |
||
6092 | } |
||
6093 | }; |
||
6094 | |||
6095 | /// This represents '#pragma omp parallel loop' directive. |
||
6096 | /// |
||
6097 | /// \code |
||
6098 | /// #pragma omp parallel loop private(a,b) order(concurrent) |
||
6099 | /// \endcode |
||
6100 | /// In this example directive '#pragma omp parallel loop' has |
||
6101 | /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). |
||
6102 | /// |
||
6103 | class OMPParallelGenericLoopDirective final : public OMPLoopDirective { |
||
6104 | friend class ASTStmtReader; |
||
6105 | friend class OMPExecutableDirective; |
||
6106 | /// Build directive with the given start and end location. |
||
6107 | /// |
||
6108 | /// \param StartLoc Starting location of the directive kind. |
||
6109 | /// \param EndLoc Ending location of the directive. |
||
6110 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6111 | /// |
||
6112 | OMPParallelGenericLoopDirective(SourceLocation StartLoc, |
||
6113 | SourceLocation EndLoc, unsigned CollapsedNum) |
||
6114 | : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, |
||
6115 | llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc, |
||
6116 | CollapsedNum) {} |
||
6117 | |||
6118 | /// Build an empty directive. |
||
6119 | /// |
||
6120 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6121 | /// |
||
6122 | explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum) |
||
6123 | : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, |
||
6124 | llvm::omp::OMPD_parallel_loop, SourceLocation(), |
||
6125 | SourceLocation(), CollapsedNum) {} |
||
6126 | |||
6127 | public: |
||
6128 | /// Creates directive with a list of \p Clauses. |
||
6129 | /// |
||
6130 | /// \param C AST context. |
||
6131 | /// \param StartLoc Starting location of the directive kind. |
||
6132 | /// \param EndLoc Ending Location of the directive. |
||
6133 | /// \param CollapsedNum Number of collapsed loops. |
||
6134 | /// \param Clauses List of clauses. |
||
6135 | /// \param AssociatedStmt Statement, associated with the directive. |
||
6136 | /// \param Exprs Helper expressions for CodeGen. |
||
6137 | /// |
||
6138 | static OMPParallelGenericLoopDirective * |
||
6139 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
6140 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
6141 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
6142 | |||
6143 | /// Creates an empty directive with the place |
||
6144 | /// for \a NumClauses clauses. |
||
6145 | /// |
||
6146 | /// \param C AST context. |
||
6147 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6148 | /// \param NumClauses Number of clauses. |
||
6149 | /// |
||
6150 | static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C, |
||
6151 | unsigned NumClauses, |
||
6152 | unsigned CollapsedNum, |
||
6153 | EmptyShell); |
||
6154 | |||
6155 | static bool classof(const Stmt *T) { |
||
6156 | return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass; |
||
6157 | } |
||
6158 | }; |
||
6159 | |||
6160 | /// This represents '#pragma omp target parallel loop' directive. |
||
6161 | /// |
||
6162 | /// \code |
||
6163 | /// #pragma omp target parallel loop private(a,b) order(concurrent) |
||
6164 | /// \endcode |
||
6165 | /// In this example directive '#pragma omp target parallel loop' has |
||
6166 | /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). |
||
6167 | /// |
||
6168 | class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { |
||
6169 | friend class ASTStmtReader; |
||
6170 | friend class OMPExecutableDirective; |
||
6171 | /// Build directive with the given start and end location. |
||
6172 | /// |
||
6173 | /// \param StartLoc Starting location of the directive kind. |
||
6174 | /// \param EndLoc Ending location of the directive. |
||
6175 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6176 | /// |
||
6177 | OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc, |
||
6178 | SourceLocation EndLoc, |
||
6179 | unsigned CollapsedNum) |
||
6180 | : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, |
||
6181 | llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc, |
||
6182 | CollapsedNum) {} |
||
6183 | |||
6184 | /// Build an empty directive. |
||
6185 | /// |
||
6186 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6187 | /// |
||
6188 | explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum) |
||
6189 | : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, |
||
6190 | llvm::omp::OMPD_target_parallel_loop, SourceLocation(), |
||
6191 | SourceLocation(), CollapsedNum) {} |
||
6192 | |||
6193 | public: |
||
6194 | /// Creates directive with a list of \p Clauses. |
||
6195 | /// |
||
6196 | /// \param C AST context. |
||
6197 | /// \param StartLoc Starting location of the directive kind. |
||
6198 | /// \param EndLoc Ending Location of the directive. |
||
6199 | /// \param CollapsedNum Number of collapsed loops. |
||
6200 | /// \param Clauses List of clauses. |
||
6201 | /// \param AssociatedStmt Statement, associated with the directive. |
||
6202 | /// \param Exprs Helper expressions for CodeGen. |
||
6203 | /// |
||
6204 | static OMPTargetParallelGenericLoopDirective * |
||
6205 | Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
||
6206 | unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
||
6207 | Stmt *AssociatedStmt, const HelperExprs &Exprs); |
||
6208 | |||
6209 | /// Creates an empty directive with the place |
||
6210 | /// for \a NumClauses clauses. |
||
6211 | /// |
||
6212 | /// \param C AST context. |
||
6213 | /// \param CollapsedNum Number of collapsed nested loops. |
||
6214 | /// \param NumClauses Number of clauses. |
||
6215 | /// |
||
6216 | static OMPTargetParallelGenericLoopDirective * |
||
6217 | CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
||
6218 | EmptyShell); |
||
6219 | |||
6220 | static bool classof(const Stmt *T) { |
||
6221 | return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass; |
||
6222 | } |
||
6223 | }; |
||
6224 | |||
6225 | /// This represents '#pragma omp error' directive. |
||
6226 | /// |
||
6227 | /// \code |
||
6228 | /// #pragma omp error |
||
6229 | /// \endcode |
||
6230 | class OMPErrorDirective final : public OMPExecutableDirective { |
||
6231 | friend class ASTStmtReader; |
||
6232 | friend class OMPExecutableDirective; |
||
6233 | /// Build directive with the given start and end location. |
||
6234 | /// |
||
6235 | /// \param StartLoc Starting location of the directive kind. |
||
6236 | /// \param EndLoc Ending location of the directive. |
||
6237 | /// |
||
6238 | OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
||
6239 | : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, |
||
6240 | StartLoc, EndLoc) {} |
||
6241 | /// Build an empty directive. |
||
6242 | /// |
||
6243 | explicit OMPErrorDirective() |
||
6244 | : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, |
||
6245 | SourceLocation(), SourceLocation()) {} |
||
6246 | |||
6247 | public: |
||
6248 | /// |
||
6249 | /// \param C AST context. |
||
6250 | /// \param StartLoc Starting location of the directive kind. |
||
6251 | /// \param EndLoc Ending Location of the directive. |
||
6252 | /// \param Clauses List of clauses. |
||
6253 | /// |
||
6254 | static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
||
6255 | SourceLocation EndLoc, |
||
6256 | ArrayRef<OMPClause *> Clauses); |
||
6257 | |||
6258 | /// Creates an empty directive. |
||
6259 | /// |
||
6260 | /// \param C AST context. |
||
6261 | /// |
||
6262 | static OMPErrorDirective *CreateEmpty(const ASTContext &C, |
||
6263 | unsigned NumClauses, EmptyShell); |
||
6264 | |||
6265 | static bool classof(const Stmt *T) { |
||
6266 | return T->getStmtClass() == OMPErrorDirectiveClass; |
||
6267 | } |
||
6268 | }; |
||
6269 | } // end namespace clang |
||
6270 | |||
6271 | #endif |