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