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