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