Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 1 | //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 2 | // |
3 | // The LLVM Compiler Infrastructure | ||||
4 | // | ||||
5 | // This file is distributed under the University of Illinois Open Source | ||||
6 | // License. See LICENSE.TXT for details. | ||||
7 | // | ||||
8 | //===----------------------------------------------------------------------===// | ||||
9 | /// \file | ||||
10 | /// \brief This file implements semantic analysis for OpenMP directives and | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 11 | /// clauses. |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 12 | /// |
13 | //===----------------------------------------------------------------------===// | ||||
14 | |||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 15 | #include "TreeTransform.h" |
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 16 | #include "clang/AST/ASTContext.h" |
Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 17 | #include "clang/AST/ASTMutationListener.h" |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 18 | #include "clang/AST/CXXInheritance.h" |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 19 | #include "clang/AST/Decl.h" |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 20 | #include "clang/AST/DeclCXX.h" |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 21 | #include "clang/AST/DeclOpenMP.h" |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 22 | #include "clang/AST/StmtCXX.h" |
23 | #include "clang/AST/StmtOpenMP.h" | ||||
24 | #include "clang/AST/StmtVisitor.h" | ||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 25 | #include "clang/Basic/OpenMPKinds.h" |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 26 | #include "clang/Sema/Initialization.h" |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 27 | #include "clang/Sema/Lookup.h" |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 28 | #include "clang/Sema/Scope.h" |
29 | #include "clang/Sema/ScopeInfo.h" | ||||
Chandler Carruth | 5553d0d | 2014-01-07 11:51:46 +0000 | [diff] [blame] | 30 | #include "clang/Sema/SemaInternal.h" |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 31 | #include "llvm/ADT/PointerEmbeddedInt.h" |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 32 | using namespace clang; |
33 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 34 | //===----------------------------------------------------------------------===// |
35 | // Stack of data-sharing attributes for variables | ||||
36 | //===----------------------------------------------------------------------===// | ||||
37 | |||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 38 | static Expr *CheckMapClauseExpressionBase( |
39 | Sema &SemaRef, Expr *E, | ||||
40 | OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, | ||||
41 | OpenMPClauseKind CKind); | ||||
42 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 43 | namespace { |
44 | /// \brief Default data sharing attributes, which can be applied to directive. | ||||
45 | enum DefaultDataSharingAttributes { | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 46 | DSA_unspecified = 0, /// \brief Data sharing attribute not specified. |
47 | DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. | ||||
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 48 | DSA_shared = 1 << 1, /// \brief Default data sharing attribute 'shared'. |
49 | }; | ||||
50 | |||||
51 | /// Attributes of the defaultmap clause. | ||||
52 | enum DefaultMapAttributes { | ||||
53 | DMA_unspecified, /// Default mapping is not specified. | ||||
54 | DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 55 | }; |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 56 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 57 | /// \brief Stack for tracking declarations used in OpenMP directives and |
58 | /// clauses and their data-sharing attributes. | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 59 | class DSAStackTy final { |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 60 | public: |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 61 | struct DSAVarData final { |
62 | OpenMPDirectiveKind DKind = OMPD_unknown; | ||||
63 | OpenMPClauseKind CKind = OMPC_unknown; | ||||
64 | Expr *RefExpr = nullptr; | ||||
65 | DeclRefExpr *PrivateCopy = nullptr; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 66 | SourceLocation ImplicitDSALoc; |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 67 | DSAVarData() = default; |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 68 | DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr, |
69 | DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc) | ||||
70 | : DKind(DKind), CKind(CKind), RefExpr(RefExpr), | ||||
71 | PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 72 | }; |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 73 | typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4> |
74 | OperatorOffsetTy; | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 75 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 76 | private: |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 77 | struct DSAInfo final { |
78 | OpenMPClauseKind Attributes = OMPC_unknown; | ||||
79 | /// Pointer to a reference expression and a flag which shows that the | ||||
80 | /// variable is marked as lastprivate(true) or not (false). | ||||
81 | llvm::PointerIntPair<Expr *, 1, bool> RefExpr; | ||||
82 | DeclRefExpr *PrivateCopy = nullptr; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 83 | }; |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 84 | typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy; |
85 | typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 86 | typedef std::pair<unsigned, VarDecl *> LCDeclInfo; |
87 | typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy; | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 88 | /// Struct that associates a component with the clause kind where they are |
89 | /// found. | ||||
90 | struct MappedExprComponentTy { | ||||
91 | OMPClauseMappableExprCommon::MappableExprComponentLists Components; | ||||
92 | OpenMPClauseKind Kind = OMPC_unknown; | ||||
93 | }; | ||||
94 | typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy> | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 95 | MappedExprComponentsTy; |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 96 | typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> |
97 | CriticalsWithHintsTy; | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 98 | typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy> |
99 | DoacrossDependMapTy; | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 100 | struct ReductionData { |
Alexey Bataev | f87fa88 | 2017-07-21 19:26:22 +0000 | [diff] [blame] | 101 | typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType; |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 102 | SourceRange ReductionRange; |
Alexey Bataev | f87fa88 | 2017-07-21 19:26:22 +0000 | [diff] [blame] | 103 | llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 104 | ReductionData() = default; |
105 | void set(BinaryOperatorKind BO, SourceRange RR) { | ||||
106 | ReductionRange = RR; | ||||
107 | ReductionOp = BO; | ||||
108 | } | ||||
109 | void set(const Expr *RefExpr, SourceRange RR) { | ||||
110 | ReductionRange = RR; | ||||
111 | ReductionOp = RefExpr; | ||||
112 | } | ||||
113 | }; | ||||
114 | typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 115 | |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 116 | struct SharingMapTy final { |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 117 | DeclSAMapTy SharingMap; |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 118 | DeclReductionMapTy ReductionMap; |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 119 | AlignedMapTy AlignedMap; |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 120 | MappedExprComponentsTy MappedExprComponents; |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 121 | LoopControlVariablesMapTy LCVMap; |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 122 | DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 123 | SourceLocation DefaultAttrLoc; |
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 124 | DefaultMapAttributes DefaultMapAttr = DMA_unspecified; |
125 | SourceLocation DefaultMapAttrLoc; | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 126 | OpenMPDirectiveKind Directive = OMPD_unknown; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 127 | DeclarationNameInfo DirectiveName; |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 128 | Scope *CurScope = nullptr; |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 129 | SourceLocation ConstructLoc; |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 130 | /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to |
131 | /// get the data (loop counters etc.) about enclosing loop-based construct. | ||||
132 | /// This data is required during codegen. | ||||
133 | DoacrossDependMapTy DoacrossDepends; | ||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 134 | /// \brief first argument (Expr *) contains optional argument of the |
135 | /// 'ordered' clause, the second one is true if the regions has 'ordered' | ||||
136 | /// clause, false otherwise. | ||||
137 | llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 138 | bool NowaitRegion = false; |
139 | bool CancelRegion = false; | ||||
140 | unsigned AssociatedLoops = 1; | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 141 | SourceLocation InnerTeamsRegionLoc; |
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 142 | /// Reference to the taskgroup task_reduction reference expression. |
143 | Expr *TaskgroupReductionRef = nullptr; | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 144 | SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 145 | Scope *CurScope, SourceLocation Loc) |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 146 | : Directive(DKind), DirectiveName(Name), CurScope(CurScope), |
147 | ConstructLoc(Loc) {} | ||||
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 148 | SharingMapTy() = default; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 149 | }; |
150 | |||||
Axel Naumann | 323862e | 2016-02-03 10:45:22 +0000 | [diff] [blame] | 151 | typedef SmallVector<SharingMapTy, 4> StackTy; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 152 | |
153 | /// \brief Stack of used declaration and their data-sharing attributes. | ||||
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 154 | DeclSAMapTy Threadprivates; |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 155 | const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; |
156 | SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 157 | /// \brief true, if check for DSA must be from parent directive, false, if |
158 | /// from current directive. | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 159 | OpenMPClauseKind ClauseKindMode = OMPC_unknown; |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 160 | Sema &SemaRef; |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 161 | bool ForceCapturing = false; |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 162 | CriticalsWithHintsTy Criticals; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 163 | |
164 | typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; | ||||
165 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 166 | DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D); |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 167 | |
168 | /// \brief Checks if the variable is a local for OpenMP region. | ||||
169 | bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 170 | |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 171 | bool isStackEmpty() const { |
172 | return Stack.empty() || | ||||
173 | Stack.back().second != CurrentNonCapturingFunctionScope || | ||||
174 | Stack.back().first.empty(); | ||||
175 | } | ||||
176 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 177 | public: |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 178 | explicit DSAStackTy(Sema &S) : SemaRef(S) {} |
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 179 | |
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 180 | bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } |
181 | void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 182 | |
Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 183 | bool isForceVarCapturing() const { return ForceCapturing; } |
184 | void setForceVarCapturing(bool V) { ForceCapturing = V; } | ||||
185 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 186 | void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 187 | Scope *CurScope, SourceLocation Loc) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 188 | if (Stack.empty() || |
189 | Stack.back().second != CurrentNonCapturingFunctionScope) | ||||
190 | Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); | ||||
191 | Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); | ||||
192 | Stack.back().first.back().DefaultAttrLoc = Loc; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 193 | } |
194 | |||||
195 | void pop() { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 196 | assert(!Stack.back().first.empty() && |
197 | "Data-sharing attributes stack is empty!"); | ||||
198 | Stack.back().first.pop_back(); | ||||
199 | } | ||||
200 | |||||
201 | /// Start new OpenMP region stack in new non-capturing function. | ||||
202 | void pushFunction() { | ||||
203 | const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); | ||||
204 | assert(!isa<CapturingScopeInfo>(CurFnScope)); | ||||
205 | CurrentNonCapturingFunctionScope = CurFnScope; | ||||
206 | } | ||||
207 | /// Pop region stack for non-capturing function. | ||||
208 | void popFunction(const FunctionScopeInfo *OldFSI) { | ||||
209 | if (!Stack.empty() && Stack.back().second == OldFSI) { | ||||
210 | assert(Stack.back().first.empty()); | ||||
211 | Stack.pop_back(); | ||||
212 | } | ||||
213 | CurrentNonCapturingFunctionScope = nullptr; | ||||
214 | for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { | ||||
215 | if (!isa<CapturingScopeInfo>(FSI)) { | ||||
216 | CurrentNonCapturingFunctionScope = FSI; | ||||
217 | break; | ||||
218 | } | ||||
219 | } | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 220 | } |
221 | |||||
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 222 | void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { |
223 | Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); | ||||
224 | } | ||||
225 | const std::pair<OMPCriticalDirective *, llvm::APSInt> | ||||
226 | getCriticalWithHint(const DeclarationNameInfo &Name) const { | ||||
227 | auto I = Criticals.find(Name.getAsString()); | ||||
228 | if (I != Criticals.end()) | ||||
229 | return I->second; | ||||
230 | return std::make_pair(nullptr, llvm::APSInt()); | ||||
231 | } | ||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 232 | /// \brief If 'aligned' declaration for given variable \a D was not seen yet, |
Alp Toker | 15e62a3 | 2014-06-06 12:02:07 +0000 | [diff] [blame] | 233 | /// add it and return NULL; otherwise return previous occurrence's expression |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 234 | /// for diagnostics. |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 235 | Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 236 | |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 237 | /// \brief Register specified variable as loop control variable. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 238 | void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 239 | /// \brief Check if the specified variable is a loop control variable for |
240 | /// current region. | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 241 | /// \return The index of the loop control variable in the list of associated |
242 | /// for-loops (from outer to inner). | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 243 | LCDeclInfo isLoopControlVariable(ValueDecl *D); |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 244 | /// \brief Check if the specified variable is a loop control variable for |
245 | /// parent region. | ||||
246 | /// \return The index of the loop control variable in the list of associated | ||||
247 | /// for-loops (from outer to inner). | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 248 | LCDeclInfo isParentLoopControlVariable(ValueDecl *D); |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 249 | /// \brief Get the loop control variable for the I-th loop (or nullptr) in |
250 | /// parent directive. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 251 | ValueDecl *getParentLoopControlVariable(unsigned I); |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 252 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 253 | /// \brief Adds explicit data sharing attribute to the specified declaration. |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 254 | void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, |
255 | DeclRefExpr *PrivateCopy = nullptr); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 256 | |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 257 | /// Adds additional information for the reduction items with the reduction id |
258 | /// represented as an operator. | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 259 | void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, |
260 | BinaryOperatorKind BOK); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 261 | /// Adds additional information for the reduction items with the reduction id |
262 | /// represented as reduction identifier. | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 263 | void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, |
264 | const Expr *ReductionRef); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 265 | /// Returns the location and reduction operation from the innermost parent |
266 | /// region for the given \p D. | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 267 | DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 268 | BinaryOperatorKind &BOK, |
269 | Expr *&TaskgroupDescriptor); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 270 | /// Returns the location and reduction operation from the innermost parent |
271 | /// region for the given \p D. | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 272 | DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 273 | const Expr *&ReductionRef, |
274 | Expr *&TaskgroupDescriptor); | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 275 | /// Return reduction reference expression for the current taskgroup. |
276 | Expr *getTaskgroupReductionRef() const { | ||||
277 | assert(Stack.back().first.back().Directive == OMPD_taskgroup && | ||||
278 | "taskgroup reference expression requested for non taskgroup " | ||||
279 | "directive."); | ||||
280 | return Stack.back().first.back().TaskgroupReductionRef; | ||||
281 | } | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 282 | /// Checks if the given \p VD declaration is actually a taskgroup reduction |
283 | /// descriptor variable at the \p Level of OpenMP regions. | ||||
284 | bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const { | ||||
285 | return Stack.back().first[Level].TaskgroupReductionRef && | ||||
286 | cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) | ||||
287 | ->getDecl() == VD; | ||||
288 | } | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 289 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 290 | /// \brief Returns data sharing attributes from top of the stack for the |
291 | /// specified declaration. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 292 | DSAVarData getTopDSA(ValueDecl *D, bool FromParent); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 293 | /// \brief Returns data-sharing attributes for the specified declaration. |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 294 | DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 295 | /// \brief Checks if the specified variables has data-sharing attributes which |
296 | /// match specified \a CPred predicate in any directive which matches \a DPred | ||||
297 | /// predicate. | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 298 | DSAVarData hasDSA(ValueDecl *D, |
299 | const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, | ||||
300 | const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, | ||||
301 | bool FromParent); | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 302 | /// \brief Checks if the specified variables has data-sharing attributes which |
303 | /// match specified \a CPred predicate in any innermost directive which | ||||
304 | /// matches \a DPred predicate. | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 305 | DSAVarData |
306 | hasInnermostDSA(ValueDecl *D, | ||||
307 | const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, | ||||
308 | const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, | ||||
309 | bool FromParent); | ||||
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 310 | /// \brief Checks if the specified variables has explicit data-sharing |
311 | /// attributes which match specified \a CPred predicate at the specified | ||||
312 | /// OpenMP region. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 313 | bool hasExplicitDSA(ValueDecl *D, |
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 314 | const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 315 | unsigned Level, bool NotLastprivate = false); |
Samuel Antao | 4be30e9 | 2015-10-02 17:14:03 +0000 | [diff] [blame] | 316 | |
317 | /// \brief Returns true if the directive at level \Level matches in the | ||||
318 | /// specified \a DPred predicate. | ||||
319 | bool hasExplicitDirective( | ||||
320 | const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, | ||||
321 | unsigned Level); | ||||
322 | |||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 323 | /// \brief Finds a directive which matches specified \a DPred predicate. |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 324 | bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind, |
325 | const DeclarationNameInfo &, | ||||
326 | SourceLocation)> &DPred, | ||||
327 | bool FromParent); | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 328 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 329 | /// \brief Returns currently analyzed directive. |
330 | OpenMPDirectiveKind getCurrentDirective() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 331 | return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 332 | } |
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 333 | /// \brief Returns parent directive. |
334 | OpenMPDirectiveKind getParentDirective() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 335 | if (isStackEmpty() || Stack.back().first.size() == 1) |
336 | return OMPD_unknown; | ||||
337 | return std::next(Stack.back().first.rbegin())->Directive; | ||||
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 338 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 339 | |
340 | /// \brief Set default data sharing attribute to none. | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 341 | void setDefaultDSANone(SourceLocation Loc) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 342 | assert(!isStackEmpty()); |
343 | Stack.back().first.back().DefaultAttr = DSA_none; | ||||
344 | Stack.back().first.back().DefaultAttrLoc = Loc; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 345 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 346 | /// \brief Set default data sharing attribute to shared. |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 347 | void setDefaultDSAShared(SourceLocation Loc) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 348 | assert(!isStackEmpty()); |
349 | Stack.back().first.back().DefaultAttr = DSA_shared; | ||||
350 | Stack.back().first.back().DefaultAttrLoc = Loc; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 351 | } |
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 352 | /// Set default data mapping attribute to 'tofrom:scalar'. |
353 | void setDefaultDMAToFromScalar(SourceLocation Loc) { | ||||
354 | assert(!isStackEmpty()); | ||||
355 | Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; | ||||
356 | Stack.back().first.back().DefaultMapAttrLoc = Loc; | ||||
357 | } | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 358 | |
359 | DefaultDataSharingAttributes getDefaultDSA() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 360 | return isStackEmpty() ? DSA_unspecified |
361 | : Stack.back().first.back().DefaultAttr; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 362 | } |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 363 | SourceLocation getDefaultDSALocation() const { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 364 | return isStackEmpty() ? SourceLocation() |
365 | : Stack.back().first.back().DefaultAttrLoc; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 366 | } |
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 367 | DefaultMapAttributes getDefaultDMA() const { |
368 | return isStackEmpty() ? DMA_unspecified | ||||
369 | : Stack.back().first.back().DefaultMapAttr; | ||||
370 | } | ||||
371 | DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { | ||||
372 | return Stack.back().first[Level].DefaultMapAttr; | ||||
373 | } | ||||
374 | SourceLocation getDefaultDMALocation() const { | ||||
375 | return isStackEmpty() ? SourceLocation() | ||||
376 | : Stack.back().first.back().DefaultMapAttrLoc; | ||||
377 | } | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 378 | |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 379 | /// \brief Checks if the specified variable is a threadprivate. |
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 380 | bool isThreadPrivate(VarDecl *D) { |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 381 | DSAVarData DVar = getTopDSA(D, false); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 382 | return isOpenMPThreadPrivate(DVar.CKind); |
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 383 | } |
384 | |||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 385 | /// \brief Marks current region as ordered (it has an 'ordered' clause). |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 386 | void setOrderedRegion(bool IsOrdered, Expr *Param) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 387 | assert(!isStackEmpty()); |
388 | Stack.back().first.back().OrderedRegion.setInt(IsOrdered); | ||||
389 | Stack.back().first.back().OrderedRegion.setPointer(Param); | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 390 | } |
391 | /// \brief Returns true, if parent region is ordered (has associated | ||||
392 | /// 'ordered' clause), false - otherwise. | ||||
393 | bool isParentOrderedRegion() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 394 | if (isStackEmpty() || Stack.back().first.size() == 1) |
395 | return false; | ||||
396 | return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt(); | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 397 | } |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 398 | /// \brief Returns optional parameter for the ordered region. |
399 | Expr *getParentOrderedRegionParam() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 400 | if (isStackEmpty() || Stack.back().first.size() == 1) |
401 | return nullptr; | ||||
402 | return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); | ||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 403 | } |
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 404 | /// \brief Marks current region as nowait (it has a 'nowait' clause). |
405 | void setNowaitRegion(bool IsNowait = true) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 406 | assert(!isStackEmpty()); |
407 | Stack.back().first.back().NowaitRegion = IsNowait; | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 408 | } |
409 | /// \brief Returns true, if parent region is nowait (has associated | ||||
410 | /// 'nowait' clause), false - otherwise. | ||||
411 | bool isParentNowaitRegion() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 412 | if (isStackEmpty() || Stack.back().first.size() == 1) |
413 | return false; | ||||
414 | return std::next(Stack.back().first.rbegin())->NowaitRegion; | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 415 | } |
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 416 | /// \brief Marks parent region as cancel region. |
417 | void setParentCancelRegion(bool Cancel = true) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 418 | if (!isStackEmpty() && Stack.back().first.size() > 1) { |
419 | auto &StackElemRef = *std::next(Stack.back().first.rbegin()); | ||||
420 | StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; | ||||
421 | } | ||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 422 | } |
423 | /// \brief Return true if current region has inner cancel construct. | ||||
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 424 | bool isCancelRegion() const { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 425 | return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 426 | } |
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 427 | |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 428 | /// \brief Set collapse value for the region. |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 429 | void setAssociatedLoops(unsigned Val) { |
430 | assert(!isStackEmpty()); | ||||
431 | Stack.back().first.back().AssociatedLoops = Val; | ||||
432 | } | ||||
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 433 | /// \brief Return collapse value for region. |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 434 | unsigned getAssociatedLoops() const { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 435 | return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 436 | } |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 437 | |
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 438 | /// \brief Marks current target region as one with closely nested teams |
439 | /// region. | ||||
440 | void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 441 | if (!isStackEmpty() && Stack.back().first.size() > 1) { |
442 | std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = | ||||
443 | TeamsRegionLoc; | ||||
444 | } | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 445 | } |
446 | /// \brief Returns true, if current region has closely nested teams region. | ||||
447 | bool hasInnerTeamsRegion() const { | ||||
448 | return getInnerTeamsRegionLoc().isValid(); | ||||
449 | } | ||||
450 | /// \brief Returns location of the nested teams region (if any). | ||||
451 | SourceLocation getInnerTeamsRegionLoc() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 452 | return isStackEmpty() ? SourceLocation() |
453 | : Stack.back().first.back().InnerTeamsRegionLoc; | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 454 | } |
455 | |||||
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 456 | Scope *getCurScope() const { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 457 | return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 458 | } |
459 | Scope *getCurScope() { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 460 | return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 461 | } |
462 | SourceLocation getConstructLoc() { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 463 | return isStackEmpty() ? SourceLocation() |
464 | : Stack.back().first.back().ConstructLoc; | ||||
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 465 | } |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 466 | |
Samuel Antao | 4c8035b | 2016-12-12 18:00:20 +0000 | [diff] [blame] | 467 | /// Do the check specified in \a Check to all component lists and return true |
468 | /// if any issue is found. | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 469 | bool checkMappableExprComponentListsForDecl( |
470 | ValueDecl *VD, bool CurrentRegionOnly, | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 471 | const llvm::function_ref< |
472 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||
473 | OpenMPClauseKind)> &Check) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 474 | if (isStackEmpty()) |
475 | return false; | ||||
476 | auto SI = Stack.back().first.rbegin(); | ||||
477 | auto SE = Stack.back().first.rend(); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 478 | |
479 | if (SI == SE) | ||||
480 | return false; | ||||
481 | |||||
482 | if (CurrentRegionOnly) { | ||||
483 | SE = std::next(SI); | ||||
484 | } else { | ||||
485 | ++SI; | ||||
486 | } | ||||
487 | |||||
488 | for (; SI != SE; ++SI) { | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 489 | auto MI = SI->MappedExprComponents.find(VD); |
490 | if (MI != SI->MappedExprComponents.end()) | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 491 | for (auto &L : MI->second.Components) |
492 | if (Check(L, MI->second.Kind)) | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 493 | return true; |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 494 | } |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 495 | return false; |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 496 | } |
497 | |||||
Jonas Hahnfeld | f7c4d7b | 2017-07-01 10:40:50 +0000 | [diff] [blame] | 498 | /// Do the check specified in \a Check to all component lists at a given level |
499 | /// and return true if any issue is found. | ||||
500 | bool checkMappableExprComponentListsForDeclAtLevel( | ||||
501 | ValueDecl *VD, unsigned Level, | ||||
502 | const llvm::function_ref< | ||||
503 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||
504 | OpenMPClauseKind)> &Check) { | ||||
505 | if (isStackEmpty()) | ||||
506 | return false; | ||||
507 | |||||
508 | auto StartI = Stack.back().first.begin(); | ||||
509 | auto EndI = Stack.back().first.end(); | ||||
510 | if (std::distance(StartI, EndI) <= (int)Level) | ||||
511 | return false; | ||||
512 | std::advance(StartI, Level); | ||||
513 | |||||
514 | auto MI = StartI->MappedExprComponents.find(VD); | ||||
515 | if (MI != StartI->MappedExprComponents.end()) | ||||
516 | for (auto &L : MI->second.Components) | ||||
517 | if (Check(L, MI->second.Kind)) | ||||
518 | return true; | ||||
519 | return false; | ||||
520 | } | ||||
521 | |||||
Samuel Antao | 4c8035b | 2016-12-12 18:00:20 +0000 | [diff] [blame] | 522 | /// Create a new mappable expression component list associated with a given |
523 | /// declaration and initialize it with the provided list of components. | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 524 | void addMappableExpressionComponents( |
525 | ValueDecl *VD, | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 526 | OMPClauseMappableExprCommon::MappableExprComponentListRef Components, |
527 | OpenMPClauseKind WhereFoundClauseKind) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 528 | assert(!isStackEmpty() && |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 529 | "Not expecting to retrieve components from a empty stack!"); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 530 | auto &MEC = Stack.back().first.back().MappedExprComponents[VD]; |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 531 | // Create new entry and append the new components there. |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 532 | MEC.Components.resize(MEC.Components.size() + 1); |
533 | MEC.Components.back().append(Components.begin(), Components.end()); | ||||
534 | MEC.Kind = WhereFoundClauseKind; | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 535 | } |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 536 | |
537 | unsigned getNestingLevel() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 538 | assert(!isStackEmpty()); |
539 | return Stack.back().first.size() - 1; | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 540 | } |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 541 | void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 542 | assert(!isStackEmpty() && Stack.back().first.size() > 1); |
543 | auto &StackElem = *std::next(Stack.back().first.rbegin()); | ||||
544 | assert(isOpenMPWorksharingDirective(StackElem.Directive)); | ||||
545 | StackElem.DoacrossDepends.insert({C, OpsOffs}); | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 546 | } |
547 | llvm::iterator_range<DoacrossDependMapTy::const_iterator> | ||||
548 | getDoacrossDependClauses() const { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 549 | assert(!isStackEmpty()); |
550 | auto &StackElem = Stack.back().first.back(); | ||||
551 | if (isOpenMPWorksharingDirective(StackElem.Directive)) { | ||||
552 | auto &Ref = StackElem.DoacrossDepends; | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 553 | return llvm::make_range(Ref.begin(), Ref.end()); |
554 | } | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 555 | return llvm::make_range(StackElem.DoacrossDepends.end(), |
556 | StackElem.DoacrossDepends.end()); | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 557 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 558 | }; |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 559 | bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 560 | return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || |
561 | isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 562 | } |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 563 | } // namespace |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 564 | |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 565 | static Expr *getExprAsWritten(Expr *E) { |
566 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) | ||||
567 | E = ExprTemp->getSubExpr(); | ||||
568 | |||||
569 | if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) | ||||
570 | E = MTE->GetTemporaryExpr(); | ||||
571 | |||||
572 | while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) | ||||
573 | E = Binder->getSubExpr(); | ||||
574 | |||||
575 | if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) | ||||
576 | E = ICE->getSubExprAsWritten(); | ||||
577 | return E->IgnoreParens(); | ||||
578 | } | ||||
579 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 580 | static ValueDecl *getCanonicalDecl(ValueDecl *D) { |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 581 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) |
582 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||
583 | D = ME->getMemberDecl(); | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 584 | auto *VD = dyn_cast<VarDecl>(D); |
585 | auto *FD = dyn_cast<FieldDecl>(D); | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 586 | if (VD != nullptr) { |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 587 | VD = VD->getCanonicalDecl(); |
588 | D = VD; | ||||
589 | } else { | ||||
590 | assert(FD); | ||||
591 | FD = FD->getCanonicalDecl(); | ||||
592 | D = FD; | ||||
593 | } | ||||
594 | return D; | ||||
595 | } | ||||
596 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 597 | DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 598 | ValueDecl *D) { |
599 | D = getCanonicalDecl(D); | ||||
600 | auto *VD = dyn_cast<VarDecl>(D); | ||||
601 | auto *FD = dyn_cast<FieldDecl>(D); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 602 | DSAVarData DVar; |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 603 | if (isStackEmpty() || Iter == Stack.back().first.rend()) { |
Alexey Bataev | 750a58b | 2014-03-18 12:19:12 +0000 | [diff] [blame] | 604 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
605 | // in a region but not in construct] | ||||
606 | // File-scope or namespace-scope variables referenced in called routines | ||||
607 | // in the region are shared unless they appear in a threadprivate | ||||
608 | // directive. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 609 | if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) |
Alexey Bataev | 750a58b | 2014-03-18 12:19:12 +0000 | [diff] [blame] | 610 | DVar.CKind = OMPC_shared; |
611 | |||||
612 | // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced | ||||
613 | // in a region but not in construct] | ||||
614 | // Variables with static storage duration that are declared in called | ||||
615 | // routines in the region are shared. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 616 | if (VD && VD->hasGlobalStorage()) |
617 | DVar.CKind = OMPC_shared; | ||||
618 | |||||
619 | // Non-static data members are shared by default. | ||||
620 | if (FD) | ||||
Alexey Bataev | 750a58b | 2014-03-18 12:19:12 +0000 | [diff] [blame] | 621 | DVar.CKind = OMPC_shared; |
622 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 623 | return DVar; |
624 | } | ||||
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 625 | |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 626 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
627 | // in a Construct, C/C++, predetermined, p.1] | ||||
628 | // Variables with automatic storage duration that are declared in a scope | ||||
629 | // inside the construct are private. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 630 | if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && |
631 | (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 632 | DVar.CKind = OMPC_private; |
633 | return DVar; | ||||
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 634 | } |
635 | |||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 636 | DVar.DKind = Iter->Directive; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 637 | // Explicitly specified attributes and local variables with predetermined |
638 | // attributes. | ||||
639 | if (Iter->SharingMap.count(D)) { | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 640 | DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer(); |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 641 | DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 642 | DVar.CKind = Iter->SharingMap[D].Attributes; |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 643 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 644 | return DVar; |
645 | } | ||||
646 | |||||
647 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
648 | // in a Construct, C/C++, implicitly determined, p.1] | ||||
649 | // In a parallel or task construct, the data-sharing attributes of these | ||||
650 | // variables are determined by the default clause, if present. | ||||
651 | switch (Iter->DefaultAttr) { | ||||
652 | case DSA_shared: | ||||
653 | DVar.CKind = OMPC_shared; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 654 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 655 | return DVar; |
656 | case DSA_none: | ||||
657 | return DVar; | ||||
658 | case DSA_unspecified: | ||||
659 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
660 | // in a Construct, implicitly determined, p.2] | ||||
661 | // In a parallel construct, if no default clause is present, these | ||||
662 | // variables are shared. | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 663 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; |
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 664 | if (isOpenMPParallelDirective(DVar.DKind) || |
665 | isOpenMPTeamsDirective(DVar.DKind)) { | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 666 | DVar.CKind = OMPC_shared; |
667 | return DVar; | ||||
668 | } | ||||
669 | |||||
670 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
671 | // in a Construct, implicitly determined, p.4] | ||||
672 | // In a task construct, if no default clause is present, a variable that in | ||||
673 | // the enclosing context is determined to be shared by all implicit tasks | ||||
674 | // bound to the current team is shared. | ||||
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 675 | if (isOpenMPTaskingDirective(DVar.DKind)) { |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 676 | DSAVarData DVarTemp; |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 677 | auto I = Iter, E = Stack.back().first.rend(); |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 678 | do { |
679 | ++I; | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 680 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 681 | // Referenced in a Construct, implicitly determined, p.6] |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 682 | // In a task construct, if no default clause is present, a variable |
683 | // whose data-sharing attribute is not determined by the rules above is | ||||
684 | // firstprivate. | ||||
685 | DVarTemp = getDSA(I, D); | ||||
686 | if (DVarTemp.CKind != OMPC_shared) { | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 687 | DVar.RefExpr = nullptr; |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 688 | DVar.CKind = OMPC_firstprivate; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 689 | return DVar; |
690 | } | ||||
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 691 | } while (I != E && !isParallelOrTaskRegion(I->Directive)); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 692 | DVar.CKind = |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 693 | (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 694 | return DVar; |
695 | } | ||||
696 | } | ||||
697 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
698 | // in a Construct, implicitly determined, p.3] | ||||
699 | // For constructs other than task, if no default clause is present, these | ||||
700 | // variables inherit their data-sharing attributes from the enclosing | ||||
701 | // context. | ||||
Dmitry Polukhin | dc78bc82 | 2016-04-01 09:52:30 +0000 | [diff] [blame] | 702 | return getDSA(++Iter, D); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 703 | } |
704 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 705 | Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 706 | assert(!isStackEmpty() && "Data sharing attributes stack is empty"); |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 707 | D = getCanonicalDecl(D); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 708 | auto &StackElem = Stack.back().first.back(); |
709 | auto It = StackElem.AlignedMap.find(D); | ||||
710 | if (It == StackElem.AlignedMap.end()) { | ||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 711 | assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 712 | StackElem.AlignedMap[D] = NewDE; |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 713 | return nullptr; |
714 | } else { | ||||
715 | assert(It->second && "Unexpected nullptr expr in the aligned map"); | ||||
716 | return It->second; | ||||
717 | } | ||||
718 | return nullptr; | ||||
719 | } | ||||
720 | |||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 721 | void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 722 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 723 | D = getCanonicalDecl(D); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 724 | auto &StackElem = Stack.back().first.back(); |
725 | StackElem.LCVMap.insert( | ||||
726 | {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)}); | ||||
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 727 | } |
728 | |||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 729 | DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 730 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 731 | D = getCanonicalDecl(D); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 732 | auto &StackElem = Stack.back().first.back(); |
733 | auto It = StackElem.LCVMap.find(D); | ||||
734 | if (It != StackElem.LCVMap.end()) | ||||
735 | return It->second; | ||||
736 | return {0, nullptr}; | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 737 | } |
738 | |||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 739 | DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 740 | assert(!isStackEmpty() && Stack.back().first.size() > 1 && |
741 | "Data-sharing attributes stack is empty"); | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 742 | D = getCanonicalDecl(D); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 743 | auto &StackElem = *std::next(Stack.back().first.rbegin()); |
744 | auto It = StackElem.LCVMap.find(D); | ||||
745 | if (It != StackElem.LCVMap.end()) | ||||
746 | return It->second; | ||||
747 | return {0, nullptr}; | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 748 | } |
749 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 750 | ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 751 | assert(!isStackEmpty() && Stack.back().first.size() > 1 && |
752 | "Data-sharing attributes stack is empty"); | ||||
753 | auto &StackElem = *std::next(Stack.back().first.rbegin()); | ||||
754 | if (StackElem.LCVMap.size() < I) | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 755 | return nullptr; |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 756 | for (auto &Pair : StackElem.LCVMap) |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 757 | if (Pair.second.first == I) |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 758 | return Pair.first; |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 759 | return nullptr; |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 760 | } |
761 | |||||
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 762 | void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, |
763 | DeclRefExpr *PrivateCopy) { | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 764 | D = getCanonicalDecl(D); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 765 | if (A == OMPC_threadprivate) { |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 766 | auto &Data = Threadprivates[D]; |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 767 | Data.Attributes = A; |
768 | Data.RefExpr.setPointer(E); | ||||
769 | Data.PrivateCopy = nullptr; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 770 | } else { |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 771 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); |
772 | auto &Data = Stack.back().first.back().SharingMap[D]; | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 773 | assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || |
774 | (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || | ||||
775 | (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || | ||||
776 | (isLoopControlVariable(D).first && A == OMPC_private)); | ||||
777 | if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { | ||||
778 | Data.RefExpr.setInt(/*IntVal=*/true); | ||||
779 | return; | ||||
780 | } | ||||
781 | const bool IsLastprivate = | ||||
782 | A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; | ||||
783 | Data.Attributes = A; | ||||
784 | Data.RefExpr.setPointerAndInt(E, IsLastprivate); | ||||
785 | Data.PrivateCopy = PrivateCopy; | ||||
786 | if (PrivateCopy) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 787 | auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 788 | Data.Attributes = A; |
789 | Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); | ||||
790 | Data.PrivateCopy = nullptr; | ||||
791 | } | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 792 | } |
793 | } | ||||
794 | |||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 795 | /// \brief Build a variable declaration for OpenMP loop iteration variable. |
796 | static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, | ||||
797 | StringRef Name, const AttrVec *Attrs = nullptr) { | ||||
798 | DeclContext *DC = SemaRef.CurContext; | ||||
799 | IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); | ||||
800 | TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); | ||||
801 | VarDecl *Decl = | ||||
802 | VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); | ||||
803 | if (Attrs) { | ||||
804 | for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); | ||||
805 | I != E; ++I) | ||||
806 | Decl->addAttr(*I); | ||||
807 | } | ||||
808 | Decl->setImplicit(); | ||||
809 | return Decl; | ||||
810 | } | ||||
811 | |||||
812 | static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, | ||||
813 | SourceLocation Loc, | ||||
814 | bool RefersToCapture = false) { | ||||
815 | D->setReferenced(); | ||||
816 | D->markUsed(S.Context); | ||||
817 | return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), | ||||
818 | SourceLocation(), D, RefersToCapture, Loc, Ty, | ||||
819 | VK_LValue); | ||||
820 | } | ||||
821 | |||||
822 | void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, | ||||
823 | BinaryOperatorKind BOK) { | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 824 | D = getCanonicalDecl(D); |
825 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 826 | assert( |
Richard Trieu | 09f1411 | 2017-07-21 21:29:35 +0000 | [diff] [blame] | 827 | Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 828 | "Additional reduction info may be specified only for reduction items."); |
829 | auto &ReductionData = Stack.back().first.back().ReductionMap[D]; | ||||
830 | assert(ReductionData.ReductionRange.isInvalid() && | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 831 | Stack.back().first.back().Directive == OMPD_taskgroup && |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 832 | "Additional reduction info may be specified only once for reduction " |
833 | "items."); | ||||
834 | ReductionData.set(BOK, SR); | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 835 | Expr *&TaskgroupReductionRef = |
836 | Stack.back().first.back().TaskgroupReductionRef; | ||||
837 | if (!TaskgroupReductionRef) { | ||||
Alexey Bataev | d070a58 | 2017-10-25 15:54:04 +0000 | [diff] [blame] | 838 | auto *VD = buildVarDecl(SemaRef, SR.getBegin(), |
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 839 | SemaRef.Context.VoidPtrTy, ".task_red."); |
Alexey Bataev | d070a58 | 2017-10-25 15:54:04 +0000 | [diff] [blame] | 840 | TaskgroupReductionRef = |
841 | buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 842 | } |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 843 | } |
844 | |||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 845 | void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, |
846 | const Expr *ReductionRef) { | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 847 | D = getCanonicalDecl(D); |
848 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 849 | assert( |
Richard Trieu | 09f1411 | 2017-07-21 21:29:35 +0000 | [diff] [blame] | 850 | Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 851 | "Additional reduction info may be specified only for reduction items."); |
852 | auto &ReductionData = Stack.back().first.back().ReductionMap[D]; | ||||
853 | assert(ReductionData.ReductionRange.isInvalid() && | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 854 | Stack.back().first.back().Directive == OMPD_taskgroup && |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 855 | "Additional reduction info may be specified only once for reduction " |
856 | "items."); | ||||
857 | ReductionData.set(ReductionRef, SR); | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 858 | Expr *&TaskgroupReductionRef = |
859 | Stack.back().first.back().TaskgroupReductionRef; | ||||
860 | if (!TaskgroupReductionRef) { | ||||
Alexey Bataev | d070a58 | 2017-10-25 15:54:04 +0000 | [diff] [blame] | 861 | auto *VD = buildVarDecl(SemaRef, SR.getBegin(), SemaRef.Context.VoidPtrTy, |
862 | ".task_red."); | ||||
863 | TaskgroupReductionRef = | ||||
864 | buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 865 | } |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 866 | } |
867 | |||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 868 | DSAStackTy::DSAVarData |
869 | DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 870 | BinaryOperatorKind &BOK, |
871 | Expr *&TaskgroupDescriptor) { | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 872 | D = getCanonicalDecl(D); |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 873 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); |
874 | if (Stack.back().first.empty()) | ||||
875 | return DSAVarData(); | ||||
876 | for (auto I = std::next(Stack.back().first.rbegin(), 1), | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 877 | E = Stack.back().first.rend(); |
878 | I != E; std::advance(I, 1)) { | ||||
879 | auto &Data = I->SharingMap[D]; | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 880 | if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 881 | continue; |
882 | auto &ReductionData = I->ReductionMap[D]; | ||||
883 | if (!ReductionData.ReductionOp || | ||||
884 | ReductionData.ReductionOp.is<const Expr *>()) | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 885 | return DSAVarData(); |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 886 | SR = ReductionData.ReductionRange; |
Alexey Bataev | f87fa88 | 2017-07-21 19:26:22 +0000 | [diff] [blame] | 887 | BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 888 | assert(I->TaskgroupReductionRef && "taskgroup reduction reference " |
889 | "expression for the descriptor is not " | ||||
890 | "set."); | ||||
891 | TaskgroupDescriptor = I->TaskgroupReductionRef; | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 892 | return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), |
893 | Data.PrivateCopy, I->DefaultAttrLoc); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 894 | } |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 895 | return DSAVarData(); |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 896 | } |
897 | |||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 898 | DSAStackTy::DSAVarData |
899 | DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 900 | const Expr *&ReductionRef, |
901 | Expr *&TaskgroupDescriptor) { | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 902 | D = getCanonicalDecl(D); |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 903 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); |
904 | if (Stack.back().first.empty()) | ||||
905 | return DSAVarData(); | ||||
906 | for (auto I = std::next(Stack.back().first.rbegin(), 1), | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 907 | E = Stack.back().first.rend(); |
908 | I != E; std::advance(I, 1)) { | ||||
909 | auto &Data = I->SharingMap[D]; | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 910 | if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 911 | continue; |
912 | auto &ReductionData = I->ReductionMap[D]; | ||||
913 | if (!ReductionData.ReductionOp || | ||||
914 | !ReductionData.ReductionOp.is<const Expr *>()) | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 915 | return DSAVarData(); |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 916 | SR = ReductionData.ReductionRange; |
917 | ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 918 | assert(I->TaskgroupReductionRef && "taskgroup reduction reference " |
919 | "expression for the descriptor is not " | ||||
920 | "set."); | ||||
921 | TaskgroupDescriptor = I->TaskgroupReductionRef; | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 922 | return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), |
923 | Data.PrivateCopy, I->DefaultAttrLoc); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 924 | } |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 925 | return DSAVarData(); |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 926 | } |
927 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 928 | bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { |
Alexey Bataev | 6ddfe1a | 2015-04-16 13:49:42 +0000 | [diff] [blame] | 929 | D = D->getCanonicalDecl(); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 930 | if (!isStackEmpty() && Stack.back().first.size() > 1) { |
931 | reverse_iterator I = Iter, E = Stack.back().first.rend(); | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 932 | Scope *TopScope = nullptr; |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 933 | while (I != E && !isParallelOrTaskRegion(I->Directive)) |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 934 | ++I; |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 935 | if (I == E) |
936 | return false; | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 937 | TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 938 | Scope *CurScope = getCurScope(); |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 939 | while (CurScope != TopScope && !CurScope->isDeclScope(D)) |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 940 | CurScope = CurScope->getParent(); |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 941 | return CurScope != TopScope; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 942 | } |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 943 | return false; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 944 | } |
945 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 946 | DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { |
947 | D = getCanonicalDecl(D); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 948 | DSAVarData DVar; |
949 | |||||
950 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
951 | // in a Construct, C/C++, predetermined, p.1] | ||||
952 | // Variables appearing in threadprivate directives are threadprivate. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 953 | auto *VD = dyn_cast<VarDecl>(D); |
954 | if ((VD && VD->getTLSKind() != VarDecl::TLS_None && | ||||
955 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && | ||||
Samuel Antao | f8b5012 | 2015-07-13 22:54:53 +0000 | [diff] [blame] | 956 | SemaRef.getLangOpts().OpenMPUseTLS && |
957 | SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 958 | (VD && VD->getStorageClass() == SC_Register && |
959 | VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { | ||||
960 | addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 961 | D->getLocation()), |
Alexey Bataev | f2453a0 | 2015-05-06 07:25:08 +0000 | [diff] [blame] | 962 | OMPC_threadprivate); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 963 | } |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 964 | auto TI = Threadprivates.find(D); |
965 | if (TI != Threadprivates.end()) { | ||||
966 | DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 967 | DVar.CKind = OMPC_threadprivate; |
968 | return DVar; | ||||
Alexey Bataev | 817d7f3 | 2017-11-14 21:01:01 +0000 | [diff] [blame] | 969 | } else if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { |
970 | DVar.RefExpr = buildDeclRefExpr( | ||||
971 | SemaRef, VD, D->getType().getNonReferenceType(), | ||||
972 | VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); | ||||
973 | DVar.CKind = OMPC_threadprivate; | ||||
974 | addDSA(D, DVar.RefExpr, OMPC_threadprivate); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 975 | } |
976 | |||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 977 | if (isStackEmpty()) |
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 978 | // Not in OpenMP execution region and top scope was already checked. |
979 | return DVar; | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 980 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 981 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
Alexey Bataev | dffa93a | 2015-12-10 08:20:58 +0000 | [diff] [blame] | 982 | // in a Construct, C/C++, predetermined, p.4] |
983 | // Static data members are shared. | ||||
984 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
985 | // in a Construct, C/C++, predetermined, p.7] | ||||
986 | // Variables with static storage duration that are declared in a scope | ||||
987 | // inside the construct are shared. | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 988 | auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; }; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 989 | if (VD && VD->isStaticDataMember()) { |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 990 | DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); |
Alexey Bataev | dffa93a | 2015-12-10 08:20:58 +0000 | [diff] [blame] | 991 | if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 992 | return DVar; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 993 | |
Alexey Bataev | dffa93a | 2015-12-10 08:20:58 +0000 | [diff] [blame] | 994 | DVar.CKind = OMPC_shared; |
995 | return DVar; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 996 | } |
997 | |||||
998 | QualType Type = D->getType().getNonReferenceType().getCanonicalType(); | ||||
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 999 | bool IsConstant = Type.isConstant(SemaRef.getASTContext()); |
1000 | Type = SemaRef.getASTContext().getBaseElementType(Type); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1001 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1002 | // in a Construct, C/C++, predetermined, p.6] | ||||
1003 | // Variables with const qualified type having no mutable member are | ||||
1004 | // shared. | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 1005 | CXXRecordDecl *RD = |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1006 | SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; |
Alexey Bataev | c9bd03d | 2015-12-17 06:55:08 +0000 | [diff] [blame] | 1007 | if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) |
1008 | if (auto *CTD = CTSD->getSpecializedTemplate()) | ||||
1009 | RD = CTD->getTemplatedDecl(); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1010 | if (IsConstant && |
Alexey Bataev | 4bcad7f | 2016-02-10 10:50:12 +0000 | [diff] [blame] | 1011 | !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && |
1012 | RD->hasMutableFields())) { | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1013 | // Variables with const-qualified type having no mutable member may be |
1014 | // listed in a firstprivate clause, even if they are static data members. | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1015 | DSAVarData DVarTemp = hasDSA( |
1016 | D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; }, | ||||
1017 | MatchesAlways, FromParent); | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 1018 | if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) |
1019 | return DVar; | ||||
1020 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1021 | DVar.CKind = OMPC_shared; |
1022 | return DVar; | ||||
1023 | } | ||||
1024 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1025 | // Explicitly specified attributes and local variables with predetermined |
1026 | // attributes. | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1027 | auto I = Stack.back().first.rbegin(); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1028 | auto EndI = Stack.back().first.rend(); |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1029 | if (FromParent && I != EndI) |
1030 | std::advance(I, 1); | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1031 | if (I->SharingMap.count(D)) { |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1032 | DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 1033 | DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1034 | DVar.CKind = I->SharingMap[D].Attributes; |
1035 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; | ||||
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 1036 | DVar.DKind = I->Directive; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1037 | } |
1038 | |||||
1039 | return DVar; | ||||
1040 | } | ||||
1041 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1042 | DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, |
1043 | bool FromParent) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1044 | if (isStackEmpty()) { |
1045 | StackTy::reverse_iterator I; | ||||
1046 | return getDSA(I, D); | ||||
1047 | } | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1048 | D = getCanonicalDecl(D); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1049 | auto StartI = Stack.back().first.rbegin(); |
1050 | auto EndI = Stack.back().first.rend(); | ||||
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 1051 | if (FromParent && StartI != EndI) |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1052 | std::advance(StartI, 1); |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1053 | return getDSA(StartI, D); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1054 | } |
1055 | |||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1056 | DSAStackTy::DSAVarData |
1057 | DSAStackTy::hasDSA(ValueDecl *D, | ||||
1058 | const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, | ||||
1059 | const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, | ||||
1060 | bool FromParent) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1061 | if (isStackEmpty()) |
1062 | return {}; | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1063 | D = getCanonicalDecl(D); |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1064 | auto I = Stack.back().first.rbegin(); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1065 | auto EndI = Stack.back().first.rend(); |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1066 | if (FromParent && I != EndI) |
Alexey Bataev | 0e6fc1c | 2017-04-27 14:46:26 +0000 | [diff] [blame] | 1067 | std::advance(I, 1); |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1068 | for (; I != EndI; std::advance(I, 1)) { |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1069 | if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1070 | continue; |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1071 | auto NewI = I; |
1072 | DSAVarData DVar = getDSA(NewI, D); | ||||
1073 | if (I == NewI && CPred(DVar.CKind)) | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 1074 | return DVar; |
Alexey Bataev | 60859c0 | 2017-04-27 15:10:33 +0000 | [diff] [blame] | 1075 | } |
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 1076 | return {}; |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 1077 | } |
1078 | |||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1079 | DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( |
1080 | ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, | ||||
1081 | const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, | ||||
1082 | bool FromParent) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1083 | if (isStackEmpty()) |
1084 | return {}; | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1085 | D = getCanonicalDecl(D); |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1086 | auto StartI = Stack.back().first.rbegin(); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1087 | auto EndI = Stack.back().first.rend(); |
Alexey Bataev | e397812 | 2016-07-19 05:06:39 +0000 | [diff] [blame] | 1088 | if (FromParent && StartI != EndI) |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1089 | std::advance(StartI, 1); |
Alexey Bataev | e397812 | 2016-07-19 05:06:39 +0000 | [diff] [blame] | 1090 | if (StartI == EndI || !DPred(StartI->Directive)) |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1091 | return {}; |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1092 | auto NewI = StartI; |
1093 | DSAVarData DVar = getDSA(NewI, D); | ||||
1094 | return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 1095 | } |
1096 | |||||
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1097 | bool DSAStackTy::hasExplicitDSA( |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1098 | ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1099 | unsigned Level, bool NotLastprivate) { |
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1100 | if (CPred(ClauseKindMode)) |
1101 | return true; | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1102 | if (isStackEmpty()) |
1103 | return false; | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1104 | D = getCanonicalDecl(D); |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1105 | auto StartI = Stack.back().first.begin(); |
1106 | auto EndI = Stack.back().first.end(); | ||||
NAKAMURA Takumi | 0332eda | 2015-06-23 10:01:20 +0000 | [diff] [blame] | 1107 | if (std::distance(StartI, EndI) <= (int)Level) |
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1108 | return false; |
1109 | std::advance(StartI, Level); | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1110 | return (StartI->SharingMap.count(D) > 0) && |
1111 | StartI->SharingMap[D].RefExpr.getPointer() && | ||||
1112 | CPred(StartI->SharingMap[D].Attributes) && | ||||
1113 | (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt()); | ||||
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1114 | } |
1115 | |||||
Samuel Antao | 4be30e9 | 2015-10-02 17:14:03 +0000 | [diff] [blame] | 1116 | bool DSAStackTy::hasExplicitDirective( |
1117 | const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, | ||||
1118 | unsigned Level) { | ||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1119 | if (isStackEmpty()) |
1120 | return false; | ||||
1121 | auto StartI = Stack.back().first.begin(); | ||||
1122 | auto EndI = Stack.back().first.end(); | ||||
Samuel Antao | 4be30e9 | 2015-10-02 17:14:03 +0000 | [diff] [blame] | 1123 | if (std::distance(StartI, EndI) <= (int)Level) |
1124 | return false; | ||||
1125 | std::advance(StartI, Level); | ||||
1126 | return DPred(StartI->Directive); | ||||
1127 | } | ||||
1128 | |||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1129 | bool DSAStackTy::hasDirective( |
1130 | const llvm::function_ref<bool(OpenMPDirectiveKind, | ||||
1131 | const DeclarationNameInfo &, SourceLocation)> | ||||
1132 | &DPred, | ||||
1133 | bool FromParent) { | ||||
Samuel Antao | f0d7975 | 2016-05-27 15:21:27 +0000 | [diff] [blame] | 1134 | // We look only in the enclosing region. |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1135 | if (isStackEmpty()) |
Samuel Antao | f0d7975 | 2016-05-27 15:21:27 +0000 | [diff] [blame] | 1136 | return false; |
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1137 | auto StartI = std::next(Stack.back().first.rbegin()); |
1138 | auto EndI = Stack.back().first.rend(); | ||||
Alexey Bataev | ccaddfb | 2017-04-26 14:24:21 +0000 | [diff] [blame] | 1139 | if (FromParent && StartI != EndI) |
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 1140 | StartI = std::next(StartI); |
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 1141 | for (auto I = StartI, EE = EndI; I != EE; ++I) { |
1142 | if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) | ||||
1143 | return true; | ||||
1144 | } | ||||
1145 | return false; | ||||
1146 | } | ||||
1147 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1148 | void Sema::InitDataSharingAttributesStack() { |
1149 | VarDataSharingAttributesStack = new DSAStackTy(*this); | ||||
1150 | } | ||||
1151 | |||||
1152 | #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) | ||||
1153 | |||||
Alexey Bataev | 4b46539 | 2017-04-26 15:06:24 +0000 | [diff] [blame] | 1154 | void Sema::pushOpenMPFunctionRegion() { |
1155 | DSAStack->pushFunction(); | ||||
1156 | } | ||||
1157 | |||||
1158 | void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { | ||||
1159 | DSAStack->popFunction(OldFSI); | ||||
1160 | } | ||||
1161 | |||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1162 | bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { |
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1163 | assert(LangOpts.OpenMP && "OpenMP is not allowed"); |
1164 | |||||
1165 | auto &Ctx = getASTContext(); | ||||
1166 | bool IsByRef = true; | ||||
1167 | |||||
1168 | // Find the directive that is associated with the provided scope. | ||||
Alexey Bataev | 0dce2ea | 2017-09-21 14:06:59 +0000 | [diff] [blame] | 1169 | D = cast<ValueDecl>(D->getCanonicalDecl()); |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1170 | auto Ty = D->getType(); |
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1171 | |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1172 | if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { |
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1173 | // This table summarizes how a given variable should be passed to the device |
1174 | // given its type and the clauses where it appears. This table is based on | ||||
1175 | // the description in OpenMP 4.5 [2.10.4, target Construct] and | ||||
1176 | // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. | ||||
1177 | // | ||||
1178 | // ========================================================================= | ||||
1179 | // | type | defaultmap | pvt | first | is_device_ptr | map | res. | | ||||
1180 | // | |(tofrom:scalar)| | pvt | | | | | ||||
1181 | // ========================================================================= | ||||
1182 | // | scl | | | | - | | bycopy| | ||||
1183 | // | scl | | - | x | - | - | bycopy| | ||||
1184 | // | scl | | x | - | - | - | null | | ||||
1185 | // | scl | x | | | - | | byref | | ||||
1186 | // | scl | x | - | x | - | - | bycopy| | ||||
1187 | // | scl | x | x | - | - | - | null | | ||||
1188 | // | scl | | - | - | - | x | byref | | ||||
1189 | // | scl | x | - | - | - | x | byref | | ||||
1190 | // | ||||
1191 | // | agg | n.a. | | | - | | byref | | ||||
1192 | // | agg | n.a. | - | x | - | - | byref | | ||||
1193 | // | agg | n.a. | x | - | - | - | null | | ||||
1194 | // | agg | n.a. | - | - | - | x | byref | | ||||
1195 | // | agg | n.a. | - | - | - | x[] | byref | | ||||
1196 | // | ||||
1197 | // | ptr | n.a. | | | - | | bycopy| | ||||
1198 | // | ptr | n.a. | - | x | - | - | bycopy| | ||||
1199 | // | ptr | n.a. | x | - | - | - | null | | ||||
1200 | // | ptr | n.a. | - | - | - | x | byref | | ||||
1201 | // | ptr | n.a. | - | - | - | x[] | bycopy| | ||||
1202 | // | ptr | n.a. | - | - | x | | bycopy| | ||||
1203 | // | ptr | n.a. | - | - | x | x | bycopy| | ||||
1204 | // | ptr | n.a. | - | - | x | x[] | bycopy| | ||||
1205 | // ========================================================================= | ||||
1206 | // Legend: | ||||
1207 | // scl - scalar | ||||
1208 | // ptr - pointer | ||||
1209 | // agg - aggregate | ||||
1210 | // x - applies | ||||
1211 | // - - invalid in this combination | ||||
1212 | // [] - mapped with an array section | ||||
1213 | // byref - should be mapped by reference | ||||
1214 | // byval - should be mapped by value | ||||
1215 | // null - initialize a local variable to null on the device | ||||
1216 | // | ||||
1217 | // Observations: | ||||
1218 | // - All scalar declarations that show up in a map clause have to be passed | ||||
1219 | // by reference, because they may have been mapped in the enclosing data | ||||
1220 | // environment. | ||||
1221 | // - If the scalar value does not fit the size of uintptr, it has to be | ||||
1222 | // passed by reference, regardless the result in the table above. | ||||
1223 | // - For pointers mapped by value that have either an implicit map or an | ||||
1224 | // array section, the runtime library may pass the NULL value to the | ||||
1225 | // device instead of the value passed to it by the compiler. | ||||
1226 | |||||
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1227 | if (Ty->isReferenceType()) |
1228 | Ty = Ty->castAs<ReferenceType>()->getPointeeType(); | ||||
Samuel Antao | 86ace55 | 2016-04-27 22:40:57 +0000 | [diff] [blame] | 1229 | |
1230 | // Locate map clauses and see if the variable being captured is referred to | ||||
1231 | // in any of those clauses. Here we only care about variables, not fields, | ||||
1232 | // because fields are part of aggregates. | ||||
1233 | bool IsVariableUsedInMapClause = false; | ||||
1234 | bool IsVariableAssociatedWithSection = false; | ||||
1235 | |||||
Jonas Hahnfeld | f7c4d7b | 2017-07-01 10:40:50 +0000 | [diff] [blame] | 1236 | DSAStack->checkMappableExprComponentListsForDeclAtLevel( |
1237 | D, Level, [&](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 1238 | MapExprComponents, |
1239 | OpenMPClauseKind WhereFoundClauseKind) { | ||||
1240 | // Only the map clause information influences how a variable is | ||||
1241 | // captured. E.g. is_device_ptr does not require changing the default | ||||
Samuel Antao | 4c8035b | 2016-12-12 18:00:20 +0000 | [diff] [blame] | 1242 | // behavior. |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 1243 | if (WhereFoundClauseKind != OMPC_map) |
1244 | return false; | ||||
Samuel Antao | 86ace55 | 2016-04-27 22:40:57 +0000 | [diff] [blame] | 1245 | |
1246 | auto EI = MapExprComponents.rbegin(); | ||||
1247 | auto EE = MapExprComponents.rend(); | ||||
1248 | |||||
1249 | assert(EI != EE && "Invalid map expression!"); | ||||
1250 | |||||
1251 | if (isa<DeclRefExpr>(EI->getAssociatedExpression())) | ||||
1252 | IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; | ||||
1253 | |||||
1254 | ++EI; | ||||
1255 | if (EI == EE) | ||||
1256 | return false; | ||||
1257 | |||||
1258 | if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || | ||||
1259 | isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || | ||||
1260 | isa<MemberExpr>(EI->getAssociatedExpression())) { | ||||
1261 | IsVariableAssociatedWithSection = true; | ||||
1262 | // There is nothing more we need to know about this variable. | ||||
1263 | return true; | ||||
1264 | } | ||||
1265 | |||||
1266 | // Keep looking for more map info. | ||||
1267 | return false; | ||||
1268 | }); | ||||
1269 | |||||
1270 | if (IsVariableUsedInMapClause) { | ||||
1271 | // If variable is identified in a map clause it is always captured by | ||||
1272 | // reference except if it is a pointer that is dereferenced somehow. | ||||
1273 | IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); | ||||
1274 | } else { | ||||
1275 | // By default, all the data that has a scalar type is mapped by copy. | ||||
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 1276 | IsByRef = !Ty->isScalarType() || |
1277 | DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar; | ||||
Samuel Antao | 86ace55 | 2016-04-27 22:40:57 +0000 | [diff] [blame] | 1278 | } |
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1279 | } |
1280 | |||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1281 | if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { |
1282 | IsByRef = !DSAStack->hasExplicitDSA( | ||||
1283 | D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, | ||||
1284 | Level, /*NotLastprivate=*/true); | ||||
1285 | } | ||||
1286 | |||||
Samuel Antao | 86ace55 | 2016-04-27 22:40:57 +0000 | [diff] [blame] | 1287 | // When passing data by copy, we need to make sure it fits the uintptr size |
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1288 | // and alignment, because the runtime library only deals with uintptr types. |
1289 | // If it does not fit the uintptr size, we need to pass the data by reference | ||||
1290 | // instead. | ||||
1291 | if (!IsByRef && | ||||
1292 | (Ctx.getTypeSizeInChars(Ty) > | ||||
1293 | Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1294 | Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { |
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1295 | IsByRef = true; |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1296 | } |
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 1297 | |
1298 | return IsByRef; | ||||
1299 | } | ||||
1300 | |||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1301 | unsigned Sema::getOpenMPNestingLevel() const { |
1302 | assert(getLangOpts().OpenMP); | ||||
1303 | return DSAStack->getNestingLevel(); | ||||
1304 | } | ||||
1305 | |||||
Jonas Hahnfeld | 87d4426 | 2017-11-18 21:00:46 +0000 | [diff] [blame] | 1306 | bool Sema::isInOpenMPTargetExecutionDirective() const { |
1307 | return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && | ||||
1308 | !DSAStack->isClauseParsingMode()) || | ||||
1309 | DSAStack->hasDirective( | ||||
1310 | [](OpenMPDirectiveKind K, const DeclarationNameInfo &, | ||||
1311 | SourceLocation) -> bool { | ||||
1312 | return isOpenMPTargetExecutionDirective(K); | ||||
1313 | }, | ||||
1314 | false); | ||||
1315 | } | ||||
1316 | |||||
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 1317 | VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { |
Alexey Bataev | f841bd9 | 2014-12-16 07:00:22 +0000 | [diff] [blame] | 1318 | assert(LangOpts.OpenMP && "OpenMP is not allowed"); |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1319 | D = getCanonicalDecl(D); |
Samuel Antao | 4be30e9 | 2015-10-02 17:14:03 +0000 | [diff] [blame] | 1320 | |
1321 | // If we are attempting to capture a global variable in a directive with | ||||
1322 | // 'target' we return true so that this global is also mapped to the device. | ||||
1323 | // | ||||
1324 | // FIXME: If the declaration is enclosed in a 'declare target' directive, | ||||
1325 | // then it should not be captured. Therefore, an extra check has to be | ||||
1326 | // inserted here once support for 'declare target' is added. | ||||
1327 | // | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1328 | auto *VD = dyn_cast<VarDecl>(D); |
Jonas Hahnfeld | 87d4426 | 2017-11-18 21:00:46 +0000 | [diff] [blame] | 1329 | if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective()) |
1330 | return VD; | ||||
Samuel Antao | 4be30e9 | 2015-10-02 17:14:03 +0000 | [diff] [blame] | 1331 | |
Alexey Bataev | 48977c3 | 2015-08-04 08:10:48 +0000 | [diff] [blame] | 1332 | if (DSAStack->getCurrentDirective() != OMPD_unknown && |
1333 | (!DSAStack->isClauseParsingMode() || | ||||
1334 | DSAStack->getParentDirective() != OMPD_unknown)) { | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 1335 | auto &&Info = DSAStack->isLoopControlVariable(D); |
1336 | if (Info.first || | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1337 | (VD && VD->hasLocalStorage() && |
Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 1338 | isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1339 | (VD && DSAStack->isForceVarCapturing())) |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 1340 | return VD ? VD : Info.second; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1341 | auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); |
Alexey Bataev | f841bd9 | 2014-12-16 07:00:22 +0000 | [diff] [blame] | 1342 | if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 1343 | return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1344 | DVarPrivate = DSAStack->hasDSA( |
1345 | D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, | ||||
1346 | DSAStack->isClauseParsingMode()); | ||||
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 1347 | if (DVarPrivate.CKind != OMPC_unknown) |
1348 | return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); | ||||
Alexey Bataev | f841bd9 | 2014-12-16 07:00:22 +0000 | [diff] [blame] | 1349 | } |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 1350 | return nullptr; |
Alexey Bataev | f841bd9 | 2014-12-16 07:00:22 +0000 | [diff] [blame] | 1351 | } |
1352 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1353 | bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { |
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1354 | assert(LangOpts.OpenMP && "OpenMP is not allowed"); |
1355 | return DSAStack->hasExplicitDSA( | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 1356 | D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, |
1357 | Level) || | ||||
1358 | // Consider taskgroup reduction descriptor variable a private to avoid | ||||
1359 | // possible capture in the region. | ||||
1360 | (DSAStack->hasExplicitDirective( | ||||
1361 | [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, | ||||
1362 | Level) && | ||||
1363 | DSAStack->isTaskgroupReductionRef(D, Level)); | ||||
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1364 | } |
1365 | |||||
Alexey Bataev | 3b8d558 | 2017-08-08 18:04:06 +0000 | [diff] [blame] | 1366 | void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) { |
1367 | assert(LangOpts.OpenMP && "OpenMP is not allowed"); | ||||
1368 | D = getCanonicalDecl(D); | ||||
1369 | OpenMPClauseKind OMPC = OMPC_unknown; | ||||
1370 | for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { | ||||
1371 | const unsigned NewLevel = I - 1; | ||||
1372 | if (DSAStack->hasExplicitDSA(D, | ||||
1373 | [&OMPC](const OpenMPClauseKind K) { | ||||
1374 | if (isOpenMPPrivate(K)) { | ||||
1375 | OMPC = K; | ||||
1376 | return true; | ||||
1377 | } | ||||
1378 | return false; | ||||
1379 | }, | ||||
1380 | NewLevel)) | ||||
1381 | break; | ||||
1382 | if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( | ||||
1383 | D, NewLevel, | ||||
1384 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef, | ||||
1385 | OpenMPClauseKind) { return true; })) { | ||||
1386 | OMPC = OMPC_map; | ||||
1387 | break; | ||||
1388 | } | ||||
1389 | if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, | ||||
1390 | NewLevel)) { | ||||
1391 | OMPC = OMPC_firstprivate; | ||||
1392 | break; | ||||
1393 | } | ||||
1394 | } | ||||
1395 | if (OMPC != OMPC_unknown) | ||||
1396 | FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); | ||||
1397 | } | ||||
1398 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1399 | bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { |
Samuel Antao | 4be30e9 | 2015-10-02 17:14:03 +0000 | [diff] [blame] | 1400 | assert(LangOpts.OpenMP && "OpenMP is not allowed"); |
1401 | // Return true if the current level is no longer enclosed in a target region. | ||||
1402 | |||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1403 | auto *VD = dyn_cast<VarDecl>(D); |
1404 | return VD && !VD->hasLocalStorage() && | ||||
Arpith Chacko Jacob | 3d58f26 | 2016-02-02 04:00:47 +0000 | [diff] [blame] | 1405 | DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, |
1406 | Level); | ||||
Samuel Antao | 4be30e9 | 2015-10-02 17:14:03 +0000 | [diff] [blame] | 1407 | } |
1408 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1409 | void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1410 | |
1411 | void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, | ||||
1412 | const DeclarationNameInfo &DirName, | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 1413 | Scope *CurScope, SourceLocation Loc) { |
1414 | DSAStack->push(DKind, DirName, CurScope, Loc); | ||||
Faisal Vali | d143a0c | 2017-04-01 21:30:49 +0000 | [diff] [blame] | 1415 | PushExpressionEvaluationContext( |
1416 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1417 | } |
1418 | |||||
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1419 | void Sema::StartOpenMPClause(OpenMPClauseKind K) { |
1420 | DSAStack->setClauseParsingMode(K); | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 1421 | } |
1422 | |||||
Alexey Bataev | aac108a | 2015-06-23 04:51:00 +0000 | [diff] [blame] | 1423 | void Sema::EndOpenMPClause() { |
1424 | DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 1425 | } |
1426 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1427 | void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 1428 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] |
1429 | // A variable of class type (or array thereof) that appears in a lastprivate | ||||
1430 | // clause requires an accessible, unambiguous default constructor for the | ||||
1431 | // class type, unless the list item is also specified in a firstprivate | ||||
1432 | // clause. | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 1433 | if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { |
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1434 | for (auto *C : D->clauses()) { |
1435 | if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { | ||||
1436 | SmallVector<Expr *, 8> PrivateCopies; | ||||
1437 | for (auto *DE : Clause->varlists()) { | ||||
1438 | if (DE->isValueDependent() || DE->isTypeDependent()) { | ||||
1439 | PrivateCopies.push_back(nullptr); | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 1440 | continue; |
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1441 | } |
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 1442 | auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 1443 | VarDecl *VD = cast<VarDecl>(DRE->getDecl()); |
1444 | QualType Type = VD->getType().getNonReferenceType(); | ||||
1445 | auto DVar = DSAStack->getTopDSA(VD, false); | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 1446 | if (DVar.CKind == OMPC_lastprivate) { |
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1447 | // Generate helper private variable and initialize it with the |
1448 | // default value. The address of the original variable is replaced | ||||
1449 | // by the address of the new private variable in CodeGen. This new | ||||
1450 | // variable is not added to IdResolver, so the code in the OpenMP | ||||
1451 | // region uses original variable for proper diagnostics. | ||||
Alexey Bataev | 1d7f0fa | 2015-09-10 09:48:30 +0000 | [diff] [blame] | 1452 | auto *VDPrivate = buildVarDecl( |
1453 | *this, DE->getExprLoc(), Type.getUnqualifiedType(), | ||||
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 1454 | VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); |
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 1455 | ActOnUninitializedDecl(VDPrivate); |
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1456 | if (VDPrivate->isInvalidDecl()) |
1457 | continue; | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 1458 | PrivateCopies.push_back(buildDeclRefExpr( |
1459 | *this, VDPrivate, DE->getType(), DE->getExprLoc())); | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1460 | } else { |
1461 | // The variable is also a firstprivate, so initialization sequence | ||||
1462 | // for private copy is generated already. | ||||
1463 | PrivateCopies.push_back(nullptr); | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 1464 | } |
1465 | } | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1466 | // Set initializers to private copies if no errors were found. |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1467 | if (PrivateCopies.size() == Clause->varlist_size()) |
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 1468 | Clause->setPrivateCopies(PrivateCopies); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 1469 | } |
1470 | } | ||||
1471 | } | ||||
1472 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1473 | DSAStack->pop(); |
1474 | DiscardCleanupsInEvaluationContext(); | ||||
1475 | PopExpressionEvaluationContext(); | ||||
1476 | } | ||||
1477 | |||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 1478 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, |
1479 | Expr *NumIterations, Sema &SemaRef, | ||||
1480 | Scope *S, DSAStackTy *Stack); | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 1481 | |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1482 | namespace { |
1483 | |||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1484 | class VarDeclFilterCCC : public CorrectionCandidateCallback { |
1485 | private: | ||||
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1486 | Sema &SemaRef; |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1487 | |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1488 | public: |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1489 | explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} |
Craig Topper | e14c0f8 | 2014-03-12 04:55:44 +0000 | [diff] [blame] | 1490 | bool ValidateCandidate(const TypoCorrection &Candidate) override { |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1491 | NamedDecl *ND = Candidate.getCorrectionDecl(); |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 1492 | if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) { |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1493 | return VD->hasGlobalStorage() && |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1494 | SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), |
1495 | SemaRef.getCurScope()); | ||||
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1496 | } |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1497 | return false; |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1498 | } |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1499 | }; |
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 1500 | |
1501 | class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { | ||||
1502 | private: | ||||
1503 | Sema &SemaRef; | ||||
1504 | |||||
1505 | public: | ||||
1506 | explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} | ||||
1507 | bool ValidateCandidate(const TypoCorrection &Candidate) override { | ||||
1508 | NamedDecl *ND = Candidate.getCorrectionDecl(); | ||||
Kelvin Li | 59e3d19 | 2017-11-30 18:52:06 +0000 | [diff] [blame] | 1509 | if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) { |
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 1510 | return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), |
1511 | SemaRef.getCurScope()); | ||||
1512 | } | ||||
1513 | return false; | ||||
1514 | } | ||||
1515 | }; | ||||
1516 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1517 | } // namespace |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1518 | |
1519 | ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, | ||||
1520 | CXXScopeSpec &ScopeSpec, | ||||
1521 | const DeclarationNameInfo &Id) { | ||||
1522 | LookupResult Lookup(*this, Id, LookupOrdinaryName); | ||||
1523 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); | ||||
1524 | |||||
1525 | if (Lookup.isAmbiguous()) | ||||
1526 | return ExprError(); | ||||
1527 | |||||
1528 | VarDecl *VD; | ||||
1529 | if (!Lookup.isSingleResult()) { | ||||
Kaelyn Takata | 89c881b | 2014-10-27 18:07:29 +0000 | [diff] [blame] | 1530 | if (TypoCorrection Corrected = CorrectTypo( |
1531 | Id, LookupOrdinaryName, CurScope, nullptr, | ||||
1532 | llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { | ||||
Richard Smith | f9b1510 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 1533 | diagnoseTypo(Corrected, |
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 1534 | PDiag(Lookup.empty() |
1535 | ? diag::err_undeclared_var_use_suggest | ||||
1536 | : diag::err_omp_expected_var_arg_suggest) | ||||
1537 | << Id.getName()); | ||||
Richard Smith | f9b1510 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 1538 | VD = Corrected.getCorrectionDeclAs<VarDecl>(); |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1539 | } else { |
Richard Smith | f9b1510 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 1540 | Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use |
1541 | : diag::err_omp_expected_var_arg) | ||||
1542 | << Id.getName(); | ||||
1543 | return ExprError(); | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1544 | } |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1545 | } else { |
1546 | if (!(VD = Lookup.getAsSingle<VarDecl>())) { | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1547 | Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1548 | Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); |
1549 | return ExprError(); | ||||
1550 | } | ||||
1551 | } | ||||
1552 | Lookup.suppressDiagnostics(); | ||||
1553 | |||||
1554 | // OpenMP [2.9.2, Syntax, C/C++] | ||||
1555 | // Variables must be file-scope, namespace-scope, or static block-scope. | ||||
1556 | if (!VD->hasGlobalStorage()) { | ||||
1557 | Diag(Id.getLoc(), diag::err_omp_global_var_arg) | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1558 | << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); |
1559 | bool IsDecl = | ||||
1560 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1561 | Diag(VD->getLocation(), |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1562 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
1563 | << VD; | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1564 | return ExprError(); |
1565 | } | ||||
1566 | |||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1567 | VarDecl *CanonicalVD = VD->getCanonicalDecl(); |
1568 | NamedDecl *ND = cast<NamedDecl>(CanonicalVD); | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1569 | // OpenMP [2.9.2, Restrictions, C/C++, p.2] |
1570 | // A threadprivate directive for file-scope variables must appear outside | ||||
1571 | // any definition or declaration. | ||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1572 | if (CanonicalVD->getDeclContext()->isTranslationUnit() && |
1573 | !getCurLexicalContext()->isTranslationUnit()) { | ||||
1574 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1575 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; |
1576 | bool IsDecl = | ||||
1577 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
1578 | Diag(VD->getLocation(), | ||||
1579 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
1580 | << VD; | ||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1581 | return ExprError(); |
1582 | } | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1583 | // OpenMP [2.9.2, Restrictions, C/C++, p.3] |
1584 | // A threadprivate directive for static class member variables must appear | ||||
1585 | // in the class definition, in the same scope in which the member | ||||
1586 | // variables are declared. | ||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1587 | if (CanonicalVD->isStaticDataMember() && |
1588 | !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { | ||||
1589 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1590 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; |
1591 | bool IsDecl = | ||||
1592 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
1593 | Diag(VD->getLocation(), | ||||
1594 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
1595 | << VD; | ||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1596 | return ExprError(); |
1597 | } | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1598 | // OpenMP [2.9.2, Restrictions, C/C++, p.4] |
1599 | // A threadprivate directive for namespace-scope variables must appear | ||||
1600 | // outside any definition or declaration other than the namespace | ||||
1601 | // definition itself. | ||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1602 | if (CanonicalVD->getDeclContext()->isNamespace() && |
1603 | (!getCurLexicalContext()->isFileContext() || | ||||
1604 | !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { | ||||
1605 | Diag(Id.getLoc(), diag::err_omp_var_scope) | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1606 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; |
1607 | bool IsDecl = | ||||
1608 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
1609 | Diag(VD->getLocation(), | ||||
1610 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
1611 | << VD; | ||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1612 | return ExprError(); |
1613 | } | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1614 | // OpenMP [2.9.2, Restrictions, C/C++, p.6] |
1615 | // A threadprivate directive for static block-scope variables must appear | ||||
1616 | // in the scope of the variable and not in a nested scope. | ||||
Alexey Bataev | 7d2960b | 2013-09-26 03:24:06 +0000 | [diff] [blame] | 1617 | if (CanonicalVD->isStaticLocal() && CurScope && |
1618 | !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1619 | Diag(Id.getLoc(), diag::err_omp_var_scope) |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1620 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; |
1621 | bool IsDecl = | ||||
1622 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
1623 | Diag(VD->getLocation(), | ||||
1624 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
1625 | << VD; | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1626 | return ExprError(); |
1627 | } | ||||
1628 | |||||
1629 | // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] | ||||
1630 | // A threadprivate directive must lexically precede all references to any | ||||
1631 | // of the variables in its list. | ||||
Alexey Bataev | 6ddfe1a | 2015-04-16 13:49:42 +0000 | [diff] [blame] | 1632 | if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1633 | Diag(Id.getLoc(), diag::err_omp_var_used) |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1634 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1635 | return ExprError(); |
1636 | } | ||||
1637 | |||||
1638 | QualType ExprType = VD->getType().getNonReferenceType(); | ||||
Alexey Bataev | 376b4a4 | 2016-02-09 09:41:09 +0000 | [diff] [blame] | 1639 | return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), |
1640 | SourceLocation(), VD, | ||||
1641 | /*RefersToEnclosingVariableOrCapture=*/false, | ||||
1642 | Id.getLoc(), ExprType, VK_LValue); | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1643 | } |
1644 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1645 | Sema::DeclGroupPtrTy |
1646 | Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, | ||||
1647 | ArrayRef<Expr *> VarList) { | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1648 | if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1649 | CurContext->addDecl(D); |
1650 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | ||||
1651 | } | ||||
David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 1652 | return nullptr; |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1653 | } |
1654 | |||||
Alexey Bataev | 18b92ee | 2014-05-28 07:40:25 +0000 | [diff] [blame] | 1655 | namespace { |
1656 | class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { | ||||
1657 | Sema &SemaRef; | ||||
1658 | |||||
1659 | public: | ||||
1660 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 1661 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { |
Alexey Bataev | 18b92ee | 2014-05-28 07:40:25 +0000 | [diff] [blame] | 1662 | if (VD->hasLocalStorage()) { |
1663 | SemaRef.Diag(E->getLocStart(), | ||||
1664 | diag::err_omp_local_var_in_threadprivate_init) | ||||
1665 | << E->getSourceRange(); | ||||
1666 | SemaRef.Diag(VD->getLocation(), diag::note_defined_here) | ||||
1667 | << VD << VD->getSourceRange(); | ||||
1668 | return true; | ||||
1669 | } | ||||
1670 | } | ||||
1671 | return false; | ||||
1672 | } | ||||
1673 | bool VisitStmt(const Stmt *S) { | ||||
1674 | for (auto Child : S->children()) { | ||||
1675 | if (Child && Visit(Child)) | ||||
1676 | return true; | ||||
1677 | } | ||||
1678 | return false; | ||||
1679 | } | ||||
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 1680 | explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} |
Alexey Bataev | 18b92ee | 2014-05-28 07:40:25 +0000 | [diff] [blame] | 1681 | }; |
1682 | } // namespace | ||||
1683 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1684 | OMPThreadPrivateDecl * |
1685 | Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1686 | SmallVector<Expr *, 8> Vars; |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1687 | for (auto &RefExpr : VarList) { |
1688 | DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1689 | VarDecl *VD = cast<VarDecl>(DE->getDecl()); |
1690 | SourceLocation ILoc = DE->getExprLoc(); | ||||
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1691 | |
Alexey Bataev | 376b4a4 | 2016-02-09 09:41:09 +0000 | [diff] [blame] | 1692 | // Mark variable as used. |
1693 | VD->setReferenced(); | ||||
1694 | VD->markUsed(Context); | ||||
1695 | |||||
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 1696 | QualType QType = VD->getType(); |
1697 | if (QType->isDependentType() || QType->isInstantiationDependentType()) { | ||||
1698 | // It will be analyzed later. | ||||
1699 | Vars.push_back(DE); | ||||
1700 | continue; | ||||
1701 | } | ||||
1702 | |||||
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1703 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] |
1704 | // A threadprivate variable must not have an incomplete type. | ||||
1705 | if (RequireCompleteType(ILoc, VD->getType(), | ||||
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1706 | diag::err_omp_threadprivate_incomplete_type)) { |
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1707 | continue; |
1708 | } | ||||
1709 | |||||
1710 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] | ||||
1711 | // A threadprivate variable must not have a reference type. | ||||
1712 | if (VD->getType()->isReferenceType()) { | ||||
1713 | Diag(ILoc, diag::err_omp_ref_type_arg) | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1714 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); |
1715 | bool IsDecl = | ||||
1716 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
1717 | Diag(VD->getLocation(), | ||||
1718 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
1719 | << VD; | ||||
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1720 | continue; |
1721 | } | ||||
1722 | |||||
Samuel Antao | f8b5012 | 2015-07-13 22:54:53 +0000 | [diff] [blame] | 1723 | // Check if this is a TLS variable. If TLS is not being supported, produce |
1724 | // the corresponding diagnostic. | ||||
1725 | if ((VD->getTLSKind() != VarDecl::TLS_None && | ||||
1726 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && | ||||
1727 | getLangOpts().OpenMPUseTLS && | ||||
1728 | getASTContext().getTargetInfo().isTLSSupported())) || | ||||
Alexey Bataev | 1a8b3f1 | 2015-05-06 06:34:55 +0000 | [diff] [blame] | 1729 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && |
1730 | !VD->isLocalVarDecl())) { | ||||
Alexey Bataev | 26a3924 | 2015-01-13 03:35:30 +0000 | [diff] [blame] | 1731 | Diag(ILoc, diag::err_omp_var_thread_local) |
1732 | << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1733 | bool IsDecl = |
1734 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
1735 | Diag(VD->getLocation(), | ||||
1736 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
1737 | << VD; | ||||
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1738 | continue; |
1739 | } | ||||
1740 | |||||
Alexey Bataev | 18b92ee | 2014-05-28 07:40:25 +0000 | [diff] [blame] | 1741 | // Check if initial value of threadprivate variable reference variable with |
1742 | // local storage (it is not supported by runtime). | ||||
1743 | if (auto Init = VD->getAnyInitializer()) { | ||||
1744 | LocalVarRefChecker Checker(*this); | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 1745 | if (Checker.Visit(Init)) |
1746 | continue; | ||||
Alexey Bataev | 18b92ee | 2014-05-28 07:40:25 +0000 | [diff] [blame] | 1747 | } |
1748 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1749 | Vars.push_back(RefExpr); |
Alexey Bataev | d178ad4 | 2014-03-07 08:03:37 +0000 | [diff] [blame] | 1750 | DSAStack->addDSA(VD, DE, OMPC_threadprivate); |
Alexey Bataev | 9772000 | 2014-11-11 04:05:39 +0000 | [diff] [blame] | 1751 | VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( |
1752 | Context, SourceRange(Loc, Loc))); | ||||
1753 | if (auto *ML = Context.getASTMutationListener()) | ||||
1754 | ML->DeclarationMarkedOpenMPThreadPrivate(VD); | ||||
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1755 | } |
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 1756 | OMPThreadPrivateDecl *D = nullptr; |
Alexey Bataev | ec3da87 | 2014-01-31 05:15:34 +0000 | [diff] [blame] | 1757 | if (!Vars.empty()) { |
1758 | D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, | ||||
1759 | Vars); | ||||
1760 | D->setAccess(AS_public); | ||||
1761 | } | ||||
1762 | return D; | ||||
Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1763 | } |
Alexey Bataev | 6f6f3b4 | 2013-05-13 04:18:18 +0000 | [diff] [blame] | 1764 | |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1765 | static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1766 | const ValueDecl *D, DSAStackTy::DSAVarData DVar, |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1767 | bool IsLoopIterVar = false) { |
1768 | if (DVar.RefExpr) { | ||||
1769 | SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) | ||||
1770 | << getOpenMPClauseName(DVar.CKind); | ||||
1771 | return; | ||||
1772 | } | ||||
1773 | enum { | ||||
1774 | PDSA_StaticMemberShared, | ||||
1775 | PDSA_StaticLocalVarShared, | ||||
1776 | PDSA_LoopIterVarPrivate, | ||||
1777 | PDSA_LoopIterVarLinear, | ||||
1778 | PDSA_LoopIterVarLastprivate, | ||||
1779 | PDSA_ConstVarShared, | ||||
1780 | PDSA_GlobalVarShared, | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1781 | PDSA_TaskVarFirstprivate, |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 1782 | PDSA_LocalVarPrivate, |
1783 | PDSA_Implicit | ||||
1784 | } Reason = PDSA_Implicit; | ||||
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1785 | bool ReportHint = false; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1786 | auto ReportLoc = D->getLocation(); |
1787 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1788 | if (IsLoopIterVar) { |
1789 | if (DVar.CKind == OMPC_private) | ||||
1790 | Reason = PDSA_LoopIterVarPrivate; | ||||
1791 | else if (DVar.CKind == OMPC_lastprivate) | ||||
1792 | Reason = PDSA_LoopIterVarLastprivate; | ||||
1793 | else | ||||
1794 | Reason = PDSA_LoopIterVarLinear; | ||||
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 1795 | } else if (isOpenMPTaskingDirective(DVar.DKind) && |
1796 | DVar.CKind == OMPC_firstprivate) { | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1797 | Reason = PDSA_TaskVarFirstprivate; |
1798 | ReportLoc = DVar.ImplicitDSALoc; | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1799 | } else if (VD && VD->isStaticLocal()) |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1800 | Reason = PDSA_StaticLocalVarShared; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1801 | else if (VD && VD->isStaticDataMember()) |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1802 | Reason = PDSA_StaticMemberShared; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1803 | else if (VD && VD->isFileVarDecl()) |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1804 | Reason = PDSA_GlobalVarShared; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1805 | else if (D->getType().isConstant(SemaRef.getASTContext())) |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1806 | Reason = PDSA_ConstVarShared; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1807 | else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1808 | ReportHint = true; |
1809 | Reason = PDSA_LocalVarPrivate; | ||||
1810 | } | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 1811 | if (Reason != PDSA_Implicit) { |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1812 | SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 1813 | << Reason << ReportHint |
1814 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); | ||||
1815 | } else if (DVar.ImplicitDSALoc.isValid()) { | ||||
1816 | SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) | ||||
1817 | << getOpenMPClauseName(DVar.CKind); | ||||
1818 | } | ||||
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1819 | } |
1820 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1821 | namespace { |
1822 | class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { | ||||
1823 | DSAStackTy *Stack; | ||||
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1824 | Sema &SemaRef; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1825 | bool ErrorFound; |
1826 | CapturedStmt *CS; | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 1827 | llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; |
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1828 | llvm::SmallVector<Expr *, 8> ImplicitMap; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1829 | llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; |
Alexey Bataev | 0dce2ea | 2017-09-21 14:06:59 +0000 | [diff] [blame] | 1830 | llvm::DenseSet<ValueDecl *> ImplicitDeclarations; |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1831 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1832 | public: |
1833 | void VisitDeclRefExpr(DeclRefExpr *E) { | ||||
Alexey Bataev | 07b79c2 | 2016-04-29 09:56:11 +0000 | [diff] [blame] | 1834 | if (E->isTypeDependent() || E->isValueDependent() || |
1835 | E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) | ||||
1836 | return; | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1837 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { |
Alexey Bataev | 0dce2ea | 2017-09-21 14:06:59 +0000 | [diff] [blame] | 1838 | VD = VD->getCanonicalDecl(); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1839 | // Skip internally declared variables. |
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 1840 | if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 1841 | return; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1842 | |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1843 | auto DVar = Stack->getTopDSA(VD, false); |
1844 | // Check if the variable has explicit DSA set and stop analysis if it so. | ||||
Alexey Bataev | 0dce2ea | 2017-09-21 14:06:59 +0000 | [diff] [blame] | 1845 | if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 1846 | return; |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1847 | |
Alexey Bataev | afe5057 | 2017-10-06 17:00:28 +0000 | [diff] [blame] | 1848 | // Skip internally declared static variables. |
1849 | if (VD->hasGlobalStorage() && !CS->capturesVariable(VD)) | ||||
1850 | return; | ||||
1851 | |||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1852 | auto ELoc = E->getExprLoc(); |
1853 | auto DKind = Stack->getCurrentDirective(); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1854 | // The default(none) clause requires that each variable that is referenced |
1855 | // in the construct, and does not have a predetermined data-sharing | ||||
1856 | // attribute, must have its data-sharing attribute explicitly determined | ||||
1857 | // by being listed in a data-sharing attribute clause. | ||||
1858 | if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1859 | isParallelOrTaskRegion(DKind) && |
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 1860 | VarsWithInheritedDSA.count(VD) == 0) { |
1861 | VarsWithInheritedDSA[VD] = E; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1862 | return; |
1863 | } | ||||
1864 | |||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1865 | if (isOpenMPTargetExecutionDirective(DKind) && |
1866 | !Stack->isLoopControlVariable(VD).first) { | ||||
1867 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||
1868 | VD, /*CurrentRegionOnly=*/true, | ||||
1869 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||
1870 | StackComponents, | ||||
1871 | OpenMPClauseKind) { | ||||
1872 | // Variable is used if it has been marked as an array, array | ||||
1873 | // section or the variable iself. | ||||
1874 | return StackComponents.size() == 1 || | ||||
1875 | std::all_of( | ||||
1876 | std::next(StackComponents.rbegin()), | ||||
1877 | StackComponents.rend(), | ||||
1878 | [](const OMPClauseMappableExprCommon:: | ||||
1879 | MappableComponent &MC) { | ||||
1880 | return MC.getAssociatedDeclaration() == | ||||
1881 | nullptr && | ||||
1882 | (isa<OMPArraySectionExpr>( | ||||
1883 | MC.getAssociatedExpression()) || | ||||
1884 | isa<ArraySubscriptExpr>( | ||||
1885 | MC.getAssociatedExpression())); | ||||
1886 | }); | ||||
1887 | })) { | ||||
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 1888 | bool IsFirstprivate = false; |
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1889 | // By default lambdas are captured as firstprivates. |
1890 | if (const auto *RD = | ||||
1891 | VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) | ||||
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 1892 | IsFirstprivate = RD->isLambda(); |
1893 | IsFirstprivate = | ||||
1894 | IsFirstprivate || | ||||
1895 | (VD->getType().getNonReferenceType()->isScalarType() && | ||||
1896 | Stack->getDefaultDMA() != DMA_tofrom_scalar); | ||||
1897 | if (IsFirstprivate) | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1898 | ImplicitFirstprivate.emplace_back(E); |
1899 | else | ||||
1900 | ImplicitMap.emplace_back(E); | ||||
1901 | return; | ||||
1902 | } | ||||
1903 | } | ||||
1904 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1905 | // OpenMP [2.9.3.6, Restrictions, p.2] |
1906 | // A list item that appears in a reduction clause of the innermost | ||||
1907 | // enclosing worksharing or parallel construct may not be accessed in an | ||||
1908 | // explicit task. | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 1909 | DVar = Stack->hasInnermostDSA( |
1910 | VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, | ||||
1911 | [](OpenMPDirectiveKind K) -> bool { | ||||
1912 | return isOpenMPParallelDirective(K) || | ||||
1913 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); | ||||
1914 | }, | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 1915 | /*FromParent=*/true); |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 1916 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 1917 | ErrorFound = true; |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 1918 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); |
1919 | ReportOriginalDSA(SemaRef, Stack, VD, DVar); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 1920 | return; |
1921 | } | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1922 | |
1923 | // Define implicit data-sharing attributes for task. | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1924 | DVar = Stack->getImplicitDSA(VD, false); |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 1925 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && |
1926 | !Stack->isLoopControlVariable(VD).first) | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 1927 | ImplicitFirstprivate.push_back(E); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 1928 | } |
1929 | } | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1930 | void VisitMemberExpr(MemberExpr *E) { |
Alexey Bataev | 07b79c2 | 2016-04-29 09:56:11 +0000 | [diff] [blame] | 1931 | if (E->isTypeDependent() || E->isValueDependent() || |
1932 | E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) | ||||
1933 | return; | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1934 | auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); |
1935 | if (!FD) | ||||
1936 | return; | ||||
1937 | OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1938 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { |
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1939 | auto DVar = Stack->getTopDSA(FD, false); |
1940 | // Check if the variable has explicit DSA set and stop analysis if it | ||||
1941 | // so. | ||||
1942 | if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) | ||||
1943 | return; | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1944 | |
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1945 | if (isOpenMPTargetExecutionDirective(DKind) && |
1946 | !Stack->isLoopControlVariable(FD).first && | ||||
1947 | !Stack->checkMappableExprComponentListsForDecl( | ||||
1948 | FD, /*CurrentRegionOnly=*/true, | ||||
1949 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||
1950 | StackComponents, | ||||
1951 | OpenMPClauseKind) { | ||||
1952 | return isa<CXXThisExpr>( | ||||
1953 | cast<MemberExpr>( | ||||
1954 | StackComponents.back().getAssociatedExpression()) | ||||
1955 | ->getBase() | ||||
1956 | ->IgnoreParens()); | ||||
1957 | })) { | ||||
1958 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] | ||||
1959 | // A bit-field cannot appear in a map clause. | ||||
1960 | // | ||||
1961 | if (FD->isBitField()) { | ||||
1962 | SemaRef.Diag(E->getMemberLoc(), | ||||
1963 | diag::err_omp_bit_fields_forbidden_in_clause) | ||||
1964 | << E->getSourceRange() << getOpenMPClauseName(OMPC_map); | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1965 | return; |
1966 | } | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1967 | ImplicitMap.emplace_back(E); |
1968 | return; | ||||
1969 | } | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 1970 | |
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 1971 | auto ELoc = E->getExprLoc(); |
1972 | // OpenMP [2.9.3.6, Restrictions, p.2] | ||||
1973 | // A list item that appears in a reduction clause of the innermost | ||||
1974 | // enclosing worksharing or parallel construct may not be accessed in | ||||
1975 | // an explicit task. | ||||
1976 | DVar = Stack->hasInnermostDSA( | ||||
1977 | FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, | ||||
1978 | [](OpenMPDirectiveKind K) -> bool { | ||||
1979 | return isOpenMPParallelDirective(K) || | ||||
1980 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); | ||||
1981 | }, | ||||
1982 | /*FromParent=*/true); | ||||
1983 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { | ||||
1984 | ErrorFound = true; | ||||
1985 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); | ||||
1986 | ReportOriginalDSA(SemaRef, Stack, FD, DVar); | ||||
1987 | return; | ||||
1988 | } | ||||
1989 | |||||
1990 | // Define implicit data-sharing attributes for task. | ||||
1991 | DVar = Stack->getImplicitDSA(FD, false); | ||||
1992 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && | ||||
1993 | !Stack->isLoopControlVariable(FD).first) | ||||
1994 | ImplicitFirstprivate.push_back(E); | ||||
1995 | return; | ||||
1996 | } | ||||
1997 | if (isOpenMPTargetExecutionDirective(DKind) && !FD->isBitField()) { | ||||
1998 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; | ||||
1999 | CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map); | ||||
2000 | auto *VD = cast<ValueDecl>( | ||||
2001 | CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); | ||||
2002 | if (!Stack->checkMappableExprComponentListsForDecl( | ||||
2003 | VD, /*CurrentRegionOnly=*/true, | ||||
2004 | [&CurComponents]( | ||||
2005 | OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||
2006 | StackComponents, | ||||
2007 | OpenMPClauseKind) { | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2008 | auto CCI = CurComponents.rbegin(); |
Alexey Bataev | 5ec3893 | 2017-09-26 16:19:04 +0000 | [diff] [blame] | 2009 | auto CCE = CurComponents.rend(); |
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2010 | for (const auto &SC : llvm::reverse(StackComponents)) { |
2011 | // Do both expressions have the same kind? | ||||
2012 | if (CCI->getAssociatedExpression()->getStmtClass() != | ||||
2013 | SC.getAssociatedExpression()->getStmtClass()) | ||||
2014 | if (!(isa<OMPArraySectionExpr>( | ||||
2015 | SC.getAssociatedExpression()) && | ||||
2016 | isa<ArraySubscriptExpr>( | ||||
2017 | CCI->getAssociatedExpression()))) | ||||
2018 | return false; | ||||
2019 | |||||
2020 | Decl *CCD = CCI->getAssociatedDeclaration(); | ||||
2021 | Decl *SCD = SC.getAssociatedDeclaration(); | ||||
2022 | CCD = CCD ? CCD->getCanonicalDecl() : nullptr; | ||||
2023 | SCD = SCD ? SCD->getCanonicalDecl() : nullptr; | ||||
2024 | if (SCD != CCD) | ||||
2025 | return false; | ||||
2026 | std::advance(CCI, 1); | ||||
Alexey Bataev | 5ec3893 | 2017-09-26 16:19:04 +0000 | [diff] [blame] | 2027 | if (CCI == CCE) |
2028 | break; | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2029 | } |
2030 | return true; | ||||
2031 | })) { | ||||
2032 | Visit(E->getBase()); | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 2033 | } |
Alexey Bataev | 7fcacd8 | 2016-11-28 15:55:15 +0000 | [diff] [blame] | 2034 | } else |
2035 | Visit(E->getBase()); | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 2036 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2037 | void VisitOMPExecutableDirective(OMPExecutableDirective *S) { |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2038 | for (auto *C : S->clauses()) { |
2039 | // Skip analysis of arguments of implicitly defined firstprivate clause | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2040 | // for task|target directives. |
2041 | // Skip analysis of arguments of implicitly defined map clause for target | ||||
2042 | // directives. | ||||
2043 | if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && | ||||
2044 | C->isImplicit())) { | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2045 | for (auto *CC : C->children()) { |
2046 | if (CC) | ||||
2047 | Visit(CC); | ||||
2048 | } | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2049 | } |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2050 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2051 | } |
2052 | void VisitStmt(Stmt *S) { | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2053 | for (auto *C : S->children()) { |
2054 | if (C && !isa<OMPExecutableDirective>(C)) | ||||
2055 | Visit(C); | ||||
2056 | } | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 2057 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2058 | |
2059 | bool isErrorFound() { return ErrorFound; } | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2060 | ArrayRef<Expr *> getImplicitFirstprivate() const { |
2061 | return ImplicitFirstprivate; | ||||
2062 | } | ||||
2063 | ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 2064 | llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { |
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 2065 | return VarsWithInheritedDSA; |
2066 | } | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2067 | |
Alexey Bataev | 7ff5524 | 2014-06-19 09:13:45 +0000 | [diff] [blame] | 2068 | DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) |
2069 | : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2070 | }; |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 2071 | } // namespace |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2072 | |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 2073 | void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { |
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2074 | switch (DKind) { |
Kelvin Li | 70a12c5 | 2016-07-13 21:51:49 +0000 | [diff] [blame] | 2075 | case OMPD_parallel: |
2076 | case OMPD_parallel_for: | ||||
2077 | case OMPD_parallel_for_simd: | ||||
2078 | case OMPD_parallel_sections: | ||||
Carlo Bertolli | ba1487b | 2017-10-04 14:12:09 +0000 | [diff] [blame] | 2079 | case OMPD_teams: |
2080 | case OMPD_teams_distribute: { | ||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2081 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); |
Alexey Bataev | 2377fe9 | 2015-09-10 08:12:02 +0000 | [diff] [blame] | 2082 | QualType KmpInt32PtrTy = |
2083 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||
Alexey Bataev | df9b159 | 2014-06-25 04:09:13 +0000 | [diff] [blame] | 2084 | Sema::CapturedParamNameType Params[] = { |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 2085 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
2086 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||
2087 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2088 | }; |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 2089 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, |
2090 | Params); | ||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2091 | break; |
2092 | } | ||||
Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 2093 | case OMPD_target_teams: |
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 2094 | case OMPD_target_parallel: |
Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 2095 | case OMPD_target_parallel_for: |
2096 | case OMPD_target_parallel_for_simd: { | ||||
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2097 | Sema::CapturedParamNameType ParamsTarget[] = { |
2098 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||
2099 | }; | ||||
2100 | // Start a captured region for 'target' with no implicit parameters. | ||||
2101 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, | ||||
2102 | ParamsTarget); | ||||
2103 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | ||||
2104 | QualType KmpInt32PtrTy = | ||||
2105 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||
Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 2106 | Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { |
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2107 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
2108 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||
2109 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||
2110 | }; | ||||
Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 2111 | // Start a captured region for 'teams' or 'parallel'. Both regions have |
2112 | // the same implicit parameters. | ||||
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2113 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, |
Arpith Chacko Jacob | 99a1e0e | 2017-01-25 02:18:43 +0000 | [diff] [blame] | 2114 | ParamsTeamsOrParallel); |
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2115 | break; |
2116 | } | ||||
Kelvin Li | 70a12c5 | 2016-07-13 21:51:49 +0000 | [diff] [blame] | 2117 | case OMPD_simd: |
2118 | case OMPD_for: | ||||
2119 | case OMPD_for_simd: | ||||
2120 | case OMPD_sections: | ||||
2121 | case OMPD_section: | ||||
2122 | case OMPD_single: | ||||
2123 | case OMPD_master: | ||||
2124 | case OMPD_critical: | ||||
Kelvin Li | a579b91 | 2016-07-14 02:54:56 +0000 | [diff] [blame] | 2125 | case OMPD_taskgroup: |
2126 | case OMPD_distribute: | ||||
Kelvin Li | 70a12c5 | 2016-07-13 21:51:49 +0000 | [diff] [blame] | 2127 | case OMPD_ordered: |
2128 | case OMPD_atomic: | ||||
2129 | case OMPD_target_data: | ||||
2130 | case OMPD_target: | ||||
Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 2131 | case OMPD_target_simd: { |
Alexey Bataev | df9b159 | 2014-06-25 04:09:13 +0000 | [diff] [blame] | 2132 | Sema::CapturedParamNameType Params[] = { |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 2133 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
2134 | }; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 2135 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, |
2136 | Params); | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 2137 | break; |
2138 | } | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2139 | case OMPD_task: { |
Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 2140 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); |
Alexey Bataev | 3ae88e2 | 2015-05-22 08:56:35 +0000 | [diff] [blame] | 2141 | QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; |
2142 | FunctionProtoType::ExtProtoInfo EPI; | ||||
2143 | EPI.Variadic = true; | ||||
2144 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2145 | Sema::CapturedParamNameType Params[] = { |
Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 2146 | std::make_pair(".global_tid.", KmpInt32Ty), |
Alexey Bataev | 48591dd | 2016-04-20 04:01:36 +0000 | [diff] [blame] | 2147 | std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), |
2148 | std::make_pair(".privates.", Context.VoidPtrTy.withConst()), | ||||
2149 | std::make_pair(".copy_fn.", | ||||
2150 | Context.getPointerType(CopyFnType).withConst()), | ||||
2151 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2152 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
2153 | }; | ||||
2154 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, | ||||
2155 | Params); | ||||
Alexey Bataev | 62b63b1 | 2015-03-10 07:28:44 +0000 | [diff] [blame] | 2156 | // Mark this captured region as inlined, because we don't use outlined |
2157 | // function directly. | ||||
2158 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||
2159 | AlwaysInlineAttr::CreateImplicit( | ||||
2160 | Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2161 | break; |
2162 | } | ||||
Alexey Bataev | 1e73ef3 | 2016-04-28 12:14:51 +0000 | [diff] [blame] | 2163 | case OMPD_taskloop: |
2164 | case OMPD_taskloop_simd: { | ||||
Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 2165 | QualType KmpInt32Ty = |
2166 | Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); | ||||
2167 | QualType KmpUInt64Ty = | ||||
2168 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); | ||||
2169 | QualType KmpInt64Ty = | ||||
2170 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); | ||||
2171 | QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; | ||||
2172 | FunctionProtoType::ExtProtoInfo EPI; | ||||
2173 | EPI.Variadic = true; | ||||
2174 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 2175 | Sema::CapturedParamNameType Params[] = { |
Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 2176 | std::make_pair(".global_tid.", KmpInt32Ty), |
2177 | std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), | ||||
2178 | std::make_pair(".privates.", | ||||
2179 | Context.VoidPtrTy.withConst().withRestrict()), | ||||
2180 | std::make_pair( | ||||
2181 | ".copy_fn.", | ||||
2182 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | ||||
2183 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||
2184 | std::make_pair(".lb.", KmpUInt64Ty), | ||||
2185 | std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), | ||||
2186 | std::make_pair(".liter.", KmpInt32Ty), | ||||
Alexey Bataev | be5a8b4 | 2017-07-17 13:30:36 +0000 | [diff] [blame] | 2187 | std::make_pair(".reductions.", |
2188 | Context.VoidPtrTy.withConst().withRestrict()), | ||||
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 2189 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
2190 | }; | ||||
2191 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, | ||||
2192 | Params); | ||||
Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 2193 | // Mark this captured region as inlined, because we don't use outlined |
2194 | // function directly. | ||||
2195 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||
2196 | AlwaysInlineAttr::CreateImplicit( | ||||
2197 | Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); | ||||
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 2198 | break; |
2199 | } | ||||
Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 2200 | case OMPD_distribute_parallel_for_simd: |
Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 2201 | case OMPD_distribute_simd: |
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 2202 | case OMPD_distribute_parallel_for: |
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 2203 | case OMPD_teams_distribute_simd: |
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 2204 | case OMPD_teams_distribute_parallel_for_simd: |
Kelvin Li | 80e8f56 | 2016-12-29 22:16:30 +0000 | [diff] [blame] | 2205 | case OMPD_target_teams_distribute: |
Kelvin Li | 1851df5 | 2017-01-03 05:23:48 +0000 | [diff] [blame] | 2206 | case OMPD_target_teams_distribute_parallel_for: |
Kelvin Li | da68118 | 2017-01-10 18:08:18 +0000 | [diff] [blame] | 2207 | case OMPD_target_teams_distribute_parallel_for_simd: |
2208 | case OMPD_target_teams_distribute_simd: { | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 2209 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); |
2210 | QualType KmpInt32PtrTy = | ||||
2211 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||
2212 | Sema::CapturedParamNameType Params[] = { | ||||
2213 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||
2214 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||
2215 | std::make_pair(".previous.lb.", Context.getSizeType()), | ||||
2216 | std::make_pair(".previous.ub.", Context.getSizeType()), | ||||
2217 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||
2218 | }; | ||||
2219 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, | ||||
2220 | Params); | ||||
2221 | break; | ||||
2222 | } | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 2223 | case OMPD_teams_distribute_parallel_for: { |
2224 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | ||||
2225 | QualType KmpInt32PtrTy = | ||||
2226 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); | ||||
2227 | |||||
2228 | Sema::CapturedParamNameType ParamsTeams[] = { | ||||
2229 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||
2230 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||
2231 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||
2232 | }; | ||||
2233 | // Start a captured region for 'target' with no implicit parameters. | ||||
2234 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, | ||||
2235 | ParamsTeams); | ||||
2236 | |||||
2237 | Sema::CapturedParamNameType ParamsParallel[] = { | ||||
2238 | std::make_pair(".global_tid.", KmpInt32PtrTy), | ||||
2239 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | ||||
2240 | std::make_pair(".previous.lb.", Context.getSizeType()), | ||||
2241 | std::make_pair(".previous.ub.", Context.getSizeType()), | ||||
2242 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||
2243 | }; | ||||
2244 | // Start a captured region for 'teams' or 'parallel'. Both regions have | ||||
2245 | // the same implicit parameters. | ||||
2246 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, | ||||
2247 | ParamsParallel); | ||||
2248 | break; | ||||
2249 | } | ||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 2250 | case OMPD_target_update: |
2251 | case OMPD_target_enter_data: | ||||
2252 | case OMPD_target_exit_data: { | ||||
2253 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | ||||
2254 | QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; | ||||
2255 | FunctionProtoType::ExtProtoInfo EPI; | ||||
2256 | EPI.Variadic = true; | ||||
2257 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | ||||
2258 | Sema::CapturedParamNameType Params[] = { | ||||
2259 | std::make_pair(".global_tid.", KmpInt32Ty), | ||||
2260 | std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), | ||||
2261 | std::make_pair(".privates.", Context.VoidPtrTy.withConst()), | ||||
2262 | std::make_pair(".copy_fn.", | ||||
2263 | Context.getPointerType(CopyFnType).withConst()), | ||||
2264 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), | ||||
2265 | std::make_pair(StringRef(), QualType()) // __context with shared vars | ||||
2266 | }; | ||||
2267 | ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, | ||||
2268 | Params); | ||||
2269 | // Mark this captured region as inlined, because we don't use outlined | ||||
2270 | // function directly. | ||||
2271 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | ||||
2272 | AlwaysInlineAttr::CreateImplicit( | ||||
2273 | Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); | ||||
2274 | break; | ||||
2275 | } | ||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2276 | case OMPD_threadprivate: |
Alexey Bataev | ee9af45 | 2014-11-21 11:33:46 +0000 | [diff] [blame] | 2277 | case OMPD_taskyield: |
2278 | case OMPD_barrier: | ||||
2279 | case OMPD_taskwait: | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2280 | case OMPD_cancellation_point: |
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 2281 | case OMPD_cancel: |
Alexey Bataev | ee9af45 | 2014-11-21 11:33:46 +0000 | [diff] [blame] | 2282 | case OMPD_flush: |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 2283 | case OMPD_declare_reduction: |
Alexey Bataev | 587e1de | 2016-03-30 10:43:55 +0000 | [diff] [blame] | 2284 | case OMPD_declare_simd: |
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 2285 | case OMPD_declare_target: |
2286 | case OMPD_end_declare_target: | ||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2287 | llvm_unreachable("OpenMP Directive is not allowed"); |
2288 | case OMPD_unknown: | ||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 2289 | llvm_unreachable("Unknown OpenMP directive"); |
2290 | } | ||||
2291 | } | ||||
2292 | |||||
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2293 | int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { |
2294 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; | ||||
2295 | getOpenMPCaptureRegions(CaptureRegions, DKind); | ||||
2296 | return CaptureRegions.size(); | ||||
2297 | } | ||||
2298 | |||||
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 2299 | static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 2300 | Expr *CaptureExpr, bool WithInit, |
2301 | bool AsExpression) { | ||||
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 2302 | assert(CaptureExpr); |
Alexey Bataev | 4244be2 | 2016-02-11 05:35:55 +0000 | [diff] [blame] | 2303 | ASTContext &C = S.getASTContext(); |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 2304 | Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); |
Alexey Bataev | 4244be2 | 2016-02-11 05:35:55 +0000 | [diff] [blame] | 2305 | QualType Ty = Init->getType(); |
2306 | if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { | ||||
2307 | if (S.getLangOpts().CPlusPlus) | ||||
2308 | Ty = C.getLValueReferenceType(Ty); | ||||
2309 | else { | ||||
2310 | Ty = C.getPointerType(Ty); | ||||
2311 | ExprResult Res = | ||||
2312 | S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); | ||||
2313 | if (!Res.isUsable()) | ||||
2314 | return nullptr; | ||||
2315 | Init = Res.get(); | ||||
2316 | } | ||||
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 2317 | WithInit = true; |
Alexey Bataev | 4244be2 | 2016-02-11 05:35:55 +0000 | [diff] [blame] | 2318 | } |
Alexey Bataev | a7206b9 | 2016-12-20 16:51:02 +0000 | [diff] [blame] | 2319 | auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, |
2320 | CaptureExpr->getLocStart()); | ||||
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 2321 | if (!WithInit) |
2322 | CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); | ||||
Alexey Bataev | 4244be2 | 2016-02-11 05:35:55 +0000 | [diff] [blame] | 2323 | S.CurContext->addHiddenDecl(CED); |
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 2324 | S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); |
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 2325 | return CED; |
2326 | } | ||||
2327 | |||||
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 2328 | static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, |
2329 | bool WithInit) { | ||||
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 2330 | OMPCapturedExprDecl *CD; |
2331 | if (auto *VD = S.IsOpenMPCapturedDecl(D)) | ||||
2332 | CD = cast<OMPCapturedExprDecl>(VD); | ||||
2333 | else | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 2334 | CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, |
2335 | /*AsExpression=*/false); | ||||
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 2336 | return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 2337 | CaptureExpr->getExprLoc()); |
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 2338 | } |
2339 | |||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 2340 | static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { |
2341 | if (!Ref) { | ||||
2342 | auto *CD = | ||||
2343 | buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), | ||||
2344 | CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); | ||||
2345 | Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), | ||||
2346 | CaptureExpr->getExprLoc()); | ||||
2347 | } | ||||
2348 | ExprResult Res = Ref; | ||||
2349 | if (!S.getLangOpts().CPlusPlus && | ||||
2350 | CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && | ||||
2351 | Ref->getType()->isPointerType()) | ||||
2352 | Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); | ||||
2353 | if (!Res.isUsable()) | ||||
2354 | return ExprError(); | ||||
2355 | return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); | ||||
Alexey Bataev | 4244be2 | 2016-02-11 05:35:55 +0000 | [diff] [blame] | 2356 | } |
2357 | |||||
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2358 | namespace { |
2359 | // OpenMP directives parsed in this section are represented as a | ||||
2360 | // CapturedStatement with an associated statement. If a syntax error | ||||
2361 | // is detected during the parsing of the associated statement, the | ||||
2362 | // compiler must abort processing and close the CapturedStatement. | ||||
2363 | // | ||||
2364 | // Combined directives such as 'target parallel' have more than one | ||||
2365 | // nested CapturedStatements. This RAII ensures that we unwind out | ||||
2366 | // of all the nested CapturedStatements when an error is found. | ||||
2367 | class CaptureRegionUnwinderRAII { | ||||
2368 | private: | ||||
2369 | Sema &S; | ||||
2370 | bool &ErrorFound; | ||||
2371 | OpenMPDirectiveKind DKind; | ||||
2372 | |||||
2373 | public: | ||||
2374 | CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, | ||||
2375 | OpenMPDirectiveKind DKind) | ||||
2376 | : S(S), ErrorFound(ErrorFound), DKind(DKind) {} | ||||
2377 | ~CaptureRegionUnwinderRAII() { | ||||
2378 | if (ErrorFound) { | ||||
2379 | int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); | ||||
2380 | while (--ThisCaptureLevel >= 0) | ||||
2381 | S.ActOnCapturedRegionError(); | ||||
2382 | } | ||||
2383 | } | ||||
2384 | }; | ||||
2385 | } // namespace | ||||
2386 | |||||
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2387 | StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, |
2388 | ArrayRef<OMPClause *> Clauses) { | ||||
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2389 | bool ErrorFound = false; |
2390 | CaptureRegionUnwinderRAII CaptureRegionUnwinder( | ||||
2391 | *this, ErrorFound, DSAStack->getCurrentDirective()); | ||||
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2392 | if (!S.isUsable()) { |
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2393 | ErrorFound = true; |
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2394 | return StmtError(); |
2395 | } | ||||
Alexey Bataev | 993d280 | 2015-12-28 06:23:08 +0000 | [diff] [blame] | 2396 | |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 2397 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
2398 | getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); | ||||
Alexey Bataev | 993d280 | 2015-12-28 06:23:08 +0000 | [diff] [blame] | 2399 | OMPOrderedClause *OC = nullptr; |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 2400 | OMPScheduleClause *SC = nullptr; |
Alexey Bataev | 993d280 | 2015-12-28 06:23:08 +0000 | [diff] [blame] | 2401 | SmallVector<OMPLinearClause *, 4> LCs; |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 2402 | SmallVector<OMPClauseWithPreInit *, 8> PICs; |
Alexey Bataev | 040d540 | 2015-05-12 08:35:28 +0000 | [diff] [blame] | 2403 | // This is required for proper codegen. |
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2404 | for (auto *Clause : Clauses) { |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 2405 | if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && |
2406 | Clause->getClauseKind() == OMPC_in_reduction) { | ||||
2407 | // Capture taskgroup task_reduction descriptors inside the tasking regions | ||||
2408 | // with the corresponding in_reduction items. | ||||
2409 | auto *IRC = cast<OMPInReductionClause>(Clause); | ||||
2410 | for (auto *E : IRC->taskgroup_descriptors()) | ||||
2411 | if (E) | ||||
2412 | MarkDeclarationsReferencedInExpr(E); | ||||
2413 | } | ||||
Alexey Bataev | 16dc7b6 | 2015-05-20 03:46:04 +0000 | [diff] [blame] | 2414 | if (isOpenMPPrivate(Clause->getClauseKind()) || |
Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 2415 | Clause->getClauseKind() == OMPC_copyprivate || |
2416 | (getLangOpts().OpenMPUseTLS && | ||||
2417 | getASTContext().getTargetInfo().isTLSSupported() && | ||||
2418 | Clause->getClauseKind() == OMPC_copyin)) { | ||||
2419 | DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); | ||||
Alexey Bataev | 040d540 | 2015-05-12 08:35:28 +0000 | [diff] [blame] | 2420 | // Mark all variables in private list clauses as used in inner region. |
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2421 | for (auto *VarRef : Clause->children()) { |
2422 | if (auto *E = cast_or_null<Expr>(VarRef)) { | ||||
Alexey Bataev | 8bf6b3e | 2015-04-02 13:07:08 +0000 | [diff] [blame] | 2423 | MarkDeclarationsReferencedInExpr(E); |
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2424 | } |
2425 | } | ||||
Samuel Antao | 9c75cfe | 2015-07-27 16:38:06 +0000 | [diff] [blame] | 2426 | DSAStack->setForceVarCapturing(/*V=*/false); |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 2427 | } else if (CaptureRegions.size() > 1 || |
2428 | CaptureRegions.back() != OMPD_unknown) { | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 2429 | if (auto *C = OMPClauseWithPreInit::get(Clause)) |
2430 | PICs.push_back(C); | ||||
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 2431 | if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { |
2432 | if (auto *E = C->getPostUpdateExpr()) | ||||
2433 | MarkDeclarationsReferencedInExpr(E); | ||||
2434 | } | ||||
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2435 | } |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 2436 | if (Clause->getClauseKind() == OMPC_schedule) |
2437 | SC = cast<OMPScheduleClause>(Clause); | ||||
2438 | else if (Clause->getClauseKind() == OMPC_ordered) | ||||
Alexey Bataev | 993d280 | 2015-12-28 06:23:08 +0000 | [diff] [blame] | 2439 | OC = cast<OMPOrderedClause>(Clause); |
2440 | else if (Clause->getClauseKind() == OMPC_linear) | ||||
2441 | LCs.push_back(cast<OMPLinearClause>(Clause)); | ||||
2442 | } | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 2443 | // OpenMP, 2.7.1 Loop Construct, Restrictions |
2444 | // The nonmonotonic modifier cannot be specified if an ordered clause is | ||||
2445 | // specified. | ||||
2446 | if (SC && | ||||
2447 | (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || | ||||
2448 | SC->getSecondScheduleModifier() == | ||||
2449 | OMPC_SCHEDULE_MODIFIER_nonmonotonic) && | ||||
2450 | OC) { | ||||
2451 | Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic | ||||
2452 | ? SC->getFirstScheduleModifierLoc() | ||||
2453 | : SC->getSecondScheduleModifierLoc(), | ||||
2454 | diag::err_omp_schedule_nonmonotonic_ordered) | ||||
2455 | << SourceRange(OC->getLocStart(), OC->getLocEnd()); | ||||
2456 | ErrorFound = true; | ||||
2457 | } | ||||
Alexey Bataev | 993d280 | 2015-12-28 06:23:08 +0000 | [diff] [blame] | 2458 | if (!LCs.empty() && OC && OC->getNumForLoops()) { |
2459 | for (auto *C : LCs) { | ||||
2460 | Diag(C->getLocStart(), diag::err_omp_linear_ordered) | ||||
2461 | << SourceRange(OC->getLocStart(), OC->getLocEnd()); | ||||
2462 | } | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 2463 | ErrorFound = true; |
2464 | } | ||||
Alexey Bataev | 113438c | 2015-12-30 12:06:23 +0000 | [diff] [blame] | 2465 | if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && |
2466 | isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && | ||||
2467 | OC->getNumForLoops()) { | ||||
2468 | Diag(OC->getLocStart(), diag::err_omp_ordered_simd) | ||||
2469 | << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); | ||||
2470 | ErrorFound = true; | ||||
2471 | } | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 2472 | if (ErrorFound) { |
Alexey Bataev | 993d280 | 2015-12-28 06:23:08 +0000 | [diff] [blame] | 2473 | return StmtError(); |
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2474 | } |
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2475 | StmtResult SR = S; |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 2476 | for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 2477 | // Mark all variables in private list clauses as used in inner region. |
2478 | // Required for proper codegen of combined directives. | ||||
2479 | // TODO: add processing for other clauses. | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 2480 | if (ThisCaptureRegion != OMPD_unknown) { |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 2481 | for (auto *C : PICs) { |
2482 | OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); | ||||
2483 | // Find the particular capture region for the clause if the | ||||
2484 | // directive is a combined one with multiple capture regions. | ||||
2485 | // If the directive is not a combined one, the capture region | ||||
2486 | // associated with the clause is OMPD_unknown and is generated | ||||
2487 | // only once. | ||||
2488 | if (CaptureRegion == ThisCaptureRegion || | ||||
2489 | CaptureRegion == OMPD_unknown) { | ||||
2490 | if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { | ||||
2491 | for (auto *D : DS->decls()) | ||||
2492 | MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); | ||||
2493 | } | ||||
2494 | } | ||||
2495 | } | ||||
2496 | } | ||||
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2497 | SR = ActOnCapturedRegionEnd(SR.get()); |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 2498 | } |
Arpith Chacko Jacob | 19b911c | 2017-01-18 18:18:53 +0000 | [diff] [blame] | 2499 | return SR; |
Alexey Bataev | a8d4a543 | 2015-04-02 07:48:16 +0000 | [diff] [blame] | 2500 | } |
2501 | |||||
Jonas Hahnfeld | 64a9e3c | 2017-02-22 06:49:10 +0000 | [diff] [blame] | 2502 | static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, |
2503 | OpenMPDirectiveKind CancelRegion, | ||||
2504 | SourceLocation StartLoc) { | ||||
2505 | // CancelRegion is only needed for cancel and cancellation_point. | ||||
2506 | if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) | ||||
2507 | return false; | ||||
2508 | |||||
2509 | if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || | ||||
2510 | CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) | ||||
2511 | return false; | ||||
2512 | |||||
2513 | SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) | ||||
2514 | << getOpenMPDirectiveName(CancelRegion); | ||||
2515 | return true; | ||||
2516 | } | ||||
2517 | |||||
2518 | static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, | ||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 2519 | OpenMPDirectiveKind CurrentRegion, |
2520 | const DeclarationNameInfo &CurrentName, | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2521 | OpenMPDirectiveKind CancelRegion, |
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 2522 | SourceLocation StartLoc) { |
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2523 | if (Stack->getCurScope()) { |
2524 | auto ParentRegion = Stack->getParentDirective(); | ||||
Arpith Chacko Jacob | 3d58f26 | 2016-02-02 04:00:47 +0000 | [diff] [blame] | 2525 | auto OffendingRegion = ParentRegion; |
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2526 | bool NestingProhibited = false; |
2527 | bool CloseNesting = true; | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 2528 | bool OrphanSeen = false; |
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2529 | enum { |
2530 | NoRecommend, | ||||
2531 | ShouldBeInParallelRegion, | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 2532 | ShouldBeInOrderedRegion, |
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 2533 | ShouldBeInTargetRegion, |
2534 | ShouldBeInTeamsRegion | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2535 | } Recommend = NoRecommend; |
Kelvin Li | fd8b574 | 2016-07-01 14:30:25 +0000 | [diff] [blame] | 2536 | if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { |
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2537 | // OpenMP [2.16, Nesting of Regions] |
2538 | // OpenMP constructs may not be nested inside a simd region. | ||||
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 2539 | // OpenMP [2.8.1,simd Construct, Restrictions] |
Kelvin Li | fd8b574 | 2016-07-01 14:30:25 +0000 | [diff] [blame] | 2540 | // An ordered construct with the simd clause is the only OpenMP |
2541 | // construct that can appear in the simd region. | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 2542 | // Allowing a SIMD construct nested in another SIMD construct is an |
Kelvin Li | fd8b574 | 2016-07-01 14:30:25 +0000 | [diff] [blame] | 2543 | // extension. The OpenMP 4.5 spec does not allow it. Issue a warning |
2544 | // message. | ||||
2545 | SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) | ||||
2546 | ? diag::err_omp_prohibited_region_simd | ||||
2547 | : diag::warn_omp_nesting_simd); | ||||
2548 | return CurrentRegion != OMPD_simd; | ||||
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2549 | } |
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 2550 | if (ParentRegion == OMPD_atomic) { |
2551 | // OpenMP [2.16, Nesting of Regions] | ||||
2552 | // OpenMP constructs may not be nested inside an atomic region. | ||||
2553 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); | ||||
2554 | return true; | ||||
2555 | } | ||||
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 2556 | if (CurrentRegion == OMPD_section) { |
2557 | // OpenMP [2.7.2, sections Construct, Restrictions] | ||||
2558 | // Orphaned section directives are prohibited. That is, the section | ||||
2559 | // directives must appear within the sections construct and must not be | ||||
2560 | // encountered elsewhere in the sections region. | ||||
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 2561 | if (ParentRegion != OMPD_sections && |
2562 | ParentRegion != OMPD_parallel_sections) { | ||||
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 2563 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) |
2564 | << (ParentRegion != OMPD_unknown) | ||||
2565 | << getOpenMPDirectiveName(ParentRegion); | ||||
2566 | return true; | ||||
2567 | } | ||||
2568 | return false; | ||||
2569 | } | ||||
Kelvin Li | 2b51f72 | 2016-07-26 04:32:50 +0000 | [diff] [blame] | 2570 | // Allow some constructs (except teams) to be orphaned (they could be |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 2571 | // used in functions, called from OpenMP regions with the required |
Kelvin Li | 2b51f72 | 2016-07-26 04:32:50 +0000 | [diff] [blame] | 2572 | // preconditions). |
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 2573 | if (ParentRegion == OMPD_unknown && |
2574 | !isOpenMPNestingTeamsDirective(CurrentRegion)) | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2575 | return false; |
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 2576 | if (CurrentRegion == OMPD_cancellation_point || |
2577 | CurrentRegion == OMPD_cancel) { | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2578 | // OpenMP [2.16, Nesting of Regions] |
2579 | // A cancellation point construct for which construct-type-clause is | ||||
2580 | // taskgroup must be nested inside a task construct. A cancellation | ||||
2581 | // point construct for which construct-type-clause is not taskgroup must | ||||
2582 | // be closely nested inside an OpenMP construct that matches the type | ||||
2583 | // specified in construct-type-clause. | ||||
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 2584 | // A cancel construct for which construct-type-clause is taskgroup must be |
2585 | // nested inside a task construct. A cancel construct for which | ||||
2586 | // construct-type-clause is not taskgroup must be closely nested inside an | ||||
2587 | // OpenMP construct that matches the type specified in | ||||
2588 | // construct-type-clause. | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2589 | NestingProhibited = |
Arpith Chacko Jacob | e955b3d | 2016-01-26 18:48:41 +0000 | [diff] [blame] | 2590 | !((CancelRegion == OMPD_parallel && |
2591 | (ParentRegion == OMPD_parallel || | ||||
2592 | ParentRegion == OMPD_target_parallel)) || | ||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 2593 | (CancelRegion == OMPD_for && |
Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 2594 | (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || |
Alexey Bataev | dcb4b8fb | 2017-11-22 20:19:50 +0000 | [diff] [blame] | 2595 | ParentRegion == OMPD_target_parallel_for || |
2596 | ParentRegion == OMPD_distribute_parallel_for || | ||||
Alexey Bataev | 16e7988 | 2017-11-22 21:12:03 +0000 | [diff] [blame] | 2597 | ParentRegion == OMPD_teams_distribute_parallel_for || |
2598 | ParentRegion == OMPD_target_teams_distribute_parallel_for)) || | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2599 | (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || |
2600 | (CancelRegion == OMPD_sections && | ||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 2601 | (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || |
2602 | ParentRegion == OMPD_parallel_sections))); | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2603 | } else if (CurrentRegion == OMPD_master) { |
Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 2604 | // OpenMP [2.16, Nesting of Regions] |
2605 | // A master region may not be closely nested inside a worksharing, | ||||
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 2606 | // atomic, or explicit task region. |
Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 2607 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 2608 | isOpenMPTaskingDirective(ParentRegion); |
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 2609 | } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { |
2610 | // OpenMP [2.16, Nesting of Regions] | ||||
2611 | // A critical region may not be nested (closely or otherwise) inside a | ||||
2612 | // critical region with the same name. Note that this restriction is not | ||||
2613 | // sufficient to prevent deadlock. | ||||
2614 | SourceLocation PreviousCriticalLoc; | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 2615 | bool DeadLock = Stack->hasDirective( |
2616 | [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, | ||||
2617 | const DeclarationNameInfo &DNI, | ||||
2618 | SourceLocation Loc) -> bool { | ||||
2619 | if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { | ||||
2620 | PreviousCriticalLoc = Loc; | ||||
2621 | return true; | ||||
2622 | } else | ||||
2623 | return false; | ||||
2624 | }, | ||||
2625 | false /* skip top directive */); | ||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 2626 | if (DeadLock) { |
2627 | SemaRef.Diag(StartLoc, | ||||
2628 | diag::err_omp_prohibited_region_critical_same_name) | ||||
2629 | << CurrentName.getName(); | ||||
2630 | if (PreviousCriticalLoc.isValid()) | ||||
2631 | SemaRef.Diag(PreviousCriticalLoc, | ||||
2632 | diag::note_omp_previous_critical_region); | ||||
2633 | return true; | ||||
2634 | } | ||||
Alexey Bataev | 4d1dfea | 2014-07-18 09:11:51 +0000 | [diff] [blame] | 2635 | } else if (CurrentRegion == OMPD_barrier) { |
2636 | // OpenMP [2.16, Nesting of Regions] | ||||
2637 | // A barrier region may not be closely nested inside a worksharing, | ||||
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 2638 | // explicit task, critical, ordered, atomic, or master region. |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 2639 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || |
2640 | isOpenMPTaskingDirective(ParentRegion) || | ||||
2641 | ParentRegion == OMPD_master || | ||||
2642 | ParentRegion == OMPD_critical || | ||||
2643 | ParentRegion == OMPD_ordered; | ||||
Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 2644 | } else if (isOpenMPWorksharingDirective(CurrentRegion) && |
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 2645 | !isOpenMPParallelDirective(CurrentRegion) && |
2646 | !isOpenMPTeamsDirective(CurrentRegion)) { | ||||
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2647 | // OpenMP [2.16, Nesting of Regions] |
2648 | // A worksharing region may not be closely nested inside a worksharing, | ||||
2649 | // explicit task, critical, ordered, atomic, or master region. | ||||
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 2650 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || |
2651 | isOpenMPTaskingDirective(ParentRegion) || | ||||
2652 | ParentRegion == OMPD_master || | ||||
2653 | ParentRegion == OMPD_critical || | ||||
2654 | ParentRegion == OMPD_ordered; | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2655 | Recommend = ShouldBeInParallelRegion; |
2656 | } else if (CurrentRegion == OMPD_ordered) { | ||||
2657 | // OpenMP [2.16, Nesting of Regions] | ||||
2658 | // An ordered region may not be closely nested inside a critical, | ||||
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 2659 | // atomic, or explicit task region. |
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2660 | // An ordered region must be closely nested inside a loop region (or |
2661 | // parallel loop region) with an ordered clause. | ||||
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 2662 | // OpenMP [2.8.1,simd Construct, Restrictions] |
2663 | // An ordered construct with the simd clause is the only OpenMP construct | ||||
2664 | // that can appear in the simd region. | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2665 | NestingProhibited = ParentRegion == OMPD_critical || |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 2666 | isOpenMPTaskingDirective(ParentRegion) || |
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 2667 | !(isOpenMPSimdDirective(ParentRegion) || |
2668 | Stack->isParentOrderedRegion()); | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2669 | Recommend = ShouldBeInOrderedRegion; |
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 2670 | } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { |
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 2671 | // OpenMP [2.16, Nesting of Regions] |
2672 | // If specified, a teams construct must be contained within a target | ||||
2673 | // construct. | ||||
2674 | NestingProhibited = ParentRegion != OMPD_target; | ||||
Kelvin Li | 2b51f72 | 2016-07-26 04:32:50 +0000 | [diff] [blame] | 2675 | OrphanSeen = ParentRegion == OMPD_unknown; |
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 2676 | Recommend = ShouldBeInTargetRegion; |
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 2677 | } |
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 2678 | if (!NestingProhibited && |
2679 | !isOpenMPTargetExecutionDirective(CurrentRegion) && | ||||
2680 | !isOpenMPTargetDataManagementDirective(CurrentRegion) && | ||||
2681 | (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 2682 | // OpenMP [2.16, Nesting of Regions] |
2683 | // distribute, parallel, parallel sections, parallel workshare, and the | ||||
2684 | // parallel loop and parallel loop SIMD constructs are the only OpenMP | ||||
2685 | // constructs that can be closely nested in the teams region. | ||||
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 2686 | NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && |
2687 | !isOpenMPDistributeDirective(CurrentRegion); | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 2688 | Recommend = ShouldBeInParallelRegion; |
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2689 | } |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 2690 | if (!NestingProhibited && |
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 2691 | isOpenMPNestingDistributeDirective(CurrentRegion)) { |
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 2692 | // OpenMP 4.5 [2.17 Nesting of Regions] |
2693 | // The region associated with the distribute construct must be strictly | ||||
2694 | // nested inside a teams region | ||||
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 2695 | NestingProhibited = |
2696 | (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); | ||||
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 2697 | Recommend = ShouldBeInTeamsRegion; |
2698 | } | ||||
Arpith Chacko Jacob | 3d58f26 | 2016-02-02 04:00:47 +0000 | [diff] [blame] | 2699 | if (!NestingProhibited && |
2700 | (isOpenMPTargetExecutionDirective(CurrentRegion) || | ||||
2701 | isOpenMPTargetDataManagementDirective(CurrentRegion))) { | ||||
2702 | // OpenMP 4.5 [2.17 Nesting of Regions] | ||||
2703 | // If a target, target update, target data, target enter data, or | ||||
2704 | // target exit data construct is encountered during execution of a | ||||
2705 | // target region, the behavior is unspecified. | ||||
2706 | NestingProhibited = Stack->hasDirective( | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 2707 | [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, |
2708 | SourceLocation) -> bool { | ||||
Arpith Chacko Jacob | 3d58f26 | 2016-02-02 04:00:47 +0000 | [diff] [blame] | 2709 | if (isOpenMPTargetExecutionDirective(K)) { |
2710 | OffendingRegion = K; | ||||
2711 | return true; | ||||
2712 | } else | ||||
2713 | return false; | ||||
2714 | }, | ||||
2715 | false /* don't skip top directive */); | ||||
2716 | CloseNesting = false; | ||||
2717 | } | ||||
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2718 | if (NestingProhibited) { |
Kelvin Li | 2b51f72 | 2016-07-26 04:32:50 +0000 | [diff] [blame] | 2719 | if (OrphanSeen) { |
2720 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) | ||||
2721 | << getOpenMPDirectiveName(CurrentRegion) << Recommend; | ||||
2722 | } else { | ||||
2723 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) | ||||
2724 | << CloseNesting << getOpenMPDirectiveName(OffendingRegion) | ||||
2725 | << Recommend << getOpenMPDirectiveName(CurrentRegion); | ||||
2726 | } | ||||
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2727 | return true; |
2728 | } | ||||
2729 | } | ||||
2730 | return false; | ||||
2731 | } | ||||
2732 | |||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2733 | static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, |
2734 | ArrayRef<OMPClause *> Clauses, | ||||
2735 | ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { | ||||
2736 | bool ErrorFound = false; | ||||
2737 | unsigned NamedModifiersNumber = 0; | ||||
2738 | SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( | ||||
2739 | OMPD_unknown + 1); | ||||
Alexey Bataev | ecb156a | 2015-09-15 17:23:56 +0000 | [diff] [blame] | 2740 | SmallVector<SourceLocation, 4> NameModifierLoc; |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2741 | for (const auto *C : Clauses) { |
2742 | if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { | ||||
2743 | // At most one if clause without a directive-name-modifier can appear on | ||||
2744 | // the directive. | ||||
2745 | OpenMPDirectiveKind CurNM = IC->getNameModifier(); | ||||
2746 | if (FoundNameModifiers[CurNM]) { | ||||
2747 | S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) | ||||
2748 | << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) | ||||
2749 | << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); | ||||
2750 | ErrorFound = true; | ||||
Alexey Bataev | ecb156a | 2015-09-15 17:23:56 +0000 | [diff] [blame] | 2751 | } else if (CurNM != OMPD_unknown) { |
2752 | NameModifierLoc.push_back(IC->getNameModifierLoc()); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2753 | ++NamedModifiersNumber; |
Alexey Bataev | ecb156a | 2015-09-15 17:23:56 +0000 | [diff] [blame] | 2754 | } |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2755 | FoundNameModifiers[CurNM] = IC; |
2756 | if (CurNM == OMPD_unknown) | ||||
2757 | continue; | ||||
2758 | // Check if the specified name modifier is allowed for the current | ||||
2759 | // directive. | ||||
2760 | // At most one if clause with the particular directive-name-modifier can | ||||
2761 | // appear on the directive. | ||||
2762 | bool MatchFound = false; | ||||
2763 | for (auto NM : AllowedNameModifiers) { | ||||
2764 | if (CurNM == NM) { | ||||
2765 | MatchFound = true; | ||||
2766 | break; | ||||
2767 | } | ||||
2768 | } | ||||
2769 | if (!MatchFound) { | ||||
2770 | S.Diag(IC->getNameModifierLoc(), | ||||
2771 | diag::err_omp_wrong_if_directive_name_modifier) | ||||
2772 | << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); | ||||
2773 | ErrorFound = true; | ||||
2774 | } | ||||
2775 | } | ||||
2776 | } | ||||
2777 | // If any if clause on the directive includes a directive-name-modifier then | ||||
2778 | // all if clauses on the directive must include a directive-name-modifier. | ||||
2779 | if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { | ||||
2780 | if (NamedModifiersNumber == AllowedNameModifiers.size()) { | ||||
2781 | S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), | ||||
2782 | diag::err_omp_no_more_if_clause); | ||||
2783 | } else { | ||||
2784 | std::string Values; | ||||
2785 | std::string Sep(", "); | ||||
2786 | unsigned AllowedCnt = 0; | ||||
2787 | unsigned TotalAllowedNum = | ||||
2788 | AllowedNameModifiers.size() - NamedModifiersNumber; | ||||
2789 | for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; | ||||
2790 | ++Cnt) { | ||||
2791 | OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; | ||||
2792 | if (!FoundNameModifiers[NM]) { | ||||
2793 | Values += "'"; | ||||
2794 | Values += getOpenMPDirectiveName(NM); | ||||
2795 | Values += "'"; | ||||
2796 | if (AllowedCnt + 2 == TotalAllowedNum) | ||||
2797 | Values += " or "; | ||||
2798 | else if (AllowedCnt + 1 != TotalAllowedNum) | ||||
2799 | Values += Sep; | ||||
2800 | ++AllowedCnt; | ||||
2801 | } | ||||
2802 | } | ||||
2803 | S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), | ||||
2804 | diag::err_omp_unnamed_if_clause) | ||||
2805 | << (TotalAllowedNum > 1) << Values; | ||||
2806 | } | ||||
Alexey Bataev | ecb156a | 2015-09-15 17:23:56 +0000 | [diff] [blame] | 2807 | for (auto Loc : NameModifierLoc) { |
2808 | S.Diag(Loc, diag::note_omp_previous_named_if_clause); | ||||
2809 | } | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2810 | ErrorFound = true; |
2811 | } | ||||
2812 | return ErrorFound; | ||||
2813 | } | ||||
2814 | |||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2815 | StmtResult Sema::ActOnOpenMPExecutableDirective( |
2816 | OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, | ||||
2817 | OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, | ||||
2818 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 2819 | StmtResult Res = StmtError(); |
Jonas Hahnfeld | 64a9e3c | 2017-02-22 06:49:10 +0000 | [diff] [blame] | 2820 | // First check CancelRegion which is then used in checkNestingOfRegions. |
2821 | if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || | ||||
2822 | checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 2823 | StartLoc)) |
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 2824 | return StmtError(); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2825 | |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 2826 | llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 2827 | llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 2828 | bool ErrorFound = false; |
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 2829 | ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); |
Alexey Bataev | 0dce2ea | 2017-09-21 14:06:59 +0000 | [diff] [blame] | 2830 | if (AStmt && !CurContext->isDependentContext()) { |
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 2831 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); |
2832 | |||||
2833 | // Check default data sharing attributes for referenced variables. | ||||
2834 | DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); | ||||
Arpith Chacko Jacob | 1f46b70 | 2017-01-23 15:38:49 +0000 | [diff] [blame] | 2835 | int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); |
2836 | Stmt *S = AStmt; | ||||
2837 | while (--ThisCaptureLevel >= 0) | ||||
2838 | S = cast<CapturedStmt>(S)->getCapturedStmt(); | ||||
2839 | DSAChecker.Visit(S); | ||||
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 2840 | if (DSAChecker.isErrorFound()) |
2841 | return StmtError(); | ||||
2842 | // Generate list of implicitly defined firstprivate variables. | ||||
2843 | VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); | ||||
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 2844 | |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 2845 | SmallVector<Expr *, 4> ImplicitFirstprivates( |
2846 | DSAChecker.getImplicitFirstprivate().begin(), | ||||
2847 | DSAChecker.getImplicitFirstprivate().end()); | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2848 | SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), |
2849 | DSAChecker.getImplicitMap().end()); | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 2850 | // Mark taskgroup task_reduction descriptors as implicitly firstprivate. |
2851 | for (auto *C : Clauses) { | ||||
2852 | if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { | ||||
2853 | for (auto *E : IRC->taskgroup_descriptors()) | ||||
2854 | if (E) | ||||
2855 | ImplicitFirstprivates.emplace_back(E); | ||||
2856 | } | ||||
2857 | } | ||||
2858 | if (!ImplicitFirstprivates.empty()) { | ||||
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 2859 | if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 2860 | ImplicitFirstprivates, SourceLocation(), SourceLocation(), |
2861 | SourceLocation())) { | ||||
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 2862 | ClausesWithImplicit.push_back(Implicit); |
2863 | ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 2864 | ImplicitFirstprivates.size(); |
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 2865 | } else |
2866 | ErrorFound = true; | ||||
2867 | } | ||||
Alexey Bataev | f47c4b4 | 2017-09-26 13:47:31 +0000 | [diff] [blame] | 2868 | if (!ImplicitMaps.empty()) { |
2869 | if (OMPClause *Implicit = ActOnOpenMPMapClause( | ||||
2870 | OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, | ||||
2871 | SourceLocation(), SourceLocation(), ImplicitMaps, | ||||
2872 | SourceLocation(), SourceLocation(), SourceLocation())) { | ||||
2873 | ClausesWithImplicit.emplace_back(Implicit); | ||||
2874 | ErrorFound |= | ||||
2875 | cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); | ||||
2876 | } else | ||||
2877 | ErrorFound = true; | ||||
2878 | } | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 2879 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 2880 | |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2881 | llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 2882 | switch (Kind) { |
2883 | case OMPD_parallel: | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 2884 | Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, |
2885 | EndLoc); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2886 | AllowedNameModifiers.push_back(OMPD_parallel); |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 2887 | break; |
Alexey Bataev | 1b59ab5 | 2014-02-27 08:29:12 +0000 | [diff] [blame] | 2888 | case OMPD_simd: |
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 2889 | Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, |
2890 | VarsWithInheritedDSA); | ||||
Alexey Bataev | 1b59ab5 | 2014-02-27 08:29:12 +0000 | [diff] [blame] | 2891 | break; |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 2892 | case OMPD_for: |
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 2893 | Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, |
2894 | VarsWithInheritedDSA); | ||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 2895 | break; |
Alexander Musman | f82886e | 2014-09-18 05:12:34 +0000 | [diff] [blame] | 2896 | case OMPD_for_simd: |
2897 | Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
2898 | EndLoc, VarsWithInheritedDSA); | ||||
2899 | break; | ||||
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 2900 | case OMPD_sections: |
2901 | Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
2902 | EndLoc); | ||||
2903 | break; | ||||
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 2904 | case OMPD_section: |
2905 | assert(ClausesWithImplicit.empty() && | ||||
Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 2906 | "No clauses are allowed for 'omp section' directive"); |
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 2907 | Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); |
2908 | break; | ||||
Alexey Bataev | d1e40fb | 2014-06-26 12:05:45 +0000 | [diff] [blame] | 2909 | case OMPD_single: |
2910 | Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
2911 | EndLoc); | ||||
2912 | break; | ||||
Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 2913 | case OMPD_master: |
2914 | assert(ClausesWithImplicit.empty() && | ||||
2915 | "No clauses are allowed for 'omp master' directive"); | ||||
2916 | Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); | ||||
2917 | break; | ||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 2918 | case OMPD_critical: |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 2919 | Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, |
2920 | StartLoc, EndLoc); | ||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 2921 | break; |
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 2922 | case OMPD_parallel_for: |
2923 | Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
2924 | EndLoc, VarsWithInheritedDSA); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2925 | AllowedNameModifiers.push_back(OMPD_parallel); |
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 2926 | break; |
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 2927 | case OMPD_parallel_for_simd: |
2928 | Res = ActOnOpenMPParallelForSimdDirective( | ||||
2929 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2930 | AllowedNameModifiers.push_back(OMPD_parallel); |
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 2931 | break; |
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 2932 | case OMPD_parallel_sections: |
2933 | Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, | ||||
2934 | StartLoc, EndLoc); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2935 | AllowedNameModifiers.push_back(OMPD_parallel); |
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 2936 | break; |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 2937 | case OMPD_task: |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2938 | Res = |
2939 | ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2940 | AllowedNameModifiers.push_back(OMPD_task); |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 2941 | break; |
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 2942 | case OMPD_taskyield: |
2943 | assert(ClausesWithImplicit.empty() && | ||||
2944 | "No clauses are allowed for 'omp taskyield' directive"); | ||||
2945 | assert(AStmt == nullptr && | ||||
2946 | "No associated statement allowed for 'omp taskyield' directive"); | ||||
2947 | Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); | ||||
2948 | break; | ||||
Alexey Bataev | 4d1dfea | 2014-07-18 09:11:51 +0000 | [diff] [blame] | 2949 | case OMPD_barrier: |
2950 | assert(ClausesWithImplicit.empty() && | ||||
2951 | "No clauses are allowed for 'omp barrier' directive"); | ||||
2952 | assert(AStmt == nullptr && | ||||
2953 | "No associated statement allowed for 'omp barrier' directive"); | ||||
2954 | Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); | ||||
2955 | break; | ||||
Alexey Bataev | 2df347a | 2014-07-18 10:17:07 +0000 | [diff] [blame] | 2956 | case OMPD_taskwait: |
2957 | assert(ClausesWithImplicit.empty() && | ||||
2958 | "No clauses are allowed for 'omp taskwait' directive"); | ||||
2959 | assert(AStmt == nullptr && | ||||
2960 | "No associated statement allowed for 'omp taskwait' directive"); | ||||
2961 | Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); | ||||
2962 | break; | ||||
Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 2963 | case OMPD_taskgroup: |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 2964 | Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, |
2965 | EndLoc); | ||||
Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 2966 | break; |
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 2967 | case OMPD_flush: |
2968 | assert(AStmt == nullptr && | ||||
2969 | "No associated statement allowed for 'omp flush' directive"); | ||||
2970 | Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); | ||||
2971 | break; | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2972 | case OMPD_ordered: |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 2973 | Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, |
2974 | EndLoc); | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 2975 | break; |
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 2976 | case OMPD_atomic: |
2977 | Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
2978 | EndLoc); | ||||
2979 | break; | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 2980 | case OMPD_teams: |
2981 | Res = | ||||
2982 | ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | ||||
2983 | break; | ||||
Alexey Bataev | 0bd520b | 2014-09-19 08:19:49 +0000 | [diff] [blame] | 2984 | case OMPD_target: |
2985 | Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
2986 | EndLoc); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 2987 | AllowedNameModifiers.push_back(OMPD_target); |
Alexey Bataev | 0bd520b | 2014-09-19 08:19:49 +0000 | [diff] [blame] | 2988 | break; |
Arpith Chacko Jacob | e955b3d | 2016-01-26 18:48:41 +0000 | [diff] [blame] | 2989 | case OMPD_target_parallel: |
2990 | Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, | ||||
2991 | StartLoc, EndLoc); | ||||
2992 | AllowedNameModifiers.push_back(OMPD_target); | ||||
2993 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
2994 | break; | ||||
Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 2995 | case OMPD_target_parallel_for: |
2996 | Res = ActOnOpenMPTargetParallelForDirective( | ||||
2997 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
2998 | AllowedNameModifiers.push_back(OMPD_target); | ||||
2999 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3000 | break; | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 3001 | case OMPD_cancellation_point: |
3002 | assert(ClausesWithImplicit.empty() && | ||||
3003 | "No clauses are allowed for 'omp cancellation point' directive"); | ||||
3004 | assert(AStmt == nullptr && "No associated statement allowed for 'omp " | ||||
3005 | "cancellation point' directive"); | ||||
3006 | Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); | ||||
3007 | break; | ||||
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 3008 | case OMPD_cancel: |
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 3009 | assert(AStmt == nullptr && |
3010 | "No associated statement allowed for 'omp cancel' directive"); | ||||
Alexey Bataev | 87933c7 | 2015-09-18 08:07:34 +0000 | [diff] [blame] | 3011 | Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, |
3012 | CancelRegion); | ||||
3013 | AllowedNameModifiers.push_back(OMPD_cancel); | ||||
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 3014 | break; |
Michael Wong | 65f367f | 2015-07-21 13:44:28 +0000 | [diff] [blame] | 3015 | case OMPD_target_data: |
3016 | Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
3017 | EndLoc); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 3018 | AllowedNameModifiers.push_back(OMPD_target_data); |
Michael Wong | 65f367f | 2015-07-21 13:44:28 +0000 | [diff] [blame] | 3019 | break; |
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 3020 | case OMPD_target_enter_data: |
3021 | Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, | ||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 3022 | EndLoc, AStmt); |
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 3023 | AllowedNameModifiers.push_back(OMPD_target_enter_data); |
3024 | break; | ||||
Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 3025 | case OMPD_target_exit_data: |
3026 | Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, | ||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 3027 | EndLoc, AStmt); |
Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 3028 | AllowedNameModifiers.push_back(OMPD_target_exit_data); |
3029 | break; | ||||
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 3030 | case OMPD_taskloop: |
3031 | Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
3032 | EndLoc, VarsWithInheritedDSA); | ||||
3033 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||
3034 | break; | ||||
Alexey Bataev | 0a6ed84 | 2015-12-03 09:40:15 +0000 | [diff] [blame] | 3035 | case OMPD_taskloop_simd: |
3036 | Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
3037 | EndLoc, VarsWithInheritedDSA); | ||||
3038 | AllowedNameModifiers.push_back(OMPD_taskloop); | ||||
3039 | break; | ||||
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 3040 | case OMPD_distribute: |
3041 | Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
3042 | EndLoc, VarsWithInheritedDSA); | ||||
3043 | break; | ||||
Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 3044 | case OMPD_target_update: |
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 3045 | Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, |
3046 | EndLoc, AStmt); | ||||
Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 3047 | AllowedNameModifiers.push_back(OMPD_target_update); |
3048 | break; | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 3049 | case OMPD_distribute_parallel_for: |
3050 | Res = ActOnOpenMPDistributeParallelForDirective( | ||||
3051 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3052 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3053 | break; | ||||
Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 3054 | case OMPD_distribute_parallel_for_simd: |
3055 | Res = ActOnOpenMPDistributeParallelForSimdDirective( | ||||
3056 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3057 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3058 | break; | ||||
Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 3059 | case OMPD_distribute_simd: |
3060 | Res = ActOnOpenMPDistributeSimdDirective( | ||||
3061 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3062 | break; | ||||
Kelvin Li | a579b91 | 2016-07-14 02:54:56 +0000 | [diff] [blame] | 3063 | case OMPD_target_parallel_for_simd: |
3064 | Res = ActOnOpenMPTargetParallelForSimdDirective( | ||||
3065 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3066 | AllowedNameModifiers.push_back(OMPD_target); | ||||
3067 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3068 | break; | ||||
Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 3069 | case OMPD_target_simd: |
3070 | Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
3071 | EndLoc, VarsWithInheritedDSA); | ||||
3072 | AllowedNameModifiers.push_back(OMPD_target); | ||||
3073 | break; | ||||
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 3074 | case OMPD_teams_distribute: |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3075 | Res = ActOnOpenMPTeamsDistributeDirective( |
3076 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 3077 | break; |
Kelvin Li | 4e325f7 | 2016-10-25 12:50:55 +0000 | [diff] [blame] | 3078 | case OMPD_teams_distribute_simd: |
3079 | Res = ActOnOpenMPTeamsDistributeSimdDirective( | ||||
3080 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3081 | break; | ||||
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 3082 | case OMPD_teams_distribute_parallel_for_simd: |
3083 | Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( | ||||
3084 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3085 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3086 | break; | ||||
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 3087 | case OMPD_teams_distribute_parallel_for: |
3088 | Res = ActOnOpenMPTeamsDistributeParallelForDirective( | ||||
3089 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3090 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3091 | break; | ||||
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 3092 | case OMPD_target_teams: |
3093 | Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, | ||||
3094 | EndLoc); | ||||
3095 | AllowedNameModifiers.push_back(OMPD_target); | ||||
3096 | break; | ||||
Kelvin Li | 83c451e | 2016-12-25 04:52:54 +0000 | [diff] [blame] | 3097 | case OMPD_target_teams_distribute: |
3098 | Res = ActOnOpenMPTargetTeamsDistributeDirective( | ||||
3099 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3100 | AllowedNameModifiers.push_back(OMPD_target); | ||||
3101 | break; | ||||
Kelvin Li | 80e8f56 | 2016-12-29 22:16:30 +0000 | [diff] [blame] | 3102 | case OMPD_target_teams_distribute_parallel_for: |
3103 | Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( | ||||
3104 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3105 | AllowedNameModifiers.push_back(OMPD_target); | ||||
3106 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3107 | break; | ||||
Kelvin Li | 1851df5 | 2017-01-03 05:23:48 +0000 | [diff] [blame] | 3108 | case OMPD_target_teams_distribute_parallel_for_simd: |
3109 | Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( | ||||
3110 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3111 | AllowedNameModifiers.push_back(OMPD_target); | ||||
3112 | AllowedNameModifiers.push_back(OMPD_parallel); | ||||
3113 | break; | ||||
Kelvin Li | da68118 | 2017-01-10 18:08:18 +0000 | [diff] [blame] | 3114 | case OMPD_target_teams_distribute_simd: |
3115 | Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( | ||||
3116 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | ||||
3117 | AllowedNameModifiers.push_back(OMPD_target); | ||||
3118 | break; | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 3119 | case OMPD_declare_target: |
3120 | case OMPD_end_declare_target: | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 3121 | case OMPD_threadprivate: |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 3122 | case OMPD_declare_reduction: |
Alexey Bataev | 587e1de | 2016-03-30 10:43:55 +0000 | [diff] [blame] | 3123 | case OMPD_declare_simd: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 3124 | llvm_unreachable("OpenMP Directive is not allowed"); |
3125 | case OMPD_unknown: | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 3126 | llvm_unreachable("Unknown OpenMP directive"); |
3127 | } | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 3128 | |
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 3129 | for (auto P : VarsWithInheritedDSA) { |
3130 | Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) | ||||
3131 | << P.first << P.second->getSourceRange(); | ||||
3132 | } | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 3133 | ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; |
3134 | |||||
3135 | if (!AllowedNameModifiers.empty()) | ||||
3136 | ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || | ||||
3137 | ErrorFound; | ||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 3138 | |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 3139 | if (ErrorFound) |
3140 | return StmtError(); | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 3141 | return Res; |
3142 | } | ||||
3143 | |||||
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3144 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( |
3145 | DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, | ||||
Alexey Bataev | d93d376 | 2016-04-12 09:35:56 +0000 | [diff] [blame] | 3146 | ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, |
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3147 | ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, |
3148 | ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { | ||||
Alexey Bataev | d93d376 | 2016-04-12 09:35:56 +0000 | [diff] [blame] | 3149 | assert(Aligneds.size() == Alignments.size()); |
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3150 | assert(Linears.size() == LinModifiers.size()); |
3151 | assert(Linears.size() == Steps.size()); | ||||
Alexey Bataev | 587e1de | 2016-03-30 10:43:55 +0000 | [diff] [blame] | 3152 | if (!DG || DG.get().isNull()) |
3153 | return DeclGroupPtrTy(); | ||||
3154 | |||||
3155 | if (!DG.get().isSingleDecl()) { | ||||
Alexey Bataev | 20dfd77 | 2016-04-04 10:12:15 +0000 | [diff] [blame] | 3156 | Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); |
Alexey Bataev | 587e1de | 2016-03-30 10:43:55 +0000 | [diff] [blame] | 3157 | return DG; |
3158 | } | ||||
3159 | auto *ADecl = DG.get().getSingleDecl(); | ||||
3160 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) | ||||
3161 | ADecl = FTD->getTemplatedDecl(); | ||||
3162 | |||||
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3163 | auto *FD = dyn_cast<FunctionDecl>(ADecl); |
3164 | if (!FD) { | ||||
3165 | Diag(ADecl->getLocation(), diag::err_omp_function_expected); | ||||
Alexey Bataev | 587e1de | 2016-03-30 10:43:55 +0000 | [diff] [blame] | 3166 | return DeclGroupPtrTy(); |
3167 | } | ||||
3168 | |||||
Alexey Bataev | 2af33e3 | 2016-04-07 12:45:37 +0000 | [diff] [blame] | 3169 | // OpenMP [2.8.2, declare simd construct, Description] |
3170 | // The parameter of the simdlen clause must be a constant positive integer | ||||
3171 | // expression. | ||||
3172 | ExprResult SL; | ||||
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3173 | if (Simdlen) |
Alexey Bataev | 2af33e3 | 2016-04-07 12:45:37 +0000 | [diff] [blame] | 3174 | SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); |
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3175 | // OpenMP [2.8.2, declare simd construct, Description] |
3176 | // The special this pointer can be used as if was one of the arguments to the | ||||
3177 | // function in any of the linear, aligned, or uniform clauses. | ||||
3178 | // The uniform clause declares one or more arguments to have an invariant | ||||
3179 | // value for all concurrent invocations of the function in the execution of a | ||||
3180 | // single SIMD loop. | ||||
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3181 | llvm::DenseMap<Decl *, Expr *> UniformedArgs; |
3182 | Expr *UniformedLinearThis = nullptr; | ||||
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3183 | for (auto *E : Uniforms) { |
3184 | E = E->IgnoreParenImpCasts(); | ||||
3185 | if (auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||
3186 | if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) | ||||
3187 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||
3188 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3189 | ->getCanonicalDecl() == PVD->getCanonicalDecl()) { |
3190 | UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); | ||||
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3191 | continue; |
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3192 | } |
3193 | if (isa<CXXThisExpr>(E)) { | ||||
3194 | UniformedLinearThis = E; | ||||
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3195 | continue; |
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3196 | } |
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3197 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) |
3198 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||
Alexey Bataev | 2af33e3 | 2016-04-07 12:45:37 +0000 | [diff] [blame] | 3199 | } |
Alexey Bataev | d93d376 | 2016-04-12 09:35:56 +0000 | [diff] [blame] | 3200 | // OpenMP [2.8.2, declare simd construct, Description] |
3201 | // The aligned clause declares that the object to which each list item points | ||||
3202 | // is aligned to the number of bytes expressed in the optional parameter of | ||||
3203 | // the aligned clause. | ||||
3204 | // The special this pointer can be used as if was one of the arguments to the | ||||
3205 | // function in any of the linear, aligned, or uniform clauses. | ||||
3206 | // The type of list items appearing in the aligned clause must be array, | ||||
3207 | // pointer, reference to array, or reference to pointer. | ||||
3208 | llvm::DenseMap<Decl *, Expr *> AlignedArgs; | ||||
3209 | Expr *AlignedThis = nullptr; | ||||
3210 | for (auto *E : Aligneds) { | ||||
3211 | E = E->IgnoreParenImpCasts(); | ||||
3212 | if (auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||
3213 | if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||
3214 | auto *CanonPVD = PVD->getCanonicalDecl(); | ||||
3215 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||
3216 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||
3217 | ->getCanonicalDecl() == CanonPVD) { | ||||
3218 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||
3219 | // A list-item cannot appear in more than one aligned clause. | ||||
3220 | if (AlignedArgs.count(CanonPVD) > 0) { | ||||
3221 | Diag(E->getExprLoc(), diag::err_omp_aligned_twice) | ||||
3222 | << 1 << E->getSourceRange(); | ||||
3223 | Diag(AlignedArgs[CanonPVD]->getExprLoc(), | ||||
3224 | diag::note_omp_explicit_dsa) | ||||
3225 | << getOpenMPClauseName(OMPC_aligned); | ||||
3226 | continue; | ||||
3227 | } | ||||
3228 | AlignedArgs[CanonPVD] = E; | ||||
3229 | QualType QTy = PVD->getType() | ||||
3230 | .getNonReferenceType() | ||||
3231 | .getUnqualifiedType() | ||||
3232 | .getCanonicalType(); | ||||
3233 | const Type *Ty = QTy.getTypePtrOrNull(); | ||||
3234 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { | ||||
3235 | Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) | ||||
3236 | << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); | ||||
3237 | Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; | ||||
3238 | } | ||||
3239 | continue; | ||||
3240 | } | ||||
3241 | } | ||||
3242 | if (isa<CXXThisExpr>(E)) { | ||||
3243 | if (AlignedThis) { | ||||
3244 | Diag(E->getExprLoc(), diag::err_omp_aligned_twice) | ||||
3245 | << 2 << E->getSourceRange(); | ||||
3246 | Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) | ||||
3247 | << getOpenMPClauseName(OMPC_aligned); | ||||
3248 | } | ||||
3249 | AlignedThis = E; | ||||
3250 | continue; | ||||
3251 | } | ||||
3252 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||
3253 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||
3254 | } | ||||
3255 | // The optional parameter of the aligned clause, alignment, must be a constant | ||||
3256 | // positive integer expression. If no optional parameter is specified, | ||||
3257 | // implementation-defined default alignments for SIMD instructions on the | ||||
3258 | // target platforms are assumed. | ||||
3259 | SmallVector<Expr *, 4> NewAligns; | ||||
3260 | for (auto *E : Alignments) { | ||||
3261 | ExprResult Align; | ||||
3262 | if (E) | ||||
3263 | Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); | ||||
3264 | NewAligns.push_back(Align.get()); | ||||
3265 | } | ||||
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3266 | // OpenMP [2.8.2, declare simd construct, Description] |
3267 | // The linear clause declares one or more list items to be private to a SIMD | ||||
3268 | // lane and to have a linear relationship with respect to the iteration space | ||||
3269 | // of a loop. | ||||
3270 | // The special this pointer can be used as if was one of the arguments to the | ||||
3271 | // function in any of the linear, aligned, or uniform clauses. | ||||
3272 | // When a linear-step expression is specified in a linear clause it must be | ||||
3273 | // either a constant integer expression or an integer-typed parameter that is | ||||
3274 | // specified in a uniform clause on the directive. | ||||
3275 | llvm::DenseMap<Decl *, Expr *> LinearArgs; | ||||
3276 | const bool IsUniformedThis = UniformedLinearThis != nullptr; | ||||
3277 | auto MI = LinModifiers.begin(); | ||||
3278 | for (auto *E : Linears) { | ||||
3279 | auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); | ||||
3280 | ++MI; | ||||
3281 | E = E->IgnoreParenImpCasts(); | ||||
3282 | if (auto *DRE = dyn_cast<DeclRefExpr>(E)) | ||||
3283 | if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||
3284 | auto *CanonPVD = PVD->getCanonicalDecl(); | ||||
3285 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && | ||||
3286 | FD->getParamDecl(PVD->getFunctionScopeIndex()) | ||||
3287 | ->getCanonicalDecl() == CanonPVD) { | ||||
3288 | // OpenMP [2.15.3.7, linear Clause, Restrictions] | ||||
3289 | // A list-item cannot appear in more than one linear clause. | ||||
3290 | if (LinearArgs.count(CanonPVD) > 0) { | ||||
3291 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||
3292 | << getOpenMPClauseName(OMPC_linear) | ||||
3293 | << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); | ||||
3294 | Diag(LinearArgs[CanonPVD]->getExprLoc(), | ||||
3295 | diag::note_omp_explicit_dsa) | ||||
3296 | << getOpenMPClauseName(OMPC_linear); | ||||
3297 | continue; | ||||
3298 | } | ||||
3299 | // Each argument can appear in at most one uniform or linear clause. | ||||
3300 | if (UniformedArgs.count(CanonPVD) > 0) { | ||||
3301 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||
3302 | << getOpenMPClauseName(OMPC_linear) | ||||
3303 | << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); | ||||
3304 | Diag(UniformedArgs[CanonPVD]->getExprLoc(), | ||||
3305 | diag::note_omp_explicit_dsa) | ||||
3306 | << getOpenMPClauseName(OMPC_uniform); | ||||
3307 | continue; | ||||
3308 | } | ||||
3309 | LinearArgs[CanonPVD] = E; | ||||
3310 | if (E->isValueDependent() || E->isTypeDependent() || | ||||
3311 | E->isInstantiationDependent() || | ||||
3312 | E->containsUnexpandedParameterPack()) | ||||
3313 | continue; | ||||
3314 | (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, | ||||
3315 | PVD->getOriginalType()); | ||||
3316 | continue; | ||||
3317 | } | ||||
3318 | } | ||||
3319 | if (isa<CXXThisExpr>(E)) { | ||||
3320 | if (UniformedLinearThis) { | ||||
3321 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) | ||||
3322 | << getOpenMPClauseName(OMPC_linear) | ||||
3323 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) | ||||
3324 | << E->getSourceRange(); | ||||
3325 | Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) | ||||
3326 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform | ||||
3327 | : OMPC_linear); | ||||
3328 | continue; | ||||
3329 | } | ||||
3330 | UniformedLinearThis = E; | ||||
3331 | if (E->isValueDependent() || E->isTypeDependent() || | ||||
3332 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) | ||||
3333 | continue; | ||||
3334 | (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, | ||||
3335 | E->getType()); | ||||
3336 | continue; | ||||
3337 | } | ||||
3338 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) | ||||
3339 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); | ||||
3340 | } | ||||
3341 | Expr *Step = nullptr; | ||||
3342 | Expr *NewStep = nullptr; | ||||
3343 | SmallVector<Expr *, 4> NewSteps; | ||||
3344 | for (auto *E : Steps) { | ||||
3345 | // Skip the same step expression, it was checked already. | ||||
3346 | if (Step == E || !E) { | ||||
3347 | NewSteps.push_back(E ? NewStep : nullptr); | ||||
3348 | continue; | ||||
3349 | } | ||||
3350 | Step = E; | ||||
3351 | if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) | ||||
3352 | if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||
3353 | auto *CanonPVD = PVD->getCanonicalDecl(); | ||||
3354 | if (UniformedArgs.count(CanonPVD) == 0) { | ||||
3355 | Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) | ||||
3356 | << Step->getSourceRange(); | ||||
3357 | } else if (E->isValueDependent() || E->isTypeDependent() || | ||||
3358 | E->isInstantiationDependent() || | ||||
3359 | E->containsUnexpandedParameterPack() || | ||||
3360 | CanonPVD->getType()->hasIntegerRepresentation()) | ||||
3361 | NewSteps.push_back(Step); | ||||
3362 | else { | ||||
3363 | Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) | ||||
3364 | << Step->getSourceRange(); | ||||
3365 | } | ||||
3366 | continue; | ||||
3367 | } | ||||
3368 | NewStep = Step; | ||||
3369 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && | ||||
3370 | !Step->isInstantiationDependent() && | ||||
3371 | !Step->containsUnexpandedParameterPack()) { | ||||
3372 | NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) | ||||
3373 | .get(); | ||||
3374 | if (NewStep) | ||||
3375 | NewStep = VerifyIntegerConstantExpression(NewStep).get(); | ||||
3376 | } | ||||
3377 | NewSteps.push_back(NewStep); | ||||
3378 | } | ||||
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 3379 | auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( |
3380 | Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), | ||||
Alexey Bataev | d93d376 | 2016-04-12 09:35:56 +0000 | [diff] [blame] | 3381 | Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), |
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 3382 | const_cast<Expr **>(NewAligns.data()), NewAligns.size(), |
3383 | const_cast<Expr **>(Linears.data()), Linears.size(), | ||||
3384 | const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), | ||||
3385 | NewSteps.data(), NewSteps.size(), SR); | ||||
Alexey Bataev | 587e1de | 2016-03-30 10:43:55 +0000 | [diff] [blame] | 3386 | ADecl->addAttr(NewAttr); |
3387 | return ConvertDeclToDeclGroup(ADecl); | ||||
3388 | } | ||||
3389 | |||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 3390 | StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, |
3391 | Stmt *AStmt, | ||||
3392 | SourceLocation StartLoc, | ||||
3393 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 3394 | if (!AStmt) |
3395 | return StmtError(); | ||||
3396 | |||||
Alexey Bataev | 9959db5 | 2014-05-06 10:08:46 +0000 | [diff] [blame] | 3397 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); |
3398 | // 1.2.2 OpenMP Language Terminology | ||||
3399 | // Structured block - An executable statement with a single entry at the | ||||
3400 | // top and a single exit at the bottom. | ||||
3401 | // The point of exit cannot be a branch out of the structured block. | ||||
3402 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
3403 | CS->getCapturedDecl()->setNothrow(); | ||||
3404 | |||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 3405 | getCurFunction()->setHasBranchProtectedScope(); |
3406 | |||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 3407 | return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
3408 | DSAStack->isCancelRegion()); | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 3409 | } |
3410 | |||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3411 | namespace { |
3412 | /// \brief Helper class for checking canonical form of the OpenMP loops and | ||||
3413 | /// extracting iteration space of each loop in the loop nest, that will be used | ||||
3414 | /// for IR generation. | ||||
3415 | class OpenMPIterationSpaceChecker { | ||||
3416 | /// \brief Reference to Sema. | ||||
3417 | Sema &SemaRef; | ||||
3418 | /// \brief A location for diagnostics (when there is no some better location). | ||||
3419 | SourceLocation DefaultLoc; | ||||
3420 | /// \brief A location for diagnostics (when increment is not compatible). | ||||
3421 | SourceLocation ConditionLoc; | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3422 | /// \brief A source location for referring to loop init later. |
3423 | SourceRange InitSrcRange; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3424 | /// \brief A source location for referring to condition later. |
3425 | SourceRange ConditionSrcRange; | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3426 | /// \brief A source location for referring to increment later. |
3427 | SourceRange IncrementSrcRange; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3428 | /// \brief Loop variable. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3429 | ValueDecl *LCDecl = nullptr; |
Alexey Bataev | caf09b0 | 2014-07-25 06:27:47 +0000 | [diff] [blame] | 3430 | /// \brief Reference to loop variable. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3431 | Expr *LCRef = nullptr; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3432 | /// \brief Lower bound (initializer for the var). |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3433 | Expr *LB = nullptr; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3434 | /// \brief Upper bound. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3435 | Expr *UB = nullptr; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3436 | /// \brief Loop step (increment). |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3437 | Expr *Step = nullptr; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3438 | /// \brief This flag is true when condition is one of: |
3439 | /// Var < UB | ||||
3440 | /// Var <= UB | ||||
3441 | /// UB > Var | ||||
3442 | /// UB >= Var | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3443 | bool TestIsLessOp = false; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3444 | /// \brief This flag is true when condition is strict ( < or > ). |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3445 | bool TestIsStrictOp = false; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3446 | /// \brief This flag is true when step is subtracted on each iteration. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3447 | bool SubtractStep = false; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3448 | |
3449 | public: | ||||
3450 | OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3451 | : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3452 | /// \brief Check init-expr for canonical loop form and save loop counter |
3453 | /// variable - #Var and its initialization value - #LB. | ||||
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 3454 | bool CheckInit(Stmt *S, bool EmitDiags = true); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3455 | /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags |
3456 | /// for less/greater and for strict/non-strict comparison. | ||||
3457 | bool CheckCond(Expr *S); | ||||
3458 | /// \brief Check incr-expr for canonical loop form and return true if it | ||||
3459 | /// does not conform, otherwise save loop step (#Step). | ||||
3460 | bool CheckInc(Expr *S); | ||||
3461 | /// \brief Return the loop counter variable. | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3462 | ValueDecl *GetLoopDecl() const { return LCDecl; } |
Alexey Bataev | caf09b0 | 2014-07-25 06:27:47 +0000 | [diff] [blame] | 3463 | /// \brief Return the reference expression to loop counter variable. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3464 | Expr *GetLoopDeclRefExpr() const { return LCRef; } |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3465 | /// \brief Source range of the loop init. |
3466 | SourceRange GetInitSrcRange() const { return InitSrcRange; } | ||||
3467 | /// \brief Source range of the loop condition. | ||||
3468 | SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } | ||||
3469 | /// \brief Source range of the loop increment. | ||||
3470 | SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } | ||||
3471 | /// \brief True if the step should be subtracted. | ||||
3472 | bool ShouldSubtractStep() const { return SubtractStep; } | ||||
3473 | /// \brief Build the expression to calculate the number of iterations. | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3474 | Expr * |
3475 | BuildNumIterations(Scope *S, const bool LimitedType, | ||||
3476 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; | ||||
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 3477 | /// \brief Build the precondition expression for the loops. |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3478 | Expr *BuildPreCond(Scope *S, Expr *Cond, |
3479 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3480 | /// \brief Build reference expression to the counter be used for codegen. |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 3481 | DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures, |
3482 | DSAStackTy &DSA) const; | ||||
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 3483 | /// \brief Build reference expression to the private counter be used for |
3484 | /// codegen. | ||||
3485 | Expr *BuildPrivateCounterVar() const; | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3486 | /// \brief Build initialization of the counter be used for codegen. |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3487 | Expr *BuildCounterInit() const; |
3488 | /// \brief Build step of the counter be used for codegen. | ||||
3489 | Expr *BuildCounterStep() const; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3490 | /// \brief Return true if any expression is dependent. |
3491 | bool Dependent() const; | ||||
3492 | |||||
3493 | private: | ||||
3494 | /// \brief Check the right-hand side of an assignment in the increment | ||||
3495 | /// expression. | ||||
3496 | bool CheckIncRHS(Expr *RHS); | ||||
3497 | /// \brief Helper to set loop counter variable and its initializer. | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3498 | bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3499 | /// \brief Helper to set upper bound. |
Craig Topper | e335f25 | 2015-10-04 04:53:55 +0000 | [diff] [blame] | 3500 | bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, |
Craig Topper | 9cd5e4f | 2015-09-21 01:23:32 +0000 | [diff] [blame] | 3501 | SourceLocation SL); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3502 | /// \brief Helper to set loop increment. |
3503 | bool SetStep(Expr *NewStep, bool Subtract); | ||||
3504 | }; | ||||
3505 | |||||
3506 | bool OpenMPIterationSpaceChecker::Dependent() const { | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3507 | if (!LCDecl) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3508 | assert(!LB && !UB && !Step); |
3509 | return false; | ||||
3510 | } | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3511 | return LCDecl->getType()->isDependentType() || |
3512 | (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || | ||||
3513 | (Step && Step->isValueDependent()); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3514 | } |
3515 | |||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3516 | bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, |
3517 | Expr *NewLCRefExpr, | ||||
3518 | Expr *NewLB) { | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3519 | // State consistency checking to ensure correct usage. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3520 | assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && |
Alexey Bataev | caf09b0 | 2014-07-25 06:27:47 +0000 | [diff] [blame] | 3521 | UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3522 | if (!NewLCDecl || !NewLB) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3523 | return true; |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3524 | LCDecl = getCanonicalDecl(NewLCDecl); |
3525 | LCRef = NewLCRefExpr; | ||||
Alexey Bataev | 3bed68c | 2015-07-15 12:14:07 +0000 | [diff] [blame] | 3526 | if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) |
3527 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) | ||||
Alexey Bataev | 0d08a7f | 2015-07-16 04:19:43 +0000 | [diff] [blame] | 3528 | if ((Ctor->isCopyOrMoveConstructor() || |
3529 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && | ||||
3530 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) | ||||
Alexey Bataev | 3bed68c | 2015-07-15 12:14:07 +0000 | [diff] [blame] | 3531 | NewLB = CE->getArg(0)->IgnoreParenImpCasts(); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3532 | LB = NewLB; |
3533 | return false; | ||||
3534 | } | ||||
3535 | |||||
3536 | bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, | ||||
Craig Topper | e335f25 | 2015-10-04 04:53:55 +0000 | [diff] [blame] | 3537 | SourceRange SR, SourceLocation SL) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3538 | // State consistency checking to ensure correct usage. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3539 | assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && |
3540 | Step == nullptr && !TestIsLessOp && !TestIsStrictOp); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3541 | if (!NewUB) |
3542 | return true; | ||||
3543 | UB = NewUB; | ||||
3544 | TestIsLessOp = LessOp; | ||||
3545 | TestIsStrictOp = StrictOp; | ||||
3546 | ConditionSrcRange = SR; | ||||
3547 | ConditionLoc = SL; | ||||
3548 | return false; | ||||
3549 | } | ||||
3550 | |||||
3551 | bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { | ||||
3552 | // State consistency checking to ensure correct usage. | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3553 | assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3554 | if (!NewStep) |
3555 | return true; | ||||
3556 | if (!NewStep->isValueDependent()) { | ||||
3557 | // Check that the step is integer expression. | ||||
3558 | SourceLocation StepLoc = NewStep->getLocStart(); | ||||
Alexey Bataev | 5372fb8 | 2017-08-31 23:06:52 +0000 | [diff] [blame] | 3559 | ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( |
3560 | StepLoc, getExprAsWritten(NewStep)); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3561 | if (Val.isInvalid()) |
3562 | return true; | ||||
3563 | NewStep = Val.get(); | ||||
3564 | |||||
3565 | // OpenMP [2.6, Canonical Loop Form, Restrictions] | ||||
3566 | // If test-expr is of form var relational-op b and relational-op is < or | ||||
3567 | // <= then incr-expr must cause var to increase on each iteration of the | ||||
3568 | // loop. If test-expr is of form var relational-op b and relational-op is | ||||
3569 | // > or >= then incr-expr must cause var to decrease on each iteration of | ||||
3570 | // the loop. | ||||
3571 | // If test-expr is of form b relational-op var and relational-op is < or | ||||
3572 | // <= then incr-expr must cause var to decrease on each iteration of the | ||||
3573 | // loop. If test-expr is of form b relational-op var and relational-op is | ||||
3574 | // > or >= then incr-expr must cause var to increase on each iteration of | ||||
3575 | // the loop. | ||||
3576 | llvm::APSInt Result; | ||||
3577 | bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); | ||||
3578 | bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); | ||||
3579 | bool IsConstNeg = | ||||
3580 | IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3581 | bool IsConstPos = |
3582 | IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3583 | bool IsConstZero = IsConstant && !Result.getBoolValue(); |
3584 | if (UB && (IsConstZero || | ||||
3585 | (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3586 | : (IsConstPos || (IsUnsigned && !Subtract))))) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3587 | SemaRef.Diag(NewStep->getExprLoc(), |
3588 | diag::err_omp_loop_incr_not_compatible) | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3589 | << LCDecl << TestIsLessOp << NewStep->getSourceRange(); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3590 | SemaRef.Diag(ConditionLoc, |
3591 | diag::note_omp_loop_cond_requres_compatible_incr) | ||||
3592 | << TestIsLessOp << ConditionSrcRange; | ||||
3593 | return true; | ||||
3594 | } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3595 | if (TestIsLessOp == Subtract) { |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3596 | NewStep = |
3597 | SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) | ||||
3598 | .get(); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3599 | Subtract = !Subtract; |
3600 | } | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3601 | } |
3602 | |||||
3603 | Step = NewStep; | ||||
3604 | SubtractStep = Subtract; | ||||
3605 | return false; | ||||
3606 | } | ||||
3607 | |||||
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 3608 | bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3609 | // Check init-expr for canonical loop form and save loop counter |
3610 | // variable - #Var and its initialization value - #LB. | ||||
3611 | // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: | ||||
3612 | // var = lb | ||||
3613 | // integer-type var = lb | ||||
3614 | // random-access-iterator-type var = lb | ||||
3615 | // pointer-type var = lb | ||||
3616 | // | ||||
3617 | if (!S) { | ||||
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 3618 | if (EmitDiags) { |
3619 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); | ||||
3620 | } | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3621 | return true; |
3622 | } | ||||
Tim Shen | 4a05bb8 | 2016-06-21 20:29:17 +0000 | [diff] [blame] | 3623 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) |
3624 | if (!ExprTemp->cleanupsHaveSideEffects()) | ||||
3625 | S = ExprTemp->getSubExpr(); | ||||
3626 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3627 | InitSrcRange = S->getSourceRange(); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3628 | if (Expr *E = dyn_cast<Expr>(S)) |
3629 | S = E->IgnoreParens(); | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3630 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3631 | if (BO->getOpcode() == BO_Assign) { |
3632 | auto *LHS = BO->getLHS()->IgnoreParens(); | ||||
3633 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { | ||||
3634 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) | ||||
3635 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||
3636 | return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); | ||||
3637 | return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); | ||||
3638 | } | ||||
3639 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { | ||||
3640 | if (ME->isArrow() && | ||||
3641 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||
3642 | return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); | ||||
3643 | } | ||||
3644 | } | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3645 | } else if (auto *DS = dyn_cast<DeclStmt>(S)) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3646 | if (DS->isSingleDecl()) { |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3647 | if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { |
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 3648 | if (Var->hasInit() && !Var->getType()->isReferenceType()) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3649 | // Accept non-canonical init form here but emit ext. warning. |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 3650 | if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3651 | SemaRef.Diag(S->getLocStart(), |
3652 | diag::ext_omp_loop_not_canonical_init) | ||||
3653 | << S->getSourceRange(); | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3654 | return SetLCDeclAndLB(Var, nullptr, Var->getInit()); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3655 | } |
3656 | } | ||||
3657 | } | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3658 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3659 | if (CE->getOperator() == OO_Equal) { |
3660 | auto *LHS = CE->getArg(0); | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3661 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3662 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) |
3663 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) | ||||
3664 | return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); | ||||
3665 | return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); | ||||
3666 | } | ||||
3667 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { | ||||
3668 | if (ME->isArrow() && | ||||
3669 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||
3670 | return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); | ||||
3671 | } | ||||
3672 | } | ||||
3673 | } | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3674 | |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3675 | if (Dependent() || SemaRef.CurContext->isDependentContext()) |
3676 | return false; | ||||
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 3677 | if (EmitDiags) { |
3678 | SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) | ||||
3679 | << S->getSourceRange(); | ||||
3680 | } | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3681 | return true; |
3682 | } | ||||
3683 | |||||
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 3684 | /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3685 | /// variable (which may be the loop variable) if possible. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3686 | static const ValueDecl *GetInitLCDecl(Expr *E) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3687 | if (!E) |
Craig Topper | 4b56692 | 2014-06-09 02:04:02 +0000 | [diff] [blame] | 3688 | return nullptr; |
Alexey Bataev | 3bed68c | 2015-07-15 12:14:07 +0000 | [diff] [blame] | 3689 | E = getExprAsWritten(E); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3690 | if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) |
3691 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) | ||||
Alexey Bataev | 0d08a7f | 2015-07-16 04:19:43 +0000 | [diff] [blame] | 3692 | if ((Ctor->isCopyOrMoveConstructor() || |
3693 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && | ||||
3694 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3695 | E = CE->getArg(0)->IgnoreParenImpCasts(); |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3696 | if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 3697 | if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3698 | return getCanonicalDecl(VD); |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3699 | } |
3700 | if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) | ||||
3701 | if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) | ||||
3702 | return getCanonicalDecl(ME->getMemberDecl()); | ||||
3703 | return nullptr; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3704 | } |
3705 | |||||
3706 | bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { | ||||
3707 | // Check test-expr for canonical form, save upper-bound UB, flags for | ||||
3708 | // less/greater and for strict/non-strict comparison. | ||||
3709 | // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: | ||||
3710 | // var relational-op b | ||||
3711 | // b relational-op var | ||||
3712 | // | ||||
3713 | if (!S) { | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3714 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3715 | return true; |
3716 | } | ||||
Alexey Bataev | 3bed68c | 2015-07-15 12:14:07 +0000 | [diff] [blame] | 3717 | S = getExprAsWritten(S); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3718 | SourceLocation CondLoc = S->getLocStart(); |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3719 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3720 | if (BO->isRelationalOp()) { |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3721 | if (GetInitLCDecl(BO->getLHS()) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3722 | return SetUB(BO->getRHS(), |
3723 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), | ||||
3724 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | ||||
3725 | BO->getSourceRange(), BO->getOperatorLoc()); | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3726 | if (GetInitLCDecl(BO->getRHS()) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3727 | return SetUB(BO->getLHS(), |
3728 | (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), | ||||
3729 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | ||||
3730 | BO->getSourceRange(), BO->getOperatorLoc()); | ||||
3731 | } | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3732 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3733 | if (CE->getNumArgs() == 2) { |
3734 | auto Op = CE->getOperator(); | ||||
3735 | switch (Op) { | ||||
3736 | case OO_Greater: | ||||
3737 | case OO_GreaterEqual: | ||||
3738 | case OO_Less: | ||||
3739 | case OO_LessEqual: | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3740 | if (GetInitLCDecl(CE->getArg(0)) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3741 | return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, |
3742 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | ||||
3743 | CE->getOperatorLoc()); | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3744 | if (GetInitLCDecl(CE->getArg(1)) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3745 | return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, |
3746 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | ||||
3747 | CE->getOperatorLoc()); | ||||
3748 | break; | ||||
3749 | default: | ||||
3750 | break; | ||||
3751 | } | ||||
3752 | } | ||||
3753 | } | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3754 | if (Dependent() || SemaRef.CurContext->isDependentContext()) |
3755 | return false; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3756 | SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3757 | << S->getSourceRange() << LCDecl; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3758 | return true; |
3759 | } | ||||
3760 | |||||
3761 | bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { | ||||
3762 | // RHS of canonical loop form increment can be: | ||||
3763 | // var + incr | ||||
3764 | // incr + var | ||||
3765 | // var - incr | ||||
3766 | // | ||||
3767 | RHS = RHS->IgnoreParenImpCasts(); | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3768 | if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3769 | if (BO->isAdditiveOp()) { |
3770 | bool IsAdd = BO->getOpcode() == BO_Add; | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3771 | if (GetInitLCDecl(BO->getLHS()) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3772 | return SetStep(BO->getRHS(), !IsAdd); |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3773 | if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3774 | return SetStep(BO->getLHS(), false); |
3775 | } | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3776 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3777 | bool IsAdd = CE->getOperator() == OO_Plus; |
3778 | if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3779 | if (GetInitLCDecl(CE->getArg(0)) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3780 | return SetStep(CE->getArg(1), !IsAdd); |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3781 | if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3782 | return SetStep(CE->getArg(0), false); |
3783 | } | ||||
3784 | } | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3785 | if (Dependent() || SemaRef.CurContext->isDependentContext()) |
3786 | return false; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3787 | SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3788 | << RHS->getSourceRange() << LCDecl; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3789 | return true; |
3790 | } | ||||
3791 | |||||
3792 | bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { | ||||
3793 | // Check incr-expr for canonical loop form and return true if it | ||||
3794 | // does not conform. | ||||
3795 | // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: | ||||
3796 | // ++var | ||||
3797 | // var++ | ||||
3798 | // --var | ||||
3799 | // var-- | ||||
3800 | // var += incr | ||||
3801 | // var -= incr | ||||
3802 | // var = var + incr | ||||
3803 | // var = incr + var | ||||
3804 | // var = var - incr | ||||
3805 | // | ||||
3806 | if (!S) { | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3807 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3808 | return true; |
3809 | } | ||||
Tim Shen | 4a05bb8 | 2016-06-21 20:29:17 +0000 | [diff] [blame] | 3810 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) |
3811 | if (!ExprTemp->cleanupsHaveSideEffects()) | ||||
3812 | S = ExprTemp->getSubExpr(); | ||||
3813 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3814 | IncrementSrcRange = S->getSourceRange(); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3815 | S = S->IgnoreParens(); |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3816 | if (auto *UO = dyn_cast<UnaryOperator>(S)) { |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3817 | if (UO->isIncrementDecrementOp() && |
3818 | GetInitLCDecl(UO->getSubExpr()) == LCDecl) | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3819 | return SetStep(SemaRef |
3820 | .ActOnIntegerConstant(UO->getLocStart(), | ||||
3821 | (UO->isDecrementOp() ? -1 : 1)) | ||||
3822 | .get(), | ||||
3823 | false); | ||||
3824 | } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3825 | switch (BO->getOpcode()) { |
3826 | case BO_AddAssign: | ||||
3827 | case BO_SubAssign: | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3828 | if (GetInitLCDecl(BO->getLHS()) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3829 | return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); |
3830 | break; | ||||
3831 | case BO_Assign: | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3832 | if (GetInitLCDecl(BO->getLHS()) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3833 | return CheckIncRHS(BO->getRHS()); |
3834 | break; | ||||
3835 | default: | ||||
3836 | break; | ||||
3837 | } | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3838 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3839 | switch (CE->getOperator()) { |
3840 | case OO_PlusPlus: | ||||
3841 | case OO_MinusMinus: | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3842 | if (GetInitLCDecl(CE->getArg(0)) == LCDecl) |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 3843 | return SetStep(SemaRef |
3844 | .ActOnIntegerConstant( | ||||
3845 | CE->getLocStart(), | ||||
3846 | ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) | ||||
3847 | .get(), | ||||
3848 | false); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3849 | break; |
3850 | case OO_PlusEqual: | ||||
3851 | case OO_MinusEqual: | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3852 | if (GetInitLCDecl(CE->getArg(0)) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3853 | return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); |
3854 | break; | ||||
3855 | case OO_Equal: | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3856 | if (GetInitLCDecl(CE->getArg(0)) == LCDecl) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3857 | return CheckIncRHS(CE->getArg(1)); |
3858 | break; | ||||
3859 | default: | ||||
3860 | break; | ||||
3861 | } | ||||
3862 | } | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3863 | if (Dependent() || SemaRef.CurContext->isDependentContext()) |
3864 | return false; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3865 | SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3866 | << S->getSourceRange() << LCDecl; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 3867 | return true; |
3868 | } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3869 | |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3870 | static ExprResult |
3871 | tryBuildCapture(Sema &SemaRef, Expr *Capture, | ||||
3872 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { | ||||
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 3873 | if (SemaRef.CurContext->isDependentContext()) |
3874 | return ExprResult(Capture); | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3875 | if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) |
3876 | return SemaRef.PerformImplicitConversion( | ||||
3877 | Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, | ||||
3878 | /*AllowExplicit=*/true); | ||||
3879 | auto I = Captures.find(Capture); | ||||
3880 | if (I != Captures.end()) | ||||
3881 | return buildCapture(SemaRef, Capture, I->second); | ||||
3882 | DeclRefExpr *Ref = nullptr; | ||||
3883 | ExprResult Res = buildCapture(SemaRef, Capture, Ref); | ||||
3884 | Captures[Capture] = Ref; | ||||
3885 | return Res; | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3886 | } |
3887 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3888 | /// \brief Build the expression to calculate the number of iterations. |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3889 | Expr *OpenMPIterationSpaceChecker::BuildNumIterations( |
3890 | Scope *S, const bool LimitedType, | ||||
3891 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3892 | ExprResult Diff; |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 3893 | auto VarType = LCDecl->getType().getNonReferenceType(); |
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3894 | if (VarType->isIntegerType() || VarType->isPointerType() || |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3895 | SemaRef.getLangOpts().CPlusPlus) { |
3896 | // Upper - Lower | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3897 | auto *UBExpr = TestIsLessOp ? UB : LB; |
3898 | auto *LBExpr = TestIsLessOp ? LB : UB; | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3899 | Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); |
3900 | Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3901 | if (!Upper || !Lower) |
3902 | return nullptr; | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3903 | |
3904 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); | ||||
3905 | |||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3906 | if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3907 | // BuildBinOp already emitted error, this one is to point user to upper |
3908 | // and lower bound, and to tell what is passed to 'operator-'. | ||||
3909 | SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) | ||||
3910 | << Upper->getSourceRange() << Lower->getSourceRange(); | ||||
3911 | return nullptr; | ||||
3912 | } | ||||
3913 | } | ||||
3914 | |||||
3915 | if (!Diff.isUsable()) | ||||
3916 | return nullptr; | ||||
3917 | |||||
3918 | // Upper - Lower [- 1] | ||||
3919 | if (TestIsStrictOp) | ||||
3920 | Diff = SemaRef.BuildBinOp( | ||||
3921 | S, DefaultLoc, BO_Sub, Diff.get(), | ||||
3922 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | ||||
3923 | if (!Diff.isUsable()) | ||||
3924 | return nullptr; | ||||
3925 | |||||
3926 | // Upper - Lower [- 1] + Step | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3927 | auto NewStep = tryBuildCapture(SemaRef, Step, Captures); |
3928 | if (!NewStep.isUsable()) | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3929 | return nullptr; |
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3930 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3931 | if (!Diff.isUsable()) |
3932 | return nullptr; | ||||
3933 | |||||
3934 | // Parentheses (for dumping/debugging purposes only). | ||||
3935 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | ||||
3936 | if (!Diff.isUsable()) | ||||
3937 | return nullptr; | ||||
3938 | |||||
3939 | // (Upper - Lower [- 1] + Step) / Step | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3940 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3941 | if (!Diff.isUsable()) |
3942 | return nullptr; | ||||
3943 | |||||
Alexander Musman | 174b3ca | 2014-10-06 11:16:29 +0000 | [diff] [blame] | 3944 | // OpenMP runtime requires 32-bit or 64-bit loop variables. |
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3945 | QualType Type = Diff.get()->getType(); |
3946 | auto &C = SemaRef.Context; | ||||
3947 | bool UseVarType = VarType->hasIntegerRepresentation() && | ||||
3948 | C.getTypeSize(Type) > C.getTypeSize(VarType); | ||||
3949 | if (!Type->isIntegerType() || UseVarType) { | ||||
3950 | unsigned NewSize = | ||||
3951 | UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); | ||||
3952 | bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() | ||||
3953 | : Type->hasSignedIntegerRepresentation(); | ||||
3954 | Type = C.getIntTypeForBitwidth(NewSize, IsSigned); | ||||
Alexey Bataev | 11481f5 | 2016-02-17 10:29:05 +0000 | [diff] [blame] | 3955 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { |
3956 | Diff = SemaRef.PerformImplicitConversion( | ||||
3957 | Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); | ||||
3958 | if (!Diff.isUsable()) | ||||
3959 | return nullptr; | ||||
3960 | } | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3961 | } |
Alexander Musman | 174b3ca | 2014-10-06 11:16:29 +0000 | [diff] [blame] | 3962 | if (LimitedType) { |
Alexander Musman | 174b3ca | 2014-10-06 11:16:29 +0000 | [diff] [blame] | 3963 | unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; |
3964 | if (NewSize != C.getTypeSize(Type)) { | ||||
3965 | if (NewSize < C.getTypeSize(Type)) { | ||||
3966 | assert(NewSize == 64 && "incorrect loop var size"); | ||||
3967 | SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) | ||||
3968 | << InitSrcRange << ConditionSrcRange; | ||||
3969 | } | ||||
3970 | QualType NewType = C.getIntTypeForBitwidth( | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3971 | NewSize, Type->hasSignedIntegerRepresentation() || |
3972 | C.getTypeSize(Type) < NewSize); | ||||
Alexey Bataev | 11481f5 | 2016-02-17 10:29:05 +0000 | [diff] [blame] | 3973 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { |
3974 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, | ||||
3975 | Sema::AA_Converting, true); | ||||
3976 | if (!Diff.isUsable()) | ||||
3977 | return nullptr; | ||||
3978 | } | ||||
Alexander Musman | 174b3ca | 2014-10-06 11:16:29 +0000 | [diff] [blame] | 3979 | } |
3980 | } | ||||
3981 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 3982 | return Diff.get(); |
3983 | } | ||||
3984 | |||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3985 | Expr *OpenMPIterationSpaceChecker::BuildPreCond( |
3986 | Scope *S, Expr *Cond, | ||||
3987 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { | ||||
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 3988 | // Try to build LB <op> UB, where <op> is <, >, <=, or >=. |
3989 | bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); | ||||
3990 | SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 3991 | |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 3992 | auto NewLB = tryBuildCapture(SemaRef, LB, Captures); |
3993 | auto NewUB = tryBuildCapture(SemaRef, UB, Captures); | ||||
3994 | if (!NewLB.isUsable() || !NewUB.isUsable()) | ||||
3995 | return nullptr; | ||||
3996 | |||||
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 3997 | auto CondExpr = SemaRef.BuildBinOp( |
3998 | S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) | ||||
3999 | : (TestIsStrictOp ? BO_GT : BO_GE), | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4000 | NewLB.get(), NewUB.get()); |
Alexey Bataev | 3bed68c | 2015-07-15 12:14:07 +0000 | [diff] [blame] | 4001 | if (CondExpr.isUsable()) { |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4002 | if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), |
4003 | SemaRef.Context.BoolTy)) | ||||
Alexey Bataev | 11481f5 | 2016-02-17 10:29:05 +0000 | [diff] [blame] | 4004 | CondExpr = SemaRef.PerformImplicitConversion( |
4005 | CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, | ||||
4006 | /*AllowExplicit=*/true); | ||||
Alexey Bataev | 3bed68c | 2015-07-15 12:14:07 +0000 | [diff] [blame] | 4007 | } |
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 4008 | SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); |
4009 | // Otherwise use original loop conditon and evaluate it in runtime. | ||||
4010 | return CondExpr.isUsable() ? CondExpr.get() : Cond; | ||||
4011 | } | ||||
4012 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4013 | /// \brief Build reference expression to the counter be used for codegen. |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4014 | DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 4015 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4016 | auto *VD = dyn_cast<VarDecl>(LCDecl); |
4017 | if (!VD) { | ||||
4018 | VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); | ||||
4019 | auto *Ref = buildDeclRefExpr( | ||||
4020 | SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); | ||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 4021 | DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false); |
4022 | // If the loop control decl is explicitly marked as private, do not mark it | ||||
4023 | // as captured again. | ||||
4024 | if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) | ||||
4025 | Captures.insert(std::make_pair(LCRef, Ref)); | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4026 | return Ref; |
4027 | } | ||||
4028 | return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), | ||||
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 4029 | DefaultLoc); |
4030 | } | ||||
4031 | |||||
4032 | Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4033 | if (LCDecl && !LCDecl->isInvalidDecl()) { |
4034 | auto Type = LCDecl->getType().getNonReferenceType(); | ||||
Alexey Bataev | 1d7f0fa | 2015-09-10 09:48:30 +0000 | [diff] [blame] | 4035 | auto *PrivateVar = |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4036 | buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), |
4037 | LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); | ||||
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 4038 | if (PrivateVar->isInvalidDecl()) |
4039 | return nullptr; | ||||
4040 | return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); | ||||
4041 | } | ||||
4042 | return nullptr; | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4043 | } |
4044 | |||||
Samuel Antao | 4c8035b | 2016-12-12 18:00:20 +0000 | [diff] [blame] | 4045 | /// \brief Build initialization of the counter to be used for codegen. |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4046 | Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } |
4047 | |||||
4048 | /// \brief Build step of the counter be used for codegen. | ||||
4049 | Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } | ||||
4050 | |||||
4051 | /// \brief Iteration space of a single for loop. | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4052 | struct LoopIterationSpace final { |
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 4053 | /// \brief Condition of the loop. |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4054 | Expr *PreCond = nullptr; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4055 | /// \brief This expression calculates the number of iterations in the loop. |
4056 | /// It is always possible to calculate it before starting the loop. | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4057 | Expr *NumIterations = nullptr; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4058 | /// \brief The loop counter variable. |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4059 | Expr *CounterVar = nullptr; |
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 4060 | /// \brief Private loop counter variable. |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4061 | Expr *PrivateCounterVar = nullptr; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4062 | /// \brief This is initializer for the initial value of #CounterVar. |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4063 | Expr *CounterInit = nullptr; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4064 | /// \brief This is step for the #CounterVar used to generate its update: |
4065 | /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4066 | Expr *CounterStep = nullptr; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4067 | /// \brief Should step be subtracted? |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4068 | bool Subtract = false; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4069 | /// \brief Source range of the loop init. |
4070 | SourceRange InitSrcRange; | ||||
4071 | /// \brief Source range of the loop condition. | ||||
4072 | SourceRange CondSrcRange; | ||||
4073 | /// \brief Source range of the loop increment. | ||||
4074 | SourceRange IncSrcRange; | ||||
4075 | }; | ||||
4076 | |||||
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 4077 | } // namespace |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4078 | |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 4079 | void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { |
4080 | assert(getLangOpts().OpenMP && "OpenMP is not active."); | ||||
4081 | assert(Init && "Expected loop in canonical form."); | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 4082 | unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); |
4083 | if (AssociatedLoops > 0 && | ||||
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 4084 | isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { |
4085 | OpenMPIterationSpaceChecker ISC(*this, ForLoc); | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4086 | if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { |
4087 | if (auto *D = ISC.GetLoopDecl()) { | ||||
4088 | auto *VD = dyn_cast<VarDecl>(D); | ||||
4089 | if (!VD) { | ||||
4090 | if (auto *Private = IsOpenMPCapturedDecl(D)) | ||||
4091 | VD = Private; | ||||
4092 | else { | ||||
4093 | auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), | ||||
4094 | /*WithInit=*/false); | ||||
4095 | VD = cast<VarDecl>(Ref->getDecl()); | ||||
4096 | } | ||||
4097 | } | ||||
4098 | DSAStack->addLoopControlVariable(D, VD); | ||||
4099 | } | ||||
4100 | } | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 4101 | DSAStack->setAssociatedLoops(AssociatedLoops - 1); |
Alexey Bataev | 9c82103 | 2015-04-30 04:23:23 +0000 | [diff] [blame] | 4102 | } |
4103 | } | ||||
4104 | |||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4105 | /// \brief Called on a for stmt to check and extract its iteration space |
4106 | /// for further processing (such as collapsing). | ||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 4107 | static bool CheckOpenMPIterationSpace( |
4108 | OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, | ||||
4109 | unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4110 | Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 4111 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4112 | LoopIterationSpace &ResultIterSpace, |
4113 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4114 | // OpenMP [2.6, Canonical Loop Form] |
4115 | // for (init-expr; test-expr; incr-expr) structured-block | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4116 | auto *For = dyn_cast_or_null<ForStmt>(S); |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4117 | if (!For) { |
4118 | SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4119 | << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) |
4120 | << getOpenMPDirectiveName(DKind) << NestedLoopCount | ||||
4121 | << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; | ||||
4122 | if (NestedLoopCount > 1) { | ||||
4123 | if (CollapseLoopCountExpr && OrderedLoopCountExpr) | ||||
4124 | SemaRef.Diag(DSA.getConstructLoc(), | ||||
4125 | diag::note_omp_collapse_ordered_expr) | ||||
4126 | << 2 << CollapseLoopCountExpr->getSourceRange() | ||||
4127 | << OrderedLoopCountExpr->getSourceRange(); | ||||
4128 | else if (CollapseLoopCountExpr) | ||||
4129 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), | ||||
4130 | diag::note_omp_collapse_ordered_expr) | ||||
4131 | << 0 << CollapseLoopCountExpr->getSourceRange(); | ||||
4132 | else | ||||
4133 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), | ||||
4134 | diag::note_omp_collapse_ordered_expr) | ||||
4135 | << 1 << OrderedLoopCountExpr->getSourceRange(); | ||||
4136 | } | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4137 | return true; |
4138 | } | ||||
4139 | assert(For->getBody()); | ||||
4140 | |||||
4141 | OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); | ||||
4142 | |||||
4143 | // Check init. | ||||
Alexey Bataev | df9b159 | 2014-06-25 04:09:13 +0000 | [diff] [blame] | 4144 | auto Init = For->getInit(); |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4145 | if (ISC.CheckInit(Init)) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4146 | return true; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4147 | |
4148 | bool HasErrors = false; | ||||
4149 | |||||
4150 | // Check loop variable's type. | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4151 | if (auto *LCDecl = ISC.GetLoopDecl()) { |
4152 | auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4153 | |
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4154 | // OpenMP [2.6, Canonical Loop Form] |
4155 | // Var is one of the following: | ||||
4156 | // A variable of signed or unsigned integer type. | ||||
4157 | // For C++, a variable of a random access iterator type. | ||||
4158 | // For C, a variable of a pointer type. | ||||
4159 | auto VarType = LCDecl->getType().getNonReferenceType(); | ||||
4160 | if (!VarType->isDependentType() && !VarType->isIntegerType() && | ||||
4161 | !VarType->isPointerType() && | ||||
4162 | !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { | ||||
4163 | SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) | ||||
4164 | << SemaRef.getLangOpts().CPlusPlus; | ||||
4165 | HasErrors = true; | ||||
4166 | } | ||||
4167 | |||||
4168 | // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in | ||||
4169 | // a Construct | ||||
4170 | // The loop iteration variable(s) in the associated for-loop(s) of a for or | ||||
4171 | // parallel for construct is (are) private. | ||||
4172 | // The loop iteration variable in the associated for-loop of a simd | ||||
4173 | // construct with just one associated for-loop is linear with a | ||||
4174 | // constant-linear-step that is the increment of the associated for-loop. | ||||
4175 | // Exclude loop var from the list of variables with implicitly defined data | ||||
4176 | // sharing attributes. | ||||
4177 | VarsWithImplicitDSA.erase(LCDecl); | ||||
4178 | |||||
4179 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
4180 | // in a Construct, C/C++]. | ||||
4181 | // The loop iteration variable in the associated for-loop of a simd | ||||
4182 | // construct with just one associated for-loop may be listed in a linear | ||||
4183 | // clause with a constant-linear-step that is the increment of the | ||||
4184 | // associated for-loop. | ||||
4185 | // The loop iteration variable(s) in the associated for-loop(s) of a for or | ||||
4186 | // parallel for construct may be listed in a private or lastprivate clause. | ||||
4187 | DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); | ||||
4188 | // If LoopVarRefExpr is nullptr it means the corresponding loop variable is | ||||
4189 | // declared in the loop and it is predetermined as a private. | ||||
4190 | auto PredeterminedCKind = | ||||
4191 | isOpenMPSimdDirective(DKind) | ||||
4192 | ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) | ||||
4193 | : OMPC_private; | ||||
4194 | if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && | ||||
4195 | DVar.CKind != PredeterminedCKind) || | ||||
4196 | ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || | ||||
4197 | isOpenMPDistributeDirective(DKind)) && | ||||
4198 | !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && | ||||
4199 | DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && | ||||
4200 | (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { | ||||
4201 | SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) | ||||
4202 | << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) | ||||
4203 | << getOpenMPClauseName(PredeterminedCKind); | ||||
4204 | if (DVar.RefExpr == nullptr) | ||||
4205 | DVar.CKind = PredeterminedCKind; | ||||
4206 | ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); | ||||
4207 | HasErrors = true; | ||||
4208 | } else if (LoopDeclRefExpr != nullptr) { | ||||
4209 | // Make the loop iteration variable private (for worksharing constructs), | ||||
4210 | // linear (for simd directives with the only one associated loop) or | ||||
4211 | // lastprivate (for simd directives with several collapsed or ordered | ||||
4212 | // loops). | ||||
4213 | if (DVar.CKind == OMPC_unknown) | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 4214 | DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, |
4215 | [](OpenMPDirectiveKind) -> bool { return true; }, | ||||
Alexey Bataev | c6ad97a | 2016-04-01 09:23:34 +0000 | [diff] [blame] | 4216 | /*FromParent=*/false); |
4217 | DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); | ||||
4218 | } | ||||
4219 | |||||
4220 | assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); | ||||
4221 | |||||
4222 | // Check test-expr. | ||||
4223 | HasErrors |= ISC.CheckCond(For->getCond()); | ||||
4224 | |||||
4225 | // Check incr-expr. | ||||
4226 | HasErrors |= ISC.CheckInc(For->getInc()); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4227 | } |
4228 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4229 | if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4230 | return HasErrors; |
4231 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4232 | // Build the loop's iteration space representation. |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4233 | ResultIterSpace.PreCond = |
4234 | ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); | ||||
Alexander Musman | 174b3ca | 2014-10-06 11:16:29 +0000 | [diff] [blame] | 4235 | ResultIterSpace.NumIterations = ISC.BuildNumIterations( |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4236 | DSA.getCurScope(), |
4237 | (isOpenMPWorksharingDirective(DKind) || | ||||
4238 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), | ||||
4239 | Captures); | ||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 4240 | ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA); |
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 4241 | ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4242 | ResultIterSpace.CounterInit = ISC.BuildCounterInit(); |
4243 | ResultIterSpace.CounterStep = ISC.BuildCounterStep(); | ||||
4244 | ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); | ||||
4245 | ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); | ||||
4246 | ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); | ||||
4247 | ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); | ||||
4248 | |||||
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 4249 | HasErrors |= (ResultIterSpace.PreCond == nullptr || |
4250 | ResultIterSpace.NumIterations == nullptr || | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4251 | ResultIterSpace.CounterVar == nullptr || |
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 4252 | ResultIterSpace.PrivateCounterVar == nullptr || |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4253 | ResultIterSpace.CounterInit == nullptr || |
4254 | ResultIterSpace.CounterStep == nullptr); | ||||
4255 | |||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4256 | return HasErrors; |
4257 | } | ||||
4258 | |||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4259 | /// \brief Build 'VarRef = Start. |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4260 | static ExprResult |
4261 | BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, | ||||
4262 | ExprResult Start, | ||||
4263 | llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4264 | // Build 'VarRef = Start. |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4265 | auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); |
4266 | if (!NewStart.isUsable()) | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4267 | return ExprError(); |
Alexey Bataev | 11481f5 | 2016-02-17 10:29:05 +0000 | [diff] [blame] | 4268 | if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), |
Alexey Bataev | 11481f5 | 2016-02-17 10:29:05 +0000 | [diff] [blame] | 4269 | VarRef.get()->getType())) { |
4270 | NewStart = SemaRef.PerformImplicitConversion( | ||||
4271 | NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, | ||||
4272 | /*AllowExplicit=*/true); | ||||
4273 | if (!NewStart.isUsable()) | ||||
4274 | return ExprError(); | ||||
4275 | } | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4276 | |
4277 | auto Init = | ||||
4278 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); | ||||
4279 | return Init; | ||||
4280 | } | ||||
4281 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4282 | /// \brief Build 'VarRef = Start + Iter * Step'. |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4283 | static ExprResult |
4284 | BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, | ||||
4285 | ExprResult VarRef, ExprResult Start, ExprResult Iter, | ||||
4286 | ExprResult Step, bool Subtract, | ||||
4287 | llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4288 | // Add parentheses (for debugging purposes only). |
4289 | Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); | ||||
4290 | if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || | ||||
4291 | !Step.isUsable()) | ||||
4292 | return ExprError(); | ||||
4293 | |||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4294 | ExprResult NewStep = Step; |
4295 | if (Captures) | ||||
4296 | NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4297 | if (NewStep.isInvalid()) |
4298 | return ExprError(); | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4299 | ExprResult Update = |
4300 | SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4301 | if (!Update.isUsable()) |
4302 | return ExprError(); | ||||
4303 | |||||
Alexey Bataev | c0214e0 | 2016-02-16 12:13:49 +0000 | [diff] [blame] | 4304 | // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or |
4305 | // 'VarRef = Start (+|-) Iter * Step'. | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4306 | ExprResult NewStart = Start; |
4307 | if (Captures) | ||||
4308 | NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4309 | if (NewStart.isInvalid()) |
4310 | return ExprError(); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4311 | |
Alexey Bataev | c0214e0 | 2016-02-16 12:13:49 +0000 | [diff] [blame] | 4312 | // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. |
4313 | ExprResult SavedUpdate = Update; | ||||
4314 | ExprResult UpdateVal; | ||||
4315 | if (VarRef.get()->getType()->isOverloadableType() || | ||||
4316 | NewStart.get()->getType()->isOverloadableType() || | ||||
4317 | Update.get()->getType()->isOverloadableType()) { | ||||
4318 | bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); | ||||
4319 | SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); | ||||
4320 | Update = | ||||
4321 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); | ||||
4322 | if (Update.isUsable()) { | ||||
4323 | UpdateVal = | ||||
4324 | SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, | ||||
4325 | VarRef.get(), SavedUpdate.get()); | ||||
4326 | if (UpdateVal.isUsable()) { | ||||
4327 | Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), | ||||
4328 | UpdateVal.get()); | ||||
4329 | } | ||||
4330 | } | ||||
4331 | SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); | ||||
4332 | } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4333 | |
Alexey Bataev | c0214e0 | 2016-02-16 12:13:49 +0000 | [diff] [blame] | 4334 | // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. |
4335 | if (!Update.isUsable() || !UpdateVal.isUsable()) { | ||||
4336 | Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, | ||||
4337 | NewStart.get(), SavedUpdate.get()); | ||||
4338 | if (!Update.isUsable()) | ||||
4339 | return ExprError(); | ||||
4340 | |||||
Alexey Bataev | 11481f5 | 2016-02-17 10:29:05 +0000 | [diff] [blame] | 4341 | if (!SemaRef.Context.hasSameType(Update.get()->getType(), |
4342 | VarRef.get()->getType())) { | ||||
4343 | Update = SemaRef.PerformImplicitConversion( | ||||
4344 | Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); | ||||
4345 | if (!Update.isUsable()) | ||||
4346 | return ExprError(); | ||||
4347 | } | ||||
Alexey Bataev | c0214e0 | 2016-02-16 12:13:49 +0000 | [diff] [blame] | 4348 | |
4349 | Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); | ||||
4350 | } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4351 | return Update; |
4352 | } | ||||
4353 | |||||
4354 | /// \brief Convert integer expression \a E to make it have at least \a Bits | ||||
4355 | /// bits. | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4356 | static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4357 | if (E == nullptr) |
4358 | return ExprError(); | ||||
4359 | auto &C = SemaRef.Context; | ||||
4360 | QualType OldType = E->getType(); | ||||
4361 | unsigned HasBits = C.getTypeSize(OldType); | ||||
4362 | if (HasBits >= Bits) | ||||
4363 | return ExprResult(E); | ||||
4364 | // OK to convert to signed, because new type has more bits than old. | ||||
4365 | QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); | ||||
4366 | return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, | ||||
4367 | true); | ||||
4368 | } | ||||
4369 | |||||
4370 | /// \brief Check if the given expression \a E is a constant integer that fits | ||||
4371 | /// into \a Bits bits. | ||||
4372 | static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { | ||||
4373 | if (E == nullptr) | ||||
4374 | return false; | ||||
4375 | llvm::APSInt Result; | ||||
4376 | if (E->isIntegerConstantExpr(Result, SemaRef.Context)) | ||||
4377 | return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); | ||||
4378 | return false; | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4379 | } |
4380 | |||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4381 | /// Build preinits statement for the given declarations. |
4382 | static Stmt *buildPreInits(ASTContext &Context, | ||||
Alexey Bataev | c551406 | 2017-10-25 15:44:52 +0000 | [diff] [blame] | 4383 | MutableArrayRef<Decl *> PreInits) { |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4384 | if (!PreInits.empty()) { |
4385 | return new (Context) DeclStmt( | ||||
4386 | DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), | ||||
4387 | SourceLocation(), SourceLocation()); | ||||
4388 | } | ||||
4389 | return nullptr; | ||||
4390 | } | ||||
4391 | |||||
4392 | /// Build preinits statement for the given declarations. | ||||
Alexey Bataev | c551406 | 2017-10-25 15:44:52 +0000 | [diff] [blame] | 4393 | static Stmt * |
4394 | buildPreInits(ASTContext &Context, | ||||
4395 | const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4396 | if (!Captures.empty()) { |
4397 | SmallVector<Decl *, 16> PreInits; | ||||
4398 | for (auto &Pair : Captures) | ||||
4399 | PreInits.push_back(Pair.second->getDecl()); | ||||
4400 | return buildPreInits(Context, PreInits); | ||||
4401 | } | ||||
4402 | return nullptr; | ||||
4403 | } | ||||
4404 | |||||
4405 | /// Build postupdate expression for the given list of postupdates expressions. | ||||
4406 | static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { | ||||
4407 | Expr *PostUpdate = nullptr; | ||||
4408 | if (!PostUpdates.empty()) { | ||||
4409 | for (auto *E : PostUpdates) { | ||||
4410 | Expr *ConvE = S.BuildCStyleCastExpr( | ||||
4411 | E->getExprLoc(), | ||||
4412 | S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), | ||||
4413 | E->getExprLoc(), E) | ||||
4414 | .get(); | ||||
4415 | PostUpdate = PostUpdate | ||||
4416 | ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, | ||||
4417 | PostUpdate, ConvE) | ||||
4418 | .get() | ||||
4419 | : ConvE; | ||||
4420 | } | ||||
4421 | } | ||||
4422 | return PostUpdate; | ||||
4423 | } | ||||
4424 | |||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4425 | /// \brief Called on a for stmt to check itself and nested loops (if any). |
Alexey Bataev | abfc069 | 2014-06-25 06:52:00 +0000 | [diff] [blame] | 4426 | /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, |
4427 | /// number of collapsed loops otherwise. | ||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 4428 | static unsigned |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4429 | CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, |
4430 | Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, | ||||
4431 | DSAStackTy &DSA, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 4432 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4433 | OMPLoopDirective::HelperExprs &Built) { |
Alexey Bataev | e2f07d4 | 2014-06-24 12:55:56 +0000 | [diff] [blame] | 4434 | unsigned NestedLoopCount = 1; |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4435 | if (CollapseLoopCountExpr) { |
Alexey Bataev | e2f07d4 | 2014-06-24 12:55:56 +0000 | [diff] [blame] | 4436 | // Found 'collapse' clause - calculate collapse number. |
4437 | llvm::APSInt Result; | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4438 | if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) |
Alexey Bataev | 7b6bc88 | 2015-11-26 07:50:39 +0000 | [diff] [blame] | 4439 | NestedLoopCount = Result.getLimitedValue(); |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4440 | } |
4441 | if (OrderedLoopCountExpr) { | ||||
4442 | // Found 'ordered' clause - calculate collapse number. | ||||
4443 | llvm::APSInt Result; | ||||
Alexey Bataev | 7b6bc88 | 2015-11-26 07:50:39 +0000 | [diff] [blame] | 4444 | if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { |
4445 | if (Result.getLimitedValue() < NestedLoopCount) { | ||||
4446 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), | ||||
4447 | diag::err_omp_wrong_ordered_loop_count) | ||||
4448 | << OrderedLoopCountExpr->getSourceRange(); | ||||
4449 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), | ||||
4450 | diag::note_collapse_loop_count) | ||||
4451 | << CollapseLoopCountExpr->getSourceRange(); | ||||
4452 | } | ||||
4453 | NestedLoopCount = Result.getLimitedValue(); | ||||
4454 | } | ||||
Alexey Bataev | e2f07d4 | 2014-06-24 12:55:56 +0000 | [diff] [blame] | 4455 | } |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4456 | // This is helper routine for loop directives (e.g., 'for', 'simd', |
4457 | // 'for simd', etc.). | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4458 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4459 | SmallVector<LoopIterationSpace, 4> IterSpaces; |
4460 | IterSpaces.resize(NestedLoopCount); | ||||
4461 | Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4462 | for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { |
Alexey Bataev | e2f07d4 | 2014-06-24 12:55:56 +0000 | [diff] [blame] | 4463 | if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4464 | NestedLoopCount, CollapseLoopCountExpr, |
4465 | OrderedLoopCountExpr, VarsWithImplicitDSA, | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4466 | IterSpaces[Cnt], Captures)) |
Alexey Bataev | abfc069 | 2014-06-25 06:52:00 +0000 | [diff] [blame] | 4467 | return 0; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4468 | // Move on to the next nested for loop, or to the loop body. |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4469 | // OpenMP [2.8.1, simd construct, Restrictions] |
4470 | // All loops associated with the construct must be perfectly nested; that | ||||
4471 | // is, there must be no intervening code nor any OpenMP directive between | ||||
4472 | // any two loops. | ||||
4473 | CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 4474 | } |
4475 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4476 | Built.clear(/* size */ NestedLoopCount); |
4477 | |||||
4478 | if (SemaRef.CurContext->isDependentContext()) | ||||
4479 | return NestedLoopCount; | ||||
4480 | |||||
4481 | // An example of what is generated for the following code: | ||||
4482 | // | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4483 | // #pragma omp simd collapse(2) ordered(2) |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4484 | // for (i = 0; i < NI; ++i) |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 4485 | // for (k = 0; k < NK; ++k) |
4486 | // for (j = J0; j < NJ; j+=2) { | ||||
4487 | // <loop body> | ||||
4488 | // } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4489 | // |
4490 | // We generate the code below. | ||||
4491 | // Note: the loop body may be outlined in CodeGen. | ||||
4492 | // Note: some counters may be C++ classes, operator- is used to find number of | ||||
4493 | // iterations and operator+= to calculate counter value. | ||||
4494 | // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 | ||||
4495 | // or i64 is currently supported). | ||||
4496 | // | ||||
4497 | // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) | ||||
4498 | // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { | ||||
4499 | // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); | ||||
4500 | // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; | ||||
4501 | // // similar updates for vars in clauses (e.g. 'linear') | ||||
4502 | // <loop body (using local i and j)> | ||||
4503 | // } | ||||
4504 | // i = NI; // assign final values of counters | ||||
4505 | // j = NJ; | ||||
4506 | // | ||||
4507 | |||||
4508 | // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are | ||||
4509 | // the iteration counts of the collapsed for loops. | ||||
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 4510 | // Precondition tests if there is at least one iteration (all conditions are |
4511 | // true). | ||||
4512 | auto PreCond = ExprResult(IterSpaces[0].PreCond); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4513 | auto N0 = IterSpaces[0].NumIterations; |
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4514 | ExprResult LastIteration32 = WidenIterationCount( |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4515 | 32 /* Bits */, SemaRef |
4516 | .PerformImplicitConversion( | ||||
4517 | N0->IgnoreImpCasts(), N0->getType(), | ||||
4518 | Sema::AA_Converting, /*AllowExplicit=*/true) | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4519 | .get(), |
4520 | SemaRef); | ||||
4521 | ExprResult LastIteration64 = WidenIterationCount( | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4522 | 64 /* Bits */, SemaRef |
4523 | .PerformImplicitConversion( | ||||
4524 | N0->IgnoreImpCasts(), N0->getType(), | ||||
4525 | Sema::AA_Converting, /*AllowExplicit=*/true) | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4526 | .get(), |
4527 | SemaRef); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4528 | |
4529 | if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) | ||||
4530 | return NestedLoopCount; | ||||
4531 | |||||
4532 | auto &C = SemaRef.Context; | ||||
4533 | bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; | ||||
4534 | |||||
4535 | Scope *CurScope = DSA.getCurScope(); | ||||
4536 | for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { | ||||
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 4537 | if (PreCond.isUsable()) { |
Alexey Bataev | a7206b9 | 2016-12-20 16:51:02 +0000 | [diff] [blame] | 4538 | PreCond = |
4539 | SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, | ||||
4540 | PreCond.get(), IterSpaces[Cnt].PreCond); | ||||
Alexey Bataev | 62dbb97 | 2015-04-22 11:59:37 +0000 | [diff] [blame] | 4541 | } |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4542 | auto N = IterSpaces[Cnt].NumIterations; |
Alexey Bataev | a7206b9 | 2016-12-20 16:51:02 +0000 | [diff] [blame] | 4543 | SourceLocation Loc = N->getExprLoc(); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4544 | AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; |
4545 | if (LastIteration32.isUsable()) | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4546 | LastIteration32 = SemaRef.BuildBinOp( |
Alexey Bataev | a7206b9 | 2016-12-20 16:51:02 +0000 | [diff] [blame] | 4547 | CurScope, Loc, BO_Mul, LastIteration32.get(), |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4548 | SemaRef |
4549 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), | ||||
4550 | Sema::AA_Converting, | ||||
4551 | /*AllowExplicit=*/true) | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4552 | .get()); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4553 | if (LastIteration64.isUsable()) |
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4554 | LastIteration64 = SemaRef.BuildBinOp( |
Alexey Bataev | a7206b9 | 2016-12-20 16:51:02 +0000 | [diff] [blame] | 4555 | CurScope, Loc, BO_Mul, LastIteration64.get(), |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4556 | SemaRef |
4557 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), | ||||
4558 | Sema::AA_Converting, | ||||
4559 | /*AllowExplicit=*/true) | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4560 | .get()); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4561 | } |
4562 | |||||
4563 | // Choose either the 32-bit or 64-bit version. | ||||
4564 | ExprResult LastIteration = LastIteration64; | ||||
4565 | if (LastIteration32.isUsable() && | ||||
4566 | C.getTypeSize(LastIteration32.get()->getType()) == 32 && | ||||
4567 | (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || | ||||
4568 | FitsInto( | ||||
4569 | 32 /* Bits */, | ||||
4570 | LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), | ||||
4571 | LastIteration64.get(), SemaRef))) | ||||
4572 | LastIteration = LastIteration32; | ||||
Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 4573 | QualType VType = LastIteration.get()->getType(); |
4574 | QualType RealVType = VType; | ||||
4575 | QualType StrideVType = VType; | ||||
4576 | if (isOpenMPTaskLoopDirective(DKind)) { | ||||
4577 | VType = | ||||
4578 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); | ||||
4579 | StrideVType = | ||||
4580 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); | ||||
4581 | } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4582 | |
4583 | if (!LastIteration.isUsable()) | ||||
4584 | return 0; | ||||
4585 | |||||
4586 | // Save the number of iterations. | ||||
4587 | ExprResult NumIterations = LastIteration; | ||||
4588 | { | ||||
4589 | LastIteration = SemaRef.BuildBinOp( | ||||
Alexey Bataev | a7206b9 | 2016-12-20 16:51:02 +0000 | [diff] [blame] | 4590 | CurScope, LastIteration.get()->getExprLoc(), BO_Sub, |
4591 | LastIteration.get(), | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4592 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); |
4593 | if (!LastIteration.isUsable()) | ||||
4594 | return 0; | ||||
4595 | } | ||||
4596 | |||||
4597 | // Calculate the last iteration number beforehand instead of doing this on | ||||
4598 | // each iteration. Do not do this if the number of iterations may be kfold-ed. | ||||
4599 | llvm::APSInt Result; | ||||
4600 | bool IsConstant = | ||||
4601 | LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); | ||||
4602 | ExprResult CalcLastIteration; | ||||
4603 | if (!IsConstant) { | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4604 | ExprResult SaveRef = |
4605 | tryBuildCapture(SemaRef, LastIteration.get(), Captures); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4606 | LastIteration = SaveRef; |
4607 | |||||
4608 | // Prepare SaveRef + 1. | ||||
4609 | NumIterations = SemaRef.BuildBinOp( | ||||
Alexey Bataev | a7206b9 | 2016-12-20 16:51:02 +0000 | [diff] [blame] | 4610 | CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4611 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); |
4612 | if (!NumIterations.isUsable()) | ||||
4613 | return 0; | ||||
4614 | } | ||||
4615 | |||||
4616 | SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); | ||||
4617 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4618 | // Build variables passed into runtime, necessary for worksharing directives. |
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4619 | ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; |
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 4620 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || |
4621 | isOpenMPDistributeDirective(DKind)) { | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4622 | // Lower bound variable, initialized with zero. |
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 4623 | VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); |
4624 | LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); | ||||
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 4625 | SemaRef.AddInitializerToDecl(LBDecl, |
4626 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||
4627 | /*DirectInit*/ false); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4628 | |
4629 | // Upper bound variable, initialized with last iteration number. | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 4630 | VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); |
4631 | UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4632 | SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), |
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 4633 | /*DirectInit*/ false); |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4634 | |
4635 | // A 32-bit variable-flag where runtime returns 1 for the last iteration. | ||||
4636 | // This will be used to implement clause 'lastprivate'. | ||||
4637 | QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 4638 | VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); |
4639 | IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); | ||||
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 4640 | SemaRef.AddInitializerToDecl(ILDecl, |
4641 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||
4642 | /*DirectInit*/ false); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4643 | |
4644 | // Stride variable returned by runtime (we initialize it to 1 by default). | ||||
Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 4645 | VarDecl *STDecl = |
4646 | buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); | ||||
4647 | ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); | ||||
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 4648 | SemaRef.AddInitializerToDecl(STDecl, |
4649 | SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), | ||||
4650 | /*DirectInit*/ false); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4651 | |
4652 | // Build expression: UB = min(UB, LastIteration) | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4653 | // It is necessary for CodeGen of directives with static scheduling. |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4654 | ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, |
4655 | UB.get(), LastIteration.get()); | ||||
4656 | ExprResult CondOp = SemaRef.ActOnConditionalOp( | ||||
4657 | InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); | ||||
4658 | EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), | ||||
4659 | CondOp.get()); | ||||
4660 | EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 4661 | |
4662 | // If we have a combined directive that combines 'distribute', 'for' or | ||||
4663 | // 'simd' we need to be able to access the bounds of the schedule of the | ||||
4664 | // enclosing region. E.g. in 'distribute parallel for' the bounds obtained | ||||
4665 | // by scheduling 'distribute' have to be passed to the schedule of 'for'. | ||||
4666 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 4667 | |
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4668 | // Lower bound variable, initialized with zero. |
4669 | VarDecl *CombLBDecl = | ||||
4670 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); | ||||
4671 | CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); | ||||
4672 | SemaRef.AddInitializerToDecl( | ||||
4673 | CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | ||||
4674 | /*DirectInit*/ false); | ||||
4675 | |||||
4676 | // Upper bound variable, initialized with last iteration number. | ||||
4677 | VarDecl *CombUBDecl = | ||||
4678 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); | ||||
4679 | CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); | ||||
4680 | SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), | ||||
4681 | /*DirectInit*/ false); | ||||
4682 | |||||
4683 | ExprResult CombIsUBGreater = SemaRef.BuildBinOp( | ||||
4684 | CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); | ||||
4685 | ExprResult CombCondOp = | ||||
4686 | SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), | ||||
4687 | LastIteration.get(), CombUB.get()); | ||||
4688 | CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), | ||||
4689 | CombCondOp.get()); | ||||
4690 | CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); | ||||
4691 | |||||
4692 | auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 4693 | // We expect to have at least 2 more parameters than the 'parallel' |
4694 | // directive does - the lower and upper bounds of the previous schedule. | ||||
4695 | assert(CD->getNumParams() >= 4 && | ||||
4696 | "Unexpected number of parameters in loop combined directive"); | ||||
4697 | |||||
4698 | // Set the proper type for the bounds given what we learned from the | ||||
4699 | // enclosed loops. | ||||
4700 | auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2); | ||||
4701 | auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3); | ||||
4702 | |||||
4703 | // Previous lower and upper bounds are obtained from the region | ||||
4704 | // parameters. | ||||
4705 | PrevLB = | ||||
4706 | buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); | ||||
4707 | PrevUB = | ||||
4708 | buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); | ||||
4709 | } | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4710 | } |
4711 | |||||
4712 | // Build the iteration variable and its initialization before loop. | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4713 | ExprResult IV; |
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4714 | ExprResult Init, CombInit; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4715 | { |
Alexey Bataev | 7292c29 | 2016-04-25 12:22:29 +0000 | [diff] [blame] | 4716 | VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); |
4717 | IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 4718 | Expr *RHS = |
4719 | (isOpenMPWorksharingDirective(DKind) || | ||||
4720 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) | ||||
4721 | ? LB.get() | ||||
4722 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4723 | Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); |
4724 | Init = SemaRef.ActOnFinishFullExpr(Init.get()); | ||||
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4725 | |
4726 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||
4727 | Expr *CombRHS = | ||||
4728 | (isOpenMPWorksharingDirective(DKind) || | ||||
4729 | isOpenMPTaskLoopDirective(DKind) || | ||||
4730 | isOpenMPDistributeDirective(DKind)) | ||||
4731 | ? CombLB.get() | ||||
4732 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); | ||||
4733 | CombInit = | ||||
4734 | SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); | ||||
4735 | CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); | ||||
4736 | } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4737 | } |
4738 | |||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4739 | // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4740 | SourceLocation CondLoc; |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4741 | ExprResult Cond = |
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 4742 | (isOpenMPWorksharingDirective(DKind) || |
4743 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4744 | ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) |
4745 | : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), | ||||
4746 | NumIterations.get()); | ||||
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4747 | ExprResult CombCond; |
4748 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||
4749 | CombCond = | ||||
4750 | SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); | ||||
4751 | } | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4752 | // Loop increment (IV = IV + 1) |
4753 | SourceLocation IncLoc; | ||||
4754 | ExprResult Inc = | ||||
4755 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), | ||||
4756 | SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); | ||||
4757 | if (!Inc.isUsable()) | ||||
4758 | return 0; | ||||
4759 | Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4760 | Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); |
4761 | if (!Inc.isUsable()) | ||||
4762 | return 0; | ||||
4763 | |||||
4764 | // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). | ||||
4765 | // Used for directives with static scheduling. | ||||
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4766 | // In combined construct, add combined version that use CombLB and CombUB |
4767 | // base variables for the update | ||||
4768 | ExprResult NextLB, NextUB, CombNextLB, CombNextUB; | ||||
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 4769 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || |
4770 | isOpenMPDistributeDirective(DKind)) { | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4771 | // LB + ST |
4772 | NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); | ||||
4773 | if (!NextLB.isUsable()) | ||||
4774 | return 0; | ||||
4775 | // LB = LB + ST | ||||
4776 | NextLB = | ||||
4777 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); | ||||
4778 | NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); | ||||
4779 | if (!NextLB.isUsable()) | ||||
4780 | return 0; | ||||
4781 | // UB + ST | ||||
4782 | NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); | ||||
4783 | if (!NextUB.isUsable()) | ||||
4784 | return 0; | ||||
4785 | // UB = UB + ST | ||||
4786 | NextUB = | ||||
4787 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); | ||||
4788 | NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); | ||||
4789 | if (!NextUB.isUsable()) | ||||
4790 | return 0; | ||||
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4791 | if (isOpenMPLoopBoundSharingDirective(DKind)) { |
4792 | CombNextLB = | ||||
4793 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); | ||||
4794 | if (!NextLB.isUsable()) | ||||
4795 | return 0; | ||||
4796 | // LB = LB + ST | ||||
4797 | CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), | ||||
4798 | CombNextLB.get()); | ||||
4799 | CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); | ||||
4800 | if (!CombNextLB.isUsable()) | ||||
4801 | return 0; | ||||
4802 | // UB + ST | ||||
4803 | CombNextUB = | ||||
4804 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); | ||||
4805 | if (!CombNextUB.isUsable()) | ||||
4806 | return 0; | ||||
4807 | // UB = UB + ST | ||||
4808 | CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), | ||||
4809 | CombNextUB.get()); | ||||
4810 | CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); | ||||
4811 | if (!CombNextUB.isUsable()) | ||||
4812 | return 0; | ||||
4813 | } | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4814 | } |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4815 | |
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4816 | // Create increment expression for distribute loop when combined in a same |
Carlo Bertolli | 8429d81 | 2017-02-17 21:29:13 +0000 | [diff] [blame] | 4817 | // directive with for as IV = IV + ST; ensure upper bound expression based |
4818 | // on PrevUB instead of NumIterations - used to implement 'for' when found | ||||
4819 | // in combination with 'distribute', like in 'distribute parallel for' | ||||
4820 | SourceLocation DistIncLoc; | ||||
4821 | ExprResult DistCond, DistInc, PrevEUB; | ||||
4822 | if (isOpenMPLoopBoundSharingDirective(DKind)) { | ||||
4823 | DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); | ||||
4824 | assert(DistCond.isUsable() && "distribute cond expr was not built"); | ||||
4825 | |||||
4826 | DistInc = | ||||
4827 | SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); | ||||
4828 | assert(DistInc.isUsable() && "distribute inc expr was not built"); | ||||
4829 | DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), | ||||
4830 | DistInc.get()); | ||||
4831 | DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); | ||||
4832 | assert(DistInc.isUsable() && "distribute inc expr was not built"); | ||||
4833 | |||||
4834 | // Build expression: UB = min(UB, prevUB) for #for in composite or combined | ||||
4835 | // construct | ||||
4836 | SourceLocation DistEUBLoc; | ||||
4837 | ExprResult IsUBGreater = | ||||
4838 | SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); | ||||
4839 | ExprResult CondOp = SemaRef.ActOnConditionalOp( | ||||
4840 | DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); | ||||
4841 | PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), | ||||
4842 | CondOp.get()); | ||||
4843 | PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); | ||||
4844 | } | ||||
4845 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4846 | // Build updates and final values of the loop counters. |
4847 | bool HasErrors = false; | ||||
4848 | Built.Counters.resize(NestedLoopCount); | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4849 | Built.Inits.resize(NestedLoopCount); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4850 | Built.Updates.resize(NestedLoopCount); |
4851 | Built.Finals.resize(NestedLoopCount); | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4852 | SmallVector<Expr *, 4> LoopMultipliers; |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4853 | { |
4854 | ExprResult Div; | ||||
4855 | // Go from inner nested loop to outer. | ||||
4856 | for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { | ||||
4857 | LoopIterationSpace &IS = IterSpaces[Cnt]; | ||||
4858 | SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); | ||||
4859 | // Build: Iter = (IV / Div) % IS.NumIters | ||||
4860 | // where Div is product of previous iterations' IS.NumIters. | ||||
4861 | ExprResult Iter; | ||||
4862 | if (Div.isUsable()) { | ||||
4863 | Iter = | ||||
4864 | SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); | ||||
4865 | } else { | ||||
4866 | Iter = IV; | ||||
4867 | assert((Cnt == (int)NestedLoopCount - 1) && | ||||
4868 | "unusable div expected on first iteration only"); | ||||
4869 | } | ||||
4870 | |||||
4871 | if (Cnt != 0 && Iter.isUsable()) | ||||
4872 | Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), | ||||
4873 | IS.NumIterations); | ||||
4874 | if (!Iter.isUsable()) { | ||||
4875 | HasErrors = true; | ||||
4876 | break; | ||||
4877 | } | ||||
4878 | |||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 4879 | // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 4880 | auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); |
4881 | auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(), | ||||
4882 | IS.CounterVar->getExprLoc(), | ||||
4883 | /*RefersToCapture=*/true); | ||||
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4884 | ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4885 | IS.CounterInit, Captures); |
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4886 | if (!Init.isUsable()) { |
4887 | HasErrors = true; | ||||
4888 | break; | ||||
4889 | } | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4890 | ExprResult Update = BuildCounterUpdate( |
4891 | SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, | ||||
4892 | IS.CounterStep, IS.Subtract, &Captures); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4893 | if (!Update.isUsable()) { |
4894 | HasErrors = true; | ||||
4895 | break; | ||||
4896 | } | ||||
4897 | |||||
4898 | // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step | ||||
4899 | ExprResult Final = BuildCounterUpdate( | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 4900 | SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4901 | IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4902 | if (!Final.isUsable()) { |
4903 | HasErrors = true; | ||||
4904 | break; | ||||
4905 | } | ||||
4906 | |||||
4907 | // Build Div for the next iteration: Div <- Div * IS.NumIters | ||||
4908 | if (Cnt != 0) { | ||||
4909 | if (Div.isUnset()) | ||||
4910 | Div = IS.NumIterations; | ||||
4911 | else | ||||
4912 | Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), | ||||
4913 | IS.NumIterations); | ||||
4914 | |||||
4915 | // Add parentheses (for debugging purposes only). | ||||
4916 | if (Div.isUsable()) | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4917 | Div = tryBuildCapture(SemaRef, Div.get(), Captures); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4918 | if (!Div.isUsable()) { |
4919 | HasErrors = true; | ||||
4920 | break; | ||||
4921 | } | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4922 | LoopMultipliers.push_back(Div.get()); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4923 | } |
4924 | if (!Update.isUsable() || !Final.isUsable()) { | ||||
4925 | HasErrors = true; | ||||
4926 | break; | ||||
4927 | } | ||||
4928 | // Save results | ||||
4929 | Built.Counters[Cnt] = IS.CounterVar; | ||||
Alexey Bataev | a889917 | 2015-08-06 12:30:57 +0000 | [diff] [blame] | 4930 | Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; |
Alexey Bataev | b08f89f | 2015-08-14 12:25:37 +0000 | [diff] [blame] | 4931 | Built.Inits[Cnt] = Init.get(); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4932 | Built.Updates[Cnt] = Update.get(); |
4933 | Built.Finals[Cnt] = Final.get(); | ||||
4934 | } | ||||
4935 | } | ||||
4936 | |||||
4937 | if (HasErrors) | ||||
4938 | return 0; | ||||
4939 | |||||
4940 | // Save results | ||||
4941 | Built.IterationVarRef = IV.get(); | ||||
4942 | Built.LastIteration = LastIteration.get(); | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 4943 | Built.NumIterations = NumIterations.get(); |
Alexey Bataev | 3bed68c | 2015-07-15 12:14:07 +0000 | [diff] [blame] | 4944 | Built.CalcLastIteration = |
4945 | SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4946 | Built.PreCond = PreCond.get(); |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 4947 | Built.PreInits = buildPreInits(C, Captures); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4948 | Built.Cond = Cond.get(); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4949 | Built.Init = Init.get(); |
4950 | Built.Inc = Inc.get(); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 4951 | Built.LB = LB.get(); |
4952 | Built.UB = UB.get(); | ||||
4953 | Built.IL = IL.get(); | ||||
4954 | Built.ST = ST.get(); | ||||
4955 | Built.EUB = EUB.get(); | ||||
4956 | Built.NLB = NextLB.get(); | ||||
4957 | Built.NUB = NextUB.get(); | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 4958 | Built.PrevLB = PrevLB.get(); |
4959 | Built.PrevUB = PrevUB.get(); | ||||
Carlo Bertolli | 8429d81 | 2017-02-17 21:29:13 +0000 | [diff] [blame] | 4960 | Built.DistInc = DistInc.get(); |
4961 | Built.PrevEUB = PrevEUB.get(); | ||||
Carlo Bertolli | ffafe10 | 2017-04-20 00:39:39 +0000 | [diff] [blame] | 4962 | Built.DistCombinedFields.LB = CombLB.get(); |
4963 | Built.DistCombinedFields.UB = CombUB.get(); | ||||
4964 | Built.DistCombinedFields.EUB = CombEUB.get(); | ||||
4965 | Built.DistCombinedFields.Init = CombInit.get(); | ||||
4966 | Built.DistCombinedFields.Cond = CombCond.get(); | ||||
4967 | Built.DistCombinedFields.NLB = CombNextLB.get(); | ||||
4968 | Built.DistCombinedFields.NUB = CombNextUB.get(); | ||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 4969 | |
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 4970 | Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); |
4971 | // Fill data for doacross depend clauses. | ||||
4972 | for (auto Pair : DSA.getDoacrossDependClauses()) { | ||||
4973 | if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) | ||||
4974 | Pair.first->setCounterValue(CounterVal); | ||||
4975 | else { | ||||
4976 | if (NestedLoopCount != Pair.second.size() || | ||||
4977 | NestedLoopCount != LoopMultipliers.size() + 1) { | ||||
4978 | // Erroneous case - clause has some problems. | ||||
4979 | Pair.first->setCounterValue(CounterVal); | ||||
4980 | continue; | ||||
4981 | } | ||||
4982 | assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); | ||||
4983 | auto I = Pair.second.rbegin(); | ||||
4984 | auto IS = IterSpaces.rbegin(); | ||||
4985 | auto ILM = LoopMultipliers.rbegin(); | ||||
4986 | Expr *UpCounterVal = CounterVal; | ||||
4987 | Expr *Multiplier = nullptr; | ||||
4988 | for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { | ||||
4989 | if (I->first) { | ||||
4990 | assert(IS->CounterStep); | ||||
4991 | Expr *NormalizedOffset = | ||||
4992 | SemaRef | ||||
4993 | .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, | ||||
4994 | I->first, IS->CounterStep) | ||||
4995 | .get(); | ||||
4996 | if (Multiplier) { | ||||
4997 | NormalizedOffset = | ||||
4998 | SemaRef | ||||
4999 | .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, | ||||
5000 | NormalizedOffset, Multiplier) | ||||
5001 | .get(); | ||||
5002 | } | ||||
5003 | assert(I->second == OO_Plus || I->second == OO_Minus); | ||||
5004 | BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5005 | UpCounterVal = SemaRef |
5006 | .BuildBinOp(CurScope, I->first->getExprLoc(), BOK, | ||||
5007 | UpCounterVal, NormalizedOffset) | ||||
5008 | .get(); | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 5009 | } |
5010 | Multiplier = *ILM; | ||||
5011 | ++I; | ||||
5012 | ++IS; | ||||
5013 | ++ILM; | ||||
5014 | } | ||||
5015 | Pair.first->setCounterValue(UpCounterVal); | ||||
5016 | } | ||||
5017 | } | ||||
5018 | |||||
Alexey Bataev | abfc069 | 2014-06-25 06:52:00 +0000 | [diff] [blame] | 5019 | return NestedLoopCount; |
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 5020 | } |
5021 | |||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5022 | static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { |
Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 5023 | auto CollapseClauses = |
5024 | OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); | ||||
5025 | if (CollapseClauses.begin() != CollapseClauses.end()) | ||||
5026 | return (*CollapseClauses.begin())->getNumForLoops(); | ||||
Alexey Bataev | e2f07d4 | 2014-06-24 12:55:56 +0000 | [diff] [blame] | 5027 | return nullptr; |
5028 | } | ||||
5029 | |||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5030 | static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { |
Benjamin Kramer | fc600dc | 2015-08-30 15:12:28 +0000 | [diff] [blame] | 5031 | auto OrderedClauses = |
5032 | OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); | ||||
5033 | if (OrderedClauses.begin() != OrderedClauses.end()) | ||||
5034 | return (*OrderedClauses.begin())->getNumForLoops(); | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5035 | return nullptr; |
5036 | } | ||||
5037 | |||||
Kelvin Li | c560949 | 2016-07-15 04:39:07 +0000 | [diff] [blame] | 5038 | static bool checkSimdlenSafelenSpecified(Sema &S, |
5039 | const ArrayRef<OMPClause *> Clauses) { | ||||
5040 | OMPSafelenClause *Safelen = nullptr; | ||||
5041 | OMPSimdlenClause *Simdlen = nullptr; | ||||
5042 | |||||
5043 | for (auto *Clause : Clauses) { | ||||
5044 | if (Clause->getClauseKind() == OMPC_safelen) | ||||
5045 | Safelen = cast<OMPSafelenClause>(Clause); | ||||
5046 | else if (Clause->getClauseKind() == OMPC_simdlen) | ||||
5047 | Simdlen = cast<OMPSimdlenClause>(Clause); | ||||
5048 | if (Safelen && Simdlen) | ||||
5049 | break; | ||||
5050 | } | ||||
5051 | |||||
5052 | if (Simdlen && Safelen) { | ||||
5053 | llvm::APSInt SimdlenRes, SafelenRes; | ||||
5054 | auto SimdlenLength = Simdlen->getSimdlen(); | ||||
5055 | auto SafelenLength = Safelen->getSafelen(); | ||||
5056 | if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || | ||||
5057 | SimdlenLength->isInstantiationDependent() || | ||||
5058 | SimdlenLength->containsUnexpandedParameterPack()) | ||||
5059 | return false; | ||||
5060 | if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || | ||||
5061 | SafelenLength->isInstantiationDependent() || | ||||
5062 | SafelenLength->containsUnexpandedParameterPack()) | ||||
5063 | return false; | ||||
5064 | SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); | ||||
5065 | SafelenLength->EvaluateAsInt(SafelenRes, S.Context); | ||||
5066 | // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] | ||||
5067 | // If both simdlen and safelen clauses are specified, the value of the | ||||
5068 | // simdlen parameter must be less than or equal to the value of the safelen | ||||
5069 | // parameter. | ||||
5070 | if (SimdlenRes > SafelenRes) { | ||||
5071 | S.Diag(SimdlenLength->getExprLoc(), | ||||
5072 | diag::err_omp_wrong_simdlen_safelen_values) | ||||
5073 | << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); | ||||
5074 | return true; | ||||
5075 | } | ||||
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 5076 | } |
5077 | return false; | ||||
5078 | } | ||||
5079 | |||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5080 | StmtResult Sema::ActOnOpenMPSimdDirective( |
5081 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
5082 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 5083 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5084 | if (!AStmt) |
5085 | return StmtError(); | ||||
5086 | |||||
5087 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5088 | OMPLoopDirective::HelperExprs B; |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5089 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
5090 | // define the nested loops number. | ||||
5091 | unsigned NestedLoopCount = CheckOpenMPLoop( | ||||
5092 | OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), | ||||
5093 | AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); | ||||
Alexey Bataev | abfc069 | 2014-06-25 06:52:00 +0000 | [diff] [blame] | 5094 | if (NestedLoopCount == 0) |
Alexey Bataev | 1b59ab5 | 2014-02-27 08:29:12 +0000 | [diff] [blame] | 5095 | return StmtError(); |
Alexey Bataev | 1b59ab5 | 2014-02-27 08:29:12 +0000 | [diff] [blame] | 5096 | |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 5097 | assert((CurContext->isDependentContext() || B.builtAll()) && |
5098 | "omp simd loop exprs were not built"); | ||||
5099 | |||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 5100 | if (!CurContext->isDependentContext()) { |
5101 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
5102 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5103 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 5104 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 5105 | B.NumIterations, *this, CurScope, |
5106 | DSAStack)) | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 5107 | return StmtError(); |
5108 | } | ||||
5109 | } | ||||
5110 | |||||
Kelvin Li | c560949 | 2016-07-15 04:39:07 +0000 | [diff] [blame] | 5111 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 5112 | return StmtError(); |
5113 | |||||
Alexey Bataev | 1b59ab5 | 2014-02-27 08:29:12 +0000 | [diff] [blame] | 5114 | getCurFunction()->setHasBranchProtectedScope(); |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5115 | return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, |
5116 | Clauses, AStmt, B); | ||||
Alexey Bataev | 1b59ab5 | 2014-02-27 08:29:12 +0000 | [diff] [blame] | 5117 | } |
5118 | |||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5119 | StmtResult Sema::ActOnOpenMPForDirective( |
5120 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
5121 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 5122 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5123 | if (!AStmt) |
5124 | return StmtError(); | ||||
5125 | |||||
5126 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5127 | OMPLoopDirective::HelperExprs B; |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5128 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
5129 | // define the nested loops number. | ||||
5130 | unsigned NestedLoopCount = CheckOpenMPLoop( | ||||
5131 | OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), | ||||
5132 | AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); | ||||
Alexey Bataev | abfc069 | 2014-06-25 06:52:00 +0000 | [diff] [blame] | 5133 | if (NestedLoopCount == 0) |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 5134 | return StmtError(); |
5135 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 5136 | assert((CurContext->isDependentContext() || B.builtAll()) && |
5137 | "omp for loop exprs were not built"); | ||||
5138 | |||||
Alexey Bataev | 54acd40 | 2015-08-04 11:18:19 +0000 | [diff] [blame] | 5139 | if (!CurContext->isDependentContext()) { |
5140 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
5141 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5142 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Alexey Bataev | 54acd40 | 2015-08-04 11:18:19 +0000 | [diff] [blame] | 5143 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 5144 | B.NumIterations, *this, CurScope, |
5145 | DSAStack)) | ||||
Alexey Bataev | 54acd40 | 2015-08-04 11:18:19 +0000 | [diff] [blame] | 5146 | return StmtError(); |
5147 | } | ||||
5148 | } | ||||
5149 | |||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 5150 | getCurFunction()->setHasBranchProtectedScope(); |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5151 | return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, |
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5152 | Clauses, AStmt, B, DSAStack->isCancelRegion()); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 5153 | } |
5154 | |||||
Alexander Musman | f82886e | 2014-09-18 05:12:34 +0000 | [diff] [blame] | 5155 | StmtResult Sema::ActOnOpenMPForSimdDirective( |
5156 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
5157 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 5158 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5159 | if (!AStmt) |
5160 | return StmtError(); | ||||
5161 | |||||
5162 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5163 | OMPLoopDirective::HelperExprs B; |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5164 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
5165 | // define the nested loops number. | ||||
Alexander Musman | f82886e | 2014-09-18 05:12:34 +0000 | [diff] [blame] | 5166 | unsigned NestedLoopCount = |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5167 | CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), |
5168 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, | ||||
5169 | VarsWithImplicitDSA, B); | ||||
Alexander Musman | f82886e | 2014-09-18 05:12:34 +0000 | [diff] [blame] | 5170 | if (NestedLoopCount == 0) |
5171 | return StmtError(); | ||||
5172 | |||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5173 | assert((CurContext->isDependentContext() || B.builtAll()) && |
5174 | "omp for simd loop exprs were not built"); | ||||
5175 | |||||
Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 5176 | if (!CurContext->isDependentContext()) { |
5177 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
5178 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5179 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 5180 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 5181 | B.NumIterations, *this, CurScope, |
5182 | DSAStack)) | ||||
Alexey Bataev | 58e5bdb | 2015-06-18 04:45:29 +0000 | [diff] [blame] | 5183 | return StmtError(); |
5184 | } | ||||
5185 | } | ||||
5186 | |||||
Kelvin Li | c560949 | 2016-07-15 04:39:07 +0000 | [diff] [blame] | 5187 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 5188 | return StmtError(); |
5189 | |||||
Alexander Musman | f82886e | 2014-09-18 05:12:34 +0000 | [diff] [blame] | 5190 | getCurFunction()->setHasBranchProtectedScope(); |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5191 | return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, |
5192 | Clauses, AStmt, B); | ||||
Alexander Musman | f82886e | 2014-09-18 05:12:34 +0000 | [diff] [blame] | 5193 | } |
5194 | |||||
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 5195 | StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, |
5196 | Stmt *AStmt, | ||||
5197 | SourceLocation StartLoc, | ||||
5198 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5199 | if (!AStmt) |
5200 | return StmtError(); | ||||
5201 | |||||
5202 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 5203 | auto BaseStmt = AStmt; |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5204 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) |
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 5205 | BaseStmt = CS->getCapturedStmt(); |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5206 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { |
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 5207 | auto S = C->children(); |
Benjamin Kramer | 5733e35 | 2015-07-18 17:09:36 +0000 | [diff] [blame] | 5208 | if (S.begin() == S.end()) |
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 5209 | return StmtError(); |
5210 | // All associated statements must be '#pragma omp section' except for | ||||
5211 | // the first one. | ||||
Benjamin Kramer | 5733e35 | 2015-07-18 17:09:36 +0000 | [diff] [blame] | 5212 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { |
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 5213 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { |
5214 | if (SectionStmt) | ||||
5215 | Diag(SectionStmt->getLocStart(), | ||||
5216 | diag::err_omp_sections_substmt_not_section); | ||||
5217 | return StmtError(); | ||||
5218 | } | ||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5219 | cast<OMPSectionDirective>(SectionStmt) |
5220 | ->setHasCancel(DSAStack->isCancelRegion()); | ||||
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 5221 | } |
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 5222 | } else { |
5223 | Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); | ||||
5224 | return StmtError(); | ||||
5225 | } | ||||
5226 | |||||
5227 | getCurFunction()->setHasBranchProtectedScope(); | ||||
5228 | |||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5229 | return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
5230 | DSAStack->isCancelRegion()); | ||||
Alexey Bataev | d3f8dd2 | 2014-06-25 11:44:49 +0000 | [diff] [blame] | 5231 | } |
5232 | |||||
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 5233 | StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, |
5234 | SourceLocation StartLoc, | ||||
5235 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5236 | if (!AStmt) |
5237 | return StmtError(); | ||||
5238 | |||||
5239 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 5240 | |
5241 | getCurFunction()->setHasBranchProtectedScope(); | ||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5242 | DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); |
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 5243 | |
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5244 | return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, |
5245 | DSAStack->isCancelRegion()); | ||||
Alexey Bataev | 1e0498a | 2014-06-26 08:21:58 +0000 | [diff] [blame] | 5246 | } |
5247 | |||||
Alexey Bataev | d1e40fb | 2014-06-26 12:05:45 +0000 | [diff] [blame] | 5248 | StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, |
5249 | Stmt *AStmt, | ||||
5250 | SourceLocation StartLoc, | ||||
5251 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5252 | if (!AStmt) |
5253 | return StmtError(); | ||||
5254 | |||||
5255 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexey Bataev | 74a05c9 | 2014-07-15 02:55:09 +0000 | [diff] [blame] | 5256 | |
Alexey Bataev | d1e40fb | 2014-06-26 12:05:45 +0000 | [diff] [blame] | 5257 | getCurFunction()->setHasBranchProtectedScope(); |
Alexey Bataev | 74a05c9 | 2014-07-15 02:55:09 +0000 | [diff] [blame] | 5258 | |
Alexey Bataev | 3255bf3 | 2015-01-19 05:20:46 +0000 | [diff] [blame] | 5259 | // OpenMP [2.7.3, single Construct, Restrictions] |
5260 | // The copyprivate clause must not be used with the nowait clause. | ||||
5261 | OMPClause *Nowait = nullptr; | ||||
5262 | OMPClause *Copyprivate = nullptr; | ||||
5263 | for (auto *Clause : Clauses) { | ||||
5264 | if (Clause->getClauseKind() == OMPC_nowait) | ||||
5265 | Nowait = Clause; | ||||
5266 | else if (Clause->getClauseKind() == OMPC_copyprivate) | ||||
5267 | Copyprivate = Clause; | ||||
5268 | if (Copyprivate && Nowait) { | ||||
5269 | Diag(Copyprivate->getLocStart(), | ||||
5270 | diag::err_omp_single_copyprivate_with_nowait); | ||||
5271 | Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); | ||||
5272 | return StmtError(); | ||||
5273 | } | ||||
5274 | } | ||||
5275 | |||||
Alexey Bataev | d1e40fb | 2014-06-26 12:05:45 +0000 | [diff] [blame] | 5276 | return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); |
5277 | } | ||||
5278 | |||||
Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 5279 | StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, |
5280 | SourceLocation StartLoc, | ||||
5281 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5282 | if (!AStmt) |
5283 | return StmtError(); | ||||
5284 | |||||
5285 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexander Musman | 80c2289 | 2014-07-17 08:54:58 +0000 | [diff] [blame] | 5286 | |
5287 | getCurFunction()->setHasBranchProtectedScope(); | ||||
5288 | |||||
5289 | return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); | ||||
5290 | } | ||||
5291 | |||||
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 5292 | StmtResult Sema::ActOnOpenMPCriticalDirective( |
5293 | const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, | ||||
5294 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5295 | if (!AStmt) |
5296 | return StmtError(); | ||||
5297 | |||||
5298 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 5299 | |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 5300 | bool ErrorFound = false; |
5301 | llvm::APSInt Hint; | ||||
5302 | SourceLocation HintLoc; | ||||
5303 | bool DependentHint = false; | ||||
5304 | for (auto *C : Clauses) { | ||||
5305 | if (C->getClauseKind() == OMPC_hint) { | ||||
5306 | if (!DirName.getName()) { | ||||
5307 | Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); | ||||
5308 | ErrorFound = true; | ||||
5309 | } | ||||
5310 | Expr *E = cast<OMPHintClause>(C)->getHint(); | ||||
5311 | if (E->isTypeDependent() || E->isValueDependent() || | ||||
5312 | E->isInstantiationDependent()) | ||||
5313 | DependentHint = true; | ||||
5314 | else { | ||||
5315 | Hint = E->EvaluateKnownConstInt(Context); | ||||
5316 | HintLoc = C->getLocStart(); | ||||
5317 | } | ||||
5318 | } | ||||
5319 | } | ||||
5320 | if (ErrorFound) | ||||
5321 | return StmtError(); | ||||
5322 | auto Pair = DSAStack->getCriticalWithHint(DirName); | ||||
5323 | if (Pair.first && DirName.getName() && !DependentHint) { | ||||
5324 | if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { | ||||
5325 | Diag(StartLoc, diag::err_omp_critical_with_hint); | ||||
5326 | if (HintLoc.isValid()) { | ||||
5327 | Diag(HintLoc, diag::note_omp_critical_hint_here) | ||||
5328 | << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); | ||||
5329 | } else | ||||
5330 | Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; | ||||
5331 | if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { | ||||
5332 | Diag(C->getLocStart(), diag::note_omp_critical_hint_here) | ||||
5333 | << 1 | ||||
5334 | << C->getHint()->EvaluateKnownConstInt(Context).toString( | ||||
5335 | /*Radix=*/10, /*Signed=*/false); | ||||
5336 | } else | ||||
5337 | Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; | ||||
5338 | } | ||||
5339 | } | ||||
5340 | |||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 5341 | getCurFunction()->setHasBranchProtectedScope(); |
5342 | |||||
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 5343 | auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, |
5344 | Clauses, AStmt); | ||||
5345 | if (!Pair.first && DirName.getName() && !DependentHint) | ||||
5346 | DSAStack->addCriticalWithHint(Dir, Hint); | ||||
5347 | return Dir; | ||||
Alexander Musman | d9ed09f | 2014-07-21 09:42:05 +0000 | [diff] [blame] | 5348 | } |
5349 | |||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5350 | StmtResult Sema::ActOnOpenMPParallelForDirective( |
5351 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
5352 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 5353 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5354 | if (!AStmt) |
5355 | return StmtError(); | ||||
5356 | |||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5357 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); |
5358 | // 1.2.2 OpenMP Language Terminology | ||||
5359 | // Structured block - An executable statement with a single entry at the | ||||
5360 | // top and a single exit at the bottom. | ||||
5361 | // The point of exit cannot be a branch out of the structured block. | ||||
5362 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
5363 | CS->getCapturedDecl()->setNothrow(); | ||||
5364 | |||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5365 | OMPLoopDirective::HelperExprs B; |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5366 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
5367 | // define the nested loops number. | ||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5368 | unsigned NestedLoopCount = |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5369 | CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), |
5370 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, | ||||
5371 | VarsWithImplicitDSA, B); | ||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5372 | if (NestedLoopCount == 0) |
5373 | return StmtError(); | ||||
5374 | |||||
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 5375 | assert((CurContext->isDependentContext() || B.builtAll()) && |
5376 | "omp parallel for loop exprs were not built"); | ||||
5377 | |||||
Alexey Bataev | 54acd40 | 2015-08-04 11:18:19 +0000 | [diff] [blame] | 5378 | if (!CurContext->isDependentContext()) { |
5379 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
5380 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5381 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Alexey Bataev | 54acd40 | 2015-08-04 11:18:19 +0000 | [diff] [blame] | 5382 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 5383 | B.NumIterations, *this, CurScope, |
5384 | DSAStack)) | ||||
Alexey Bataev | 54acd40 | 2015-08-04 11:18:19 +0000 | [diff] [blame] | 5385 | return StmtError(); |
5386 | } | ||||
5387 | } | ||||
5388 | |||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5389 | getCurFunction()->setHasBranchProtectedScope(); |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5390 | return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, |
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5391 | NestedLoopCount, Clauses, AStmt, B, |
5392 | DSAStack->isCancelRegion()); | ||||
Alexey Bataev | 4acb859 | 2014-07-07 13:01:15 +0000 | [diff] [blame] | 5393 | } |
5394 | |||||
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 5395 | StmtResult Sema::ActOnOpenMPParallelForSimdDirective( |
5396 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
5397 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 5398 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5399 | if (!AStmt) |
5400 | return StmtError(); | ||||
5401 | |||||
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 5402 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); |
5403 | // 1.2.2 OpenMP Language Terminology | ||||
5404 | // Structured block - An executable statement with a single entry at the | ||||
5405 | // top and a single exit at the bottom. | ||||
5406 | // The point of exit cannot be a branch out of the structured block. | ||||
5407 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
5408 | CS->getCapturedDecl()->setNothrow(); | ||||
5409 | |||||
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5410 | OMPLoopDirective::HelperExprs B; |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5411 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
5412 | // define the nested loops number. | ||||
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 5413 | unsigned NestedLoopCount = |
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 5414 | CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), |
5415 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, | ||||
5416 | VarsWithImplicitDSA, B); | ||||
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 5417 | if (NestedLoopCount == 0) |
5418 | return StmtError(); | ||||
5419 | |||||
Alexey Bataev | 3b5b5c4 | 2015-06-18 10:10:12 +0000 | [diff] [blame] | 5420 | if (!CurContext->isDependentContext()) { |
5421 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
5422 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5423 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Alexey Bataev | 3b5b5c4 | 2015-06-18 10:10:12 +0000 | [diff] [blame] | 5424 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 5425 | B.NumIterations, *this, CurScope, |
5426 | DSAStack)) | ||||
Alexey Bataev | 3b5b5c4 | 2015-06-18 10:10:12 +0000 | [diff] [blame] | 5427 | return StmtError(); |
5428 | } | ||||
5429 | } | ||||
5430 | |||||
Kelvin Li | c560949 | 2016-07-15 04:39:07 +0000 | [diff] [blame] | 5431 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 5432 | return StmtError(); |
5433 | |||||
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 5434 | getCurFunction()->setHasBranchProtectedScope(); |
Alexander Musman | a5f070a | 2014-10-01 06:03:56 +0000 | [diff] [blame] | 5435 | return OMPParallelForSimdDirective::Create( |
Alexander Musman | c638868 | 2014-12-15 07:07:06 +0000 | [diff] [blame] | 5436 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
Alexander Musman | e4e893b | 2014-09-23 09:33:00 +0000 | [diff] [blame] | 5437 | } |
5438 | |||||
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5439 | StmtResult |
5440 | Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, | ||||
5441 | Stmt *AStmt, SourceLocation StartLoc, | ||||
5442 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5443 | if (!AStmt) |
5444 | return StmtError(); | ||||
5445 | |||||
5446 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5447 | auto BaseStmt = AStmt; |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5448 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) |
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5449 | BaseStmt = CS->getCapturedStmt(); |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5450 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { |
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5451 | auto S = C->children(); |
Benjamin Kramer | 5733e35 | 2015-07-18 17:09:36 +0000 | [diff] [blame] | 5452 | if (S.begin() == S.end()) |
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5453 | return StmtError(); |
5454 | // All associated statements must be '#pragma omp section' except for | ||||
5455 | // the first one. | ||||
Benjamin Kramer | 5733e35 | 2015-07-18 17:09:36 +0000 | [diff] [blame] | 5456 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { |
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5457 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { |
5458 | if (SectionStmt) | ||||
5459 | Diag(SectionStmt->getLocStart(), | ||||
5460 | diag::err_omp_parallel_sections_substmt_not_section); | ||||
5461 | return StmtError(); | ||||
5462 | } | ||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5463 | cast<OMPSectionDirective>(SectionStmt) |
5464 | ->setHasCancel(DSAStack->isCancelRegion()); | ||||
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5465 | } |
5466 | } else { | ||||
5467 | Diag(AStmt->getLocStart(), | ||||
5468 | diag::err_omp_parallel_sections_not_compound_stmt); | ||||
5469 | return StmtError(); | ||||
5470 | } | ||||
5471 | |||||
5472 | getCurFunction()->setHasBranchProtectedScope(); | ||||
5473 | |||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5474 | return OMPParallelSectionsDirective::Create( |
5475 | Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); | ||||
Alexey Bataev | 84d0b3e | 2014-07-08 08:12:03 +0000 | [diff] [blame] | 5476 | } |
5477 | |||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 5478 | StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, |
5479 | Stmt *AStmt, SourceLocation StartLoc, | ||||
5480 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5481 | if (!AStmt) |
5482 | return StmtError(); | ||||
5483 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5484 | auto *CS = cast<CapturedStmt>(AStmt); |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 5485 | // 1.2.2 OpenMP Language Terminology |
5486 | // Structured block - An executable statement with a single entry at the | ||||
5487 | // top and a single exit at the bottom. | ||||
5488 | // The point of exit cannot be a branch out of the structured block. | ||||
5489 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
5490 | CS->getCapturedDecl()->setNothrow(); | ||||
5491 | |||||
5492 | getCurFunction()->setHasBranchProtectedScope(); | ||||
5493 | |||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 5494 | return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
5495 | DSAStack->isCancelRegion()); | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 5496 | } |
5497 | |||||
Alexey Bataev | 68446b7 | 2014-07-18 07:47:19 +0000 | [diff] [blame] | 5498 | StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, |
5499 | SourceLocation EndLoc) { | ||||
5500 | return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); | ||||
5501 | } | ||||
5502 | |||||
Alexey Bataev | 4d1dfea | 2014-07-18 09:11:51 +0000 | [diff] [blame] | 5503 | StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, |
5504 | SourceLocation EndLoc) { | ||||
5505 | return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); | ||||
5506 | } | ||||
5507 | |||||
Alexey Bataev | 2df347a | 2014-07-18 10:17:07 +0000 | [diff] [blame] | 5508 | StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, |
5509 | SourceLocation EndLoc) { | ||||
5510 | return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); | ||||
5511 | } | ||||
5512 | |||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 5513 | StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, |
5514 | Stmt *AStmt, | ||||
Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 5515 | SourceLocation StartLoc, |
5516 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5517 | if (!AStmt) |
5518 | return StmtError(); | ||||
5519 | |||||
5520 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 5521 | |
5522 | getCurFunction()->setHasBranchProtectedScope(); | ||||
5523 | |||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 5524 | return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, |
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 5525 | AStmt, |
5526 | DSAStack->getTaskgroupReductionRef()); | ||||
Alexey Bataev | c30dd2d | 2015-06-18 12:14:09 +0000 | [diff] [blame] | 5527 | } |
5528 | |||||
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 5529 | StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, |
5530 | SourceLocation StartLoc, | ||||
5531 | SourceLocation EndLoc) { | ||||
5532 | assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); | ||||
5533 | return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); | ||||
5534 | } | ||||
5535 | |||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 5536 | StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, |
5537 | Stmt *AStmt, | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 5538 | SourceLocation StartLoc, |
5539 | SourceLocation EndLoc) { | ||||
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 5540 | OMPClause *DependFound = nullptr; |
5541 | OMPClause *DependSourceClause = nullptr; | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 5542 | OMPClause *DependSinkClause = nullptr; |
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 5543 | bool ErrorFound = false; |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 5544 | OMPThreadsClause *TC = nullptr; |
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 5545 | OMPSIMDClause *SC = nullptr; |
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 5546 | for (auto *C : Clauses) { |
5547 | if (auto *DC = dyn_cast<OMPDependClause>(C)) { | ||||
5548 | DependFound = C; | ||||
5549 | if (DC->getDependencyKind() == OMPC_DEPEND_source) { | ||||
5550 | if (DependSourceClause) { | ||||
5551 | Diag(C->getLocStart(), diag::err_omp_more_one_clause) | ||||
5552 | << getOpenMPDirectiveName(OMPD_ordered) | ||||
5553 | << getOpenMPClauseName(OMPC_depend) << 2; | ||||
5554 | ErrorFound = true; | ||||
5555 | } else | ||||
5556 | DependSourceClause = C; | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 5557 | if (DependSinkClause) { |
5558 | Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) | ||||
5559 | << 0; | ||||
5560 | ErrorFound = true; | ||||
5561 | } | ||||
5562 | } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { | ||||
5563 | if (DependSourceClause) { | ||||
5564 | Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) | ||||
5565 | << 1; | ||||
5566 | ErrorFound = true; | ||||
5567 | } | ||||
5568 | DependSinkClause = C; | ||||
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 5569 | } |
5570 | } else if (C->getClauseKind() == OMPC_threads) | ||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 5571 | TC = cast<OMPThreadsClause>(C); |
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 5572 | else if (C->getClauseKind() == OMPC_simd) |
5573 | SC = cast<OMPSIMDClause>(C); | ||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 5574 | } |
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 5575 | if (!ErrorFound && !SC && |
5576 | isOpenMPSimdDirective(DSAStack->getParentDirective())) { | ||||
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 5577 | // OpenMP [2.8.1,simd Construct, Restrictions] |
5578 | // An ordered construct with the simd clause is the only OpenMP construct | ||||
5579 | // that can appear in the simd region. | ||||
5580 | Diag(StartLoc, diag::err_omp_prohibited_region_simd); | ||||
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 5581 | ErrorFound = true; |
5582 | } else if (DependFound && (TC || SC)) { | ||||
5583 | Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) | ||||
5584 | << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); | ||||
5585 | ErrorFound = true; | ||||
5586 | } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { | ||||
5587 | Diag(DependFound->getLocStart(), | ||||
5588 | diag::err_omp_ordered_directive_without_param); | ||||
5589 | ErrorFound = true; | ||||
5590 | } else if (TC || Clauses.empty()) { | ||||
5591 | if (auto *Param = DSAStack->getParentOrderedRegionParam()) { | ||||
5592 | SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; | ||||
5593 | Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) | ||||
5594 | << (TC != nullptr); | ||||
5595 | Diag(Param->getLocStart(), diag::note_omp_ordered_param); | ||||
5596 | ErrorFound = true; | ||||
5597 | } | ||||
5598 | } | ||||
5599 | if ((!AStmt && !DependFound) || ErrorFound) | ||||
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 5600 | return StmtError(); |
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 5601 | |
5602 | if (AStmt) { | ||||
5603 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
5604 | |||||
5605 | getCurFunction()->setHasBranchProtectedScope(); | ||||
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 5606 | } |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 5607 | |
5608 | return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||
Alexey Bataev | 9fb6e64 | 2014-07-22 06:45:04 +0000 | [diff] [blame] | 5609 | } |
5610 | |||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5611 | namespace { |
5612 | /// \brief Helper class for checking expression in 'omp atomic [update]' | ||||
5613 | /// construct. | ||||
5614 | class OpenMPAtomicUpdateChecker { | ||||
5615 | /// \brief Error results for atomic update expressions. | ||||
5616 | enum ExprAnalysisErrorCode { | ||||
5617 | /// \brief A statement is not an expression statement. | ||||
5618 | NotAnExpression, | ||||
5619 | /// \brief Expression is not builtin binary or unary operation. | ||||
5620 | NotABinaryOrUnaryExpression, | ||||
5621 | /// \brief Unary operation is not post-/pre- increment/decrement operation. | ||||
5622 | NotAnUnaryIncDecExpression, | ||||
5623 | /// \brief An expression is not of scalar type. | ||||
5624 | NotAScalarType, | ||||
5625 | /// \brief A binary operation is not an assignment operation. | ||||
5626 | NotAnAssignmentOp, | ||||
5627 | /// \brief RHS part of the binary operation is not a binary expression. | ||||
5628 | NotABinaryExpression, | ||||
5629 | /// \brief RHS part is not additive/multiplicative/shift/biwise binary | ||||
5630 | /// expression. | ||||
5631 | NotABinaryOperator, | ||||
5632 | /// \brief RHS binary operation does not have reference to the updated LHS | ||||
5633 | /// part. | ||||
5634 | NotAnUpdateExpression, | ||||
5635 | /// \brief No errors is found. | ||||
5636 | NoError | ||||
5637 | }; | ||||
5638 | /// \brief Reference to Sema. | ||||
5639 | Sema &SemaRef; | ||||
5640 | /// \brief A location for note diagnostics (when error is found). | ||||
5641 | SourceLocation NoteLoc; | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5642 | /// \brief 'x' lvalue part of the source atomic expression. |
5643 | Expr *X; | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5644 | /// \brief 'expr' rvalue part of the source atomic expression. |
5645 | Expr *E; | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5646 | /// \brief Helper expression of the form |
5647 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | ||||
5648 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | ||||
5649 | Expr *UpdateExpr; | ||||
5650 | /// \brief Is 'x' a LHS in a RHS part of full update expression. It is | ||||
5651 | /// important for non-associative operations. | ||||
5652 | bool IsXLHSInRHSPart; | ||||
5653 | BinaryOperatorKind Op; | ||||
5654 | SourceLocation OpLoc; | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5655 | /// \brief true if the source expression is a postfix unary operation, false |
5656 | /// if it is a prefix unary operation. | ||||
5657 | bool IsPostfixUpdate; | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5658 | |
5659 | public: | ||||
5660 | OpenMPAtomicUpdateChecker(Sema &SemaRef) | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5661 | : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5662 | IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5663 | /// \brief Check specified statement that it is suitable for 'atomic update' |
5664 | /// constructs and extract 'x', 'expr' and Operation from the original | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5665 | /// expression. If DiagId and NoteId == 0, then only check is performed |
5666 | /// without error notification. | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5667 | /// \param DiagId Diagnostic which should be emitted if error is found. |
5668 | /// \param NoteId Diagnostic note for the main error message. | ||||
5669 | /// \return true if statement is not an update expression, false otherwise. | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5670 | bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5671 | /// \brief Return the 'x' lvalue part of the source atomic expression. |
5672 | Expr *getX() const { return X; } | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5673 | /// \brief Return the 'expr' rvalue part of the source atomic expression. |
5674 | Expr *getExpr() const { return E; } | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5675 | /// \brief Return the update expression used in calculation of the updated |
5676 | /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | ||||
5677 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | ||||
5678 | Expr *getUpdateExpr() const { return UpdateExpr; } | ||||
5679 | /// \brief Return true if 'x' is LHS in RHS part of full update expression, | ||||
5680 | /// false otherwise. | ||||
5681 | bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } | ||||
5682 | |||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5683 | /// \brief true if the source expression is a postfix unary operation, false |
5684 | /// if it is a prefix unary operation. | ||||
5685 | bool isPostfixUpdate() const { return IsPostfixUpdate; } | ||||
5686 | |||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5687 | private: |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5688 | bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, |
5689 | unsigned NoteId = 0); | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5690 | }; |
5691 | } // namespace | ||||
5692 | |||||
5693 | bool OpenMPAtomicUpdateChecker::checkBinaryOperation( | ||||
5694 | BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { | ||||
5695 | ExprAnalysisErrorCode ErrorFound = NoError; | ||||
5696 | SourceLocation ErrorLoc, NoteLoc; | ||||
5697 | SourceRange ErrorRange, NoteRange; | ||||
5698 | // Allowed constructs are: | ||||
5699 | // x = x binop expr; | ||||
5700 | // x = expr binop x; | ||||
5701 | if (AtomicBinOp->getOpcode() == BO_Assign) { | ||||
5702 | X = AtomicBinOp->getLHS(); | ||||
5703 | if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( | ||||
5704 | AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { | ||||
5705 | if (AtomicInnerBinOp->isMultiplicativeOp() || | ||||
5706 | AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || | ||||
5707 | AtomicInnerBinOp->isBitwiseOp()) { | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5708 | Op = AtomicInnerBinOp->getOpcode(); |
5709 | OpLoc = AtomicInnerBinOp->getOperatorLoc(); | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5710 | auto *LHS = AtomicInnerBinOp->getLHS(); |
5711 | auto *RHS = AtomicInnerBinOp->getRHS(); | ||||
5712 | llvm::FoldingSetNodeID XId, LHSId, RHSId; | ||||
5713 | X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), | ||||
5714 | /*Canonical=*/true); | ||||
5715 | LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), | ||||
5716 | /*Canonical=*/true); | ||||
5717 | RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), | ||||
5718 | /*Canonical=*/true); | ||||
5719 | if (XId == LHSId) { | ||||
5720 | E = RHS; | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5721 | IsXLHSInRHSPart = true; |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5722 | } else if (XId == RHSId) { |
5723 | E = LHS; | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5724 | IsXLHSInRHSPart = false; |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5725 | } else { |
5726 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | ||||
5727 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | ||||
5728 | NoteLoc = X->getExprLoc(); | ||||
5729 | NoteRange = X->getSourceRange(); | ||||
5730 | ErrorFound = NotAnUpdateExpression; | ||||
5731 | } | ||||
5732 | } else { | ||||
5733 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | ||||
5734 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | ||||
5735 | NoteLoc = AtomicInnerBinOp->getOperatorLoc(); | ||||
5736 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||
5737 | ErrorFound = NotABinaryOperator; | ||||
5738 | } | ||||
5739 | } else { | ||||
5740 | NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); | ||||
5741 | NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); | ||||
5742 | ErrorFound = NotABinaryExpression; | ||||
5743 | } | ||||
5744 | } else { | ||||
5745 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||
5746 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||
5747 | NoteLoc = AtomicBinOp->getOperatorLoc(); | ||||
5748 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||
5749 | ErrorFound = NotAnAssignmentOp; | ||||
5750 | } | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5751 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5752 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; |
5753 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | ||||
5754 | return true; | ||||
5755 | } else if (SemaRef.CurContext->isDependentContext()) | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5756 | E = X = UpdateExpr = nullptr; |
Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 5757 | return ErrorFound != NoError; |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5758 | } |
5759 | |||||
5760 | bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, | ||||
5761 | unsigned NoteId) { | ||||
5762 | ExprAnalysisErrorCode ErrorFound = NoError; | ||||
5763 | SourceLocation ErrorLoc, NoteLoc; | ||||
5764 | SourceRange ErrorRange, NoteRange; | ||||
5765 | // Allowed constructs are: | ||||
5766 | // x++; | ||||
5767 | // x--; | ||||
5768 | // ++x; | ||||
5769 | // --x; | ||||
5770 | // x binop= expr; | ||||
5771 | // x = x binop expr; | ||||
5772 | // x = expr binop x; | ||||
5773 | if (auto *AtomicBody = dyn_cast<Expr>(S)) { | ||||
5774 | AtomicBody = AtomicBody->IgnoreParenImpCasts(); | ||||
5775 | if (AtomicBody->getType()->isScalarType() || | ||||
5776 | AtomicBody->isInstantiationDependent()) { | ||||
5777 | if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( | ||||
5778 | AtomicBody->IgnoreParenImpCasts())) { | ||||
5779 | // Check for Compound Assignment Operation | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5780 | Op = BinaryOperator::getOpForCompoundAssignment( |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5781 | AtomicCompAssignOp->getOpcode()); |
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5782 | OpLoc = AtomicCompAssignOp->getOperatorLoc(); |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5783 | E = AtomicCompAssignOp->getRHS(); |
Kelvin Li | 4f161cf | 2016-07-20 19:41:17 +0000 | [diff] [blame] | 5784 | X = AtomicCompAssignOp->getLHS()->IgnoreParens(); |
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5785 | IsXLHSInRHSPart = true; |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5786 | } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( |
5787 | AtomicBody->IgnoreParenImpCasts())) { | ||||
5788 | // Check for Binary Operation | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5789 | if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) |
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5790 | return true; |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5791 | } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( |
5792 | AtomicBody->IgnoreParenImpCasts())) { | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5793 | // Check for Unary Operation |
5794 | if (AtomicUnaryOp->isIncrementDecrementOp()) { | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5795 | IsPostfixUpdate = AtomicUnaryOp->isPostfix(); |
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5796 | Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; |
5797 | OpLoc = AtomicUnaryOp->getOperatorLoc(); | ||||
Kelvin Li | 4f161cf | 2016-07-20 19:41:17 +0000 | [diff] [blame] | 5798 | X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); |
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5799 | E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); |
5800 | IsXLHSInRHSPart = true; | ||||
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5801 | } else { |
5802 | ErrorFound = NotAnUnaryIncDecExpression; | ||||
5803 | ErrorLoc = AtomicUnaryOp->getExprLoc(); | ||||
5804 | ErrorRange = AtomicUnaryOp->getSourceRange(); | ||||
5805 | NoteLoc = AtomicUnaryOp->getOperatorLoc(); | ||||
5806 | NoteRange = SourceRange(NoteLoc, NoteLoc); | ||||
5807 | } | ||||
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 5808 | } else if (!AtomicBody->isInstantiationDependent()) { |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5809 | ErrorFound = NotABinaryOrUnaryExpression; |
5810 | NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); | ||||
5811 | NoteRange = ErrorRange = AtomicBody->getSourceRange(); | ||||
5812 | } | ||||
5813 | } else { | ||||
5814 | ErrorFound = NotAScalarType; | ||||
5815 | NoteLoc = ErrorLoc = AtomicBody->getLocStart(); | ||||
5816 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||
5817 | } | ||||
5818 | } else { | ||||
5819 | ErrorFound = NotAnExpression; | ||||
5820 | NoteLoc = ErrorLoc = S->getLocStart(); | ||||
5821 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||
5822 | } | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5823 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5824 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; |
5825 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | ||||
5826 | return true; | ||||
5827 | } else if (SemaRef.CurContext->isDependentContext()) | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5828 | E = X = UpdateExpr = nullptr; |
Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 5829 | if (ErrorFound == NoError && E && X) { |
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5830 | // Build an update expression of form 'OpaqueValueExpr(x) binop |
5831 | // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop | ||||
5832 | // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. | ||||
5833 | auto *OVEX = new (SemaRef.getASTContext()) | ||||
5834 | OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); | ||||
5835 | auto *OVEExpr = new (SemaRef.getASTContext()) | ||||
5836 | OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); | ||||
5837 | auto Update = | ||||
5838 | SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, | ||||
5839 | IsXLHSInRHSPart ? OVEExpr : OVEX); | ||||
5840 | if (Update.isInvalid()) | ||||
5841 | return true; | ||||
5842 | Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), | ||||
5843 | Sema::AA_Casting); | ||||
5844 | if (Update.isInvalid()) | ||||
5845 | return true; | ||||
5846 | UpdateExpr = Update.get(); | ||||
5847 | } | ||||
Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 5848 | return ErrorFound != NoError; |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 5849 | } |
5850 | |||||
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 5851 | StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, |
5852 | Stmt *AStmt, | ||||
5853 | SourceLocation StartLoc, | ||||
5854 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 5855 | if (!AStmt) |
5856 | return StmtError(); | ||||
5857 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5858 | auto *CS = cast<CapturedStmt>(AStmt); |
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 5859 | // 1.2.2 OpenMP Language Terminology |
5860 | // Structured block - An executable statement with a single entry at the | ||||
5861 | // top and a single exit at the bottom. | ||||
5862 | // The point of exit cannot be a branch out of the structured block. | ||||
5863 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 5864 | OpenMPClauseKind AtomicKind = OMPC_unknown; |
5865 | SourceLocation AtomicKindLoc; | ||||
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 5866 | for (auto *C : Clauses) { |
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 5867 | if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || |
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 5868 | C->getClauseKind() == OMPC_update || |
5869 | C->getClauseKind() == OMPC_capture) { | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 5870 | if (AtomicKind != OMPC_unknown) { |
5871 | Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) | ||||
5872 | << SourceRange(C->getLocStart(), C->getLocEnd()); | ||||
5873 | Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) | ||||
5874 | << getOpenMPClauseName(AtomicKind); | ||||
5875 | } else { | ||||
5876 | AtomicKind = C->getClauseKind(); | ||||
5877 | AtomicKindLoc = C->getLocStart(); | ||||
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 5878 | } |
5879 | } | ||||
5880 | } | ||||
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5881 | |
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 5882 | auto Body = CS->getCapturedStmt(); |
Alexey Bataev | 10fec57 | 2015-03-11 04:48:56 +0000 | [diff] [blame] | 5883 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) |
5884 | Body = EWC->getSubExpr(); | ||||
5885 | |||||
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5886 | Expr *X = nullptr; |
5887 | Expr *V = nullptr; | ||||
5888 | Expr *E = nullptr; | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 5889 | Expr *UE = nullptr; |
5890 | bool IsXLHSInRHSPart = false; | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5891 | bool IsPostfixUpdate = false; |
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5892 | // OpenMP [2.12.6, atomic Construct] |
5893 | // In the next expressions: | ||||
5894 | // * x and v (as applicable) are both l-value expressions with scalar type. | ||||
5895 | // * During the execution of an atomic region, multiple syntactic | ||||
5896 | // occurrences of x must designate the same storage location. | ||||
5897 | // * Neither of v and expr (as applicable) may access the storage location | ||||
5898 | // designated by x. | ||||
5899 | // * Neither of x and expr (as applicable) may access the storage location | ||||
5900 | // designated by v. | ||||
5901 | // * expr is an expression with scalar type. | ||||
5902 | // * binop is one of +, *, -, /, &, ^, |, <<, or >>. | ||||
5903 | // * binop, binop=, ++, and -- are not overloaded operators. | ||||
5904 | // * The expression x binop expr must be numerically equivalent to x binop | ||||
5905 | // (expr). This requirement is satisfied if the operators in expr have | ||||
5906 | // precedence greater than binop, or by using parentheses around expr or | ||||
5907 | // subexpressions of expr. | ||||
5908 | // * The expression expr binop x must be numerically equivalent to (expr) | ||||
5909 | // binop x. This requirement is satisfied if the operators in expr have | ||||
5910 | // precedence equal to or greater than binop, or by using parentheses around | ||||
5911 | // expr or subexpressions of expr. | ||||
5912 | // * For forms that allow multiple occurrences of x, the number of times | ||||
5913 | // that x is evaluated is unspecified. | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 5914 | if (AtomicKind == OMPC_read) { |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5915 | enum { |
5916 | NotAnExpression, | ||||
5917 | NotAnAssignmentOp, | ||||
5918 | NotAScalarType, | ||||
5919 | NotAnLValue, | ||||
5920 | NoError | ||||
5921 | } ErrorFound = NoError; | ||||
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5922 | SourceLocation ErrorLoc, NoteLoc; |
5923 | SourceRange ErrorRange, NoteRange; | ||||
5924 | // If clause is read: | ||||
5925 | // v = x; | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5926 | if (auto *AtomicBody = dyn_cast<Expr>(Body)) { |
5927 | auto *AtomicBinOp = | ||||
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5928 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); |
5929 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||
5930 | X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | ||||
5931 | V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); | ||||
5932 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && | ||||
5933 | (V->isInstantiationDependent() || V->getType()->isScalarType())) { | ||||
5934 | if (!X->isLValue() || !V->isLValue()) { | ||||
5935 | auto NotLValueExpr = X->isLValue() ? V : X; | ||||
5936 | ErrorFound = NotAnLValue; | ||||
5937 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||
5938 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||
5939 | NoteLoc = NotLValueExpr->getExprLoc(); | ||||
5940 | NoteRange = NotLValueExpr->getSourceRange(); | ||||
5941 | } | ||||
5942 | } else if (!X->isInstantiationDependent() || | ||||
5943 | !V->isInstantiationDependent()) { | ||||
5944 | auto NotScalarExpr = | ||||
5945 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | ||||
5946 | ? V | ||||
5947 | : X; | ||||
5948 | ErrorFound = NotAScalarType; | ||||
5949 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||
5950 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||
5951 | NoteLoc = NotScalarExpr->getExprLoc(); | ||||
5952 | NoteRange = NotScalarExpr->getSourceRange(); | ||||
5953 | } | ||||
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 5954 | } else if (!AtomicBody->isInstantiationDependent()) { |
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5955 | ErrorFound = NotAnAssignmentOp; |
5956 | ErrorLoc = AtomicBody->getExprLoc(); | ||||
5957 | ErrorRange = AtomicBody->getSourceRange(); | ||||
5958 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||
5959 | : AtomicBody->getExprLoc(); | ||||
5960 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||
5961 | : AtomicBody->getSourceRange(); | ||||
5962 | } | ||||
5963 | } else { | ||||
5964 | ErrorFound = NotAnExpression; | ||||
5965 | NoteLoc = ErrorLoc = Body->getLocStart(); | ||||
5966 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 5967 | } |
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5968 | if (ErrorFound != NoError) { |
5969 | Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) | ||||
5970 | << ErrorRange; | ||||
Alexey Bataev | f33eba6 | 2014-11-28 07:21:40 +0000 | [diff] [blame] | 5971 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound |
5972 | << NoteRange; | ||||
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 5973 | return StmtError(); |
5974 | } else if (CurContext->isDependentContext()) | ||||
5975 | V = X = nullptr; | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 5976 | } else if (AtomicKind == OMPC_write) { |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 5977 | enum { |
5978 | NotAnExpression, | ||||
5979 | NotAnAssignmentOp, | ||||
5980 | NotAScalarType, | ||||
5981 | NotAnLValue, | ||||
5982 | NoError | ||||
5983 | } ErrorFound = NoError; | ||||
Alexey Bataev | f33eba6 | 2014-11-28 07:21:40 +0000 | [diff] [blame] | 5984 | SourceLocation ErrorLoc, NoteLoc; |
5985 | SourceRange ErrorRange, NoteRange; | ||||
5986 | // If clause is write: | ||||
5987 | // x = expr; | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 5988 | if (auto *AtomicBody = dyn_cast<Expr>(Body)) { |
5989 | auto *AtomicBinOp = | ||||
Alexey Bataev | f33eba6 | 2014-11-28 07:21:40 +0000 | [diff] [blame] | 5990 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); |
5991 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||
Alexey Bataev | b832926 | 2015-02-27 06:33:30 +0000 | [diff] [blame] | 5992 | X = AtomicBinOp->getLHS(); |
5993 | E = AtomicBinOp->getRHS(); | ||||
Alexey Bataev | f33eba6 | 2014-11-28 07:21:40 +0000 | [diff] [blame] | 5994 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && |
5995 | (E->isInstantiationDependent() || E->getType()->isScalarType())) { | ||||
5996 | if (!X->isLValue()) { | ||||
5997 | ErrorFound = NotAnLValue; | ||||
5998 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||
5999 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||
6000 | NoteLoc = X->getExprLoc(); | ||||
6001 | NoteRange = X->getSourceRange(); | ||||
6002 | } | ||||
6003 | } else if (!X->isInstantiationDependent() || | ||||
6004 | !E->isInstantiationDependent()) { | ||||
6005 | auto NotScalarExpr = | ||||
6006 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | ||||
6007 | ? E | ||||
6008 | : X; | ||||
6009 | ErrorFound = NotAScalarType; | ||||
6010 | ErrorLoc = AtomicBinOp->getExprLoc(); | ||||
6011 | ErrorRange = AtomicBinOp->getSourceRange(); | ||||
6012 | NoteLoc = NotScalarExpr->getExprLoc(); | ||||
6013 | NoteRange = NotScalarExpr->getSourceRange(); | ||||
6014 | } | ||||
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 6015 | } else if (!AtomicBody->isInstantiationDependent()) { |
Alexey Bataev | f33eba6 | 2014-11-28 07:21:40 +0000 | [diff] [blame] | 6016 | ErrorFound = NotAnAssignmentOp; |
6017 | ErrorLoc = AtomicBody->getExprLoc(); | ||||
6018 | ErrorRange = AtomicBody->getSourceRange(); | ||||
6019 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||
6020 | : AtomicBody->getExprLoc(); | ||||
6021 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||
6022 | : AtomicBody->getSourceRange(); | ||||
6023 | } | ||||
6024 | } else { | ||||
6025 | ErrorFound = NotAnExpression; | ||||
6026 | NoteLoc = ErrorLoc = Body->getLocStart(); | ||||
6027 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 6028 | } |
Alexey Bataev | f33eba6 | 2014-11-28 07:21:40 +0000 | [diff] [blame] | 6029 | if (ErrorFound != NoError) { |
6030 | Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) | ||||
6031 | << ErrorRange; | ||||
6032 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound | ||||
6033 | << NoteRange; | ||||
6034 | return StmtError(); | ||||
6035 | } else if (CurContext->isDependentContext()) | ||||
6036 | E = X = nullptr; | ||||
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 6037 | } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 6038 | // If clause is update: |
6039 | // x++; | ||||
6040 | // x--; | ||||
6041 | // ++x; | ||||
6042 | // --x; | ||||
6043 | // x binop= expr; | ||||
6044 | // x = x binop expr; | ||||
6045 | // x = expr binop x; | ||||
6046 | OpenMPAtomicUpdateChecker Checker(*this); | ||||
6047 | if (Checker.checkStatement( | ||||
6048 | Body, (AtomicKind == OMPC_update) | ||||
6049 | ? diag::err_omp_atomic_update_not_expression_statement | ||||
6050 | : diag::err_omp_atomic_not_expression_statement, | ||||
6051 | diag::note_omp_atomic_update)) | ||||
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 6052 | return StmtError(); |
Alexey Bataev | 1d160b1 | 2015-03-13 12:27:31 +0000 | [diff] [blame] | 6053 | if (!CurContext->isDependentContext()) { |
6054 | E = Checker.getExpr(); | ||||
6055 | X = Checker.getX(); | ||||
Alexey Bataev | b4505a7 | 2015-03-30 05:20:59 +0000 | [diff] [blame] | 6056 | UE = Checker.getUpdateExpr(); |
6057 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 6058 | } |
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 6059 | } else if (AtomicKind == OMPC_capture) { |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6060 | enum { |
6061 | NotAnAssignmentOp, | ||||
6062 | NotACompoundStatement, | ||||
6063 | NotTwoSubstatements, | ||||
6064 | NotASpecificExpression, | ||||
6065 | NoError | ||||
6066 | } ErrorFound = NoError; | ||||
6067 | SourceLocation ErrorLoc, NoteLoc; | ||||
6068 | SourceRange ErrorRange, NoteRange; | ||||
6069 | if (auto *AtomicBody = dyn_cast<Expr>(Body)) { | ||||
6070 | // If clause is a capture: | ||||
6071 | // v = x++; | ||||
6072 | // v = x--; | ||||
6073 | // v = ++x; | ||||
6074 | // v = --x; | ||||
6075 | // v = x binop= expr; | ||||
6076 | // v = x = x binop expr; | ||||
6077 | // v = x = expr binop x; | ||||
6078 | auto *AtomicBinOp = | ||||
6079 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | ||||
6080 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | ||||
6081 | V = AtomicBinOp->getLHS(); | ||||
6082 | Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | ||||
6083 | OpenMPAtomicUpdateChecker Checker(*this); | ||||
6084 | if (Checker.checkStatement( | ||||
6085 | Body, diag::err_omp_atomic_capture_not_expression_statement, | ||||
6086 | diag::note_omp_atomic_update)) | ||||
6087 | return StmtError(); | ||||
6088 | E = Checker.getExpr(); | ||||
6089 | X = Checker.getX(); | ||||
6090 | UE = Checker.getUpdateExpr(); | ||||
6091 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||
6092 | IsPostfixUpdate = Checker.isPostfixUpdate(); | ||||
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 6093 | } else if (!AtomicBody->isInstantiationDependent()) { |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6094 | ErrorLoc = AtomicBody->getExprLoc(); |
6095 | ErrorRange = AtomicBody->getSourceRange(); | ||||
6096 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | ||||
6097 | : AtomicBody->getExprLoc(); | ||||
6098 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | ||||
6099 | : AtomicBody->getSourceRange(); | ||||
6100 | ErrorFound = NotAnAssignmentOp; | ||||
6101 | } | ||||
6102 | if (ErrorFound != NoError) { | ||||
6103 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) | ||||
6104 | << ErrorRange; | ||||
6105 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | ||||
6106 | return StmtError(); | ||||
6107 | } else if (CurContext->isDependentContext()) { | ||||
6108 | UE = V = E = X = nullptr; | ||||
6109 | } | ||||
6110 | } else { | ||||
6111 | // If clause is a capture: | ||||
6112 | // { v = x; x = expr; } | ||||
6113 | // { v = x; x++; } | ||||
6114 | // { v = x; x--; } | ||||
6115 | // { v = x; ++x; } | ||||
6116 | // { v = x; --x; } | ||||
6117 | // { v = x; x binop= expr; } | ||||
6118 | // { v = x; x = x binop expr; } | ||||
6119 | // { v = x; x = expr binop x; } | ||||
6120 | // { x++; v = x; } | ||||
6121 | // { x--; v = x; } | ||||
6122 | // { ++x; v = x; } | ||||
6123 | // { --x; v = x; } | ||||
6124 | // { x binop= expr; v = x; } | ||||
6125 | // { x = x binop expr; v = x; } | ||||
6126 | // { x = expr binop x; v = x; } | ||||
6127 | if (auto *CS = dyn_cast<CompoundStmt>(Body)) { | ||||
6128 | // Check that this is { expr1; expr2; } | ||||
6129 | if (CS->size() == 2) { | ||||
6130 | auto *First = CS->body_front(); | ||||
6131 | auto *Second = CS->body_back(); | ||||
6132 | if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) | ||||
6133 | First = EWC->getSubExpr()->IgnoreParenImpCasts(); | ||||
6134 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) | ||||
6135 | Second = EWC->getSubExpr()->IgnoreParenImpCasts(); | ||||
6136 | // Need to find what subexpression is 'v' and what is 'x'. | ||||
6137 | OpenMPAtomicUpdateChecker Checker(*this); | ||||
6138 | bool IsUpdateExprFound = !Checker.checkStatement(Second); | ||||
6139 | BinaryOperator *BinOp = nullptr; | ||||
6140 | if (IsUpdateExprFound) { | ||||
6141 | BinOp = dyn_cast<BinaryOperator>(First); | ||||
6142 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | ||||
6143 | } | ||||
6144 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | ||||
6145 | // { v = x; x++; } | ||||
6146 | // { v = x; x--; } | ||||
6147 | // { v = x; ++x; } | ||||
6148 | // { v = x; --x; } | ||||
6149 | // { v = x; x binop= expr; } | ||||
6150 | // { v = x; x = x binop expr; } | ||||
6151 | // { v = x; x = expr binop x; } | ||||
6152 | // Check that the first expression has form v = x. | ||||
6153 | auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | ||||
6154 | llvm::FoldingSetNodeID XId, PossibleXId; | ||||
6155 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | ||||
6156 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | ||||
6157 | IsUpdateExprFound = XId == PossibleXId; | ||||
6158 | if (IsUpdateExprFound) { | ||||
6159 | V = BinOp->getLHS(); | ||||
6160 | X = Checker.getX(); | ||||
6161 | E = Checker.getExpr(); | ||||
6162 | UE = Checker.getUpdateExpr(); | ||||
6163 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||
Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 6164 | IsPostfixUpdate = true; |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6165 | } |
6166 | } | ||||
6167 | if (!IsUpdateExprFound) { | ||||
6168 | IsUpdateExprFound = !Checker.checkStatement(First); | ||||
6169 | BinOp = nullptr; | ||||
6170 | if (IsUpdateExprFound) { | ||||
6171 | BinOp = dyn_cast<BinaryOperator>(Second); | ||||
6172 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | ||||
6173 | } | ||||
6174 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | ||||
6175 | // { x++; v = x; } | ||||
6176 | // { x--; v = x; } | ||||
6177 | // { ++x; v = x; } | ||||
6178 | // { --x; v = x; } | ||||
6179 | // { x binop= expr; v = x; } | ||||
6180 | // { x = x binop expr; v = x; } | ||||
6181 | // { x = expr binop x; v = x; } | ||||
6182 | // Check that the second expression has form v = x. | ||||
6183 | auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | ||||
6184 | llvm::FoldingSetNodeID XId, PossibleXId; | ||||
6185 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | ||||
6186 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | ||||
6187 | IsUpdateExprFound = XId == PossibleXId; | ||||
6188 | if (IsUpdateExprFound) { | ||||
6189 | V = BinOp->getLHS(); | ||||
6190 | X = Checker.getX(); | ||||
6191 | E = Checker.getExpr(); | ||||
6192 | UE = Checker.getUpdateExpr(); | ||||
6193 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | ||||
Alexey Bataev | 5e018f9 | 2015-04-23 06:35:10 +0000 | [diff] [blame] | 6194 | IsPostfixUpdate = false; |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6195 | } |
6196 | } | ||||
6197 | } | ||||
6198 | if (!IsUpdateExprFound) { | ||||
6199 | // { v = x; x = expr; } | ||||
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 6200 | auto *FirstExpr = dyn_cast<Expr>(First); |
6201 | auto *SecondExpr = dyn_cast<Expr>(Second); | ||||
6202 | if (!FirstExpr || !SecondExpr || | ||||
6203 | !(FirstExpr->isInstantiationDependent() || | ||||
6204 | SecondExpr->isInstantiationDependent())) { | ||||
6205 | auto *FirstBinOp = dyn_cast<BinaryOperator>(First); | ||||
6206 | if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6207 | ErrorFound = NotAnAssignmentOp; |
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 6208 | NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() |
6209 | : First->getLocStart(); | ||||
6210 | NoteRange = ErrorRange = FirstBinOp | ||||
6211 | ? FirstBinOp->getSourceRange() | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6212 | : SourceRange(ErrorLoc, ErrorLoc); |
6213 | } else { | ||||
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 6214 | auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); |
6215 | if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { | ||||
6216 | ErrorFound = NotAnAssignmentOp; | ||||
6217 | NoteLoc = ErrorLoc = SecondBinOp | ||||
6218 | ? SecondBinOp->getOperatorLoc() | ||||
6219 | : Second->getLocStart(); | ||||
6220 | NoteRange = ErrorRange = | ||||
6221 | SecondBinOp ? SecondBinOp->getSourceRange() | ||||
6222 | : SourceRange(ErrorLoc, ErrorLoc); | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6223 | } else { |
Alexey Bataev | 5a19547 | 2015-09-04 12:55:50 +0000 | [diff] [blame] | 6224 | auto *PossibleXRHSInFirst = |
6225 | FirstBinOp->getRHS()->IgnoreParenImpCasts(); | ||||
6226 | auto *PossibleXLHSInSecond = | ||||
6227 | SecondBinOp->getLHS()->IgnoreParenImpCasts(); | ||||
6228 | llvm::FoldingSetNodeID X1Id, X2Id; | ||||
6229 | PossibleXRHSInFirst->Profile(X1Id, Context, | ||||
6230 | /*Canonical=*/true); | ||||
6231 | PossibleXLHSInSecond->Profile(X2Id, Context, | ||||
6232 | /*Canonical=*/true); | ||||
6233 | IsUpdateExprFound = X1Id == X2Id; | ||||
6234 | if (IsUpdateExprFound) { | ||||
6235 | V = FirstBinOp->getLHS(); | ||||
6236 | X = SecondBinOp->getLHS(); | ||||
6237 | E = SecondBinOp->getRHS(); | ||||
6238 | UE = nullptr; | ||||
6239 | IsXLHSInRHSPart = false; | ||||
6240 | IsPostfixUpdate = true; | ||||
6241 | } else { | ||||
6242 | ErrorFound = NotASpecificExpression; | ||||
6243 | ErrorLoc = FirstBinOp->getExprLoc(); | ||||
6244 | ErrorRange = FirstBinOp->getSourceRange(); | ||||
6245 | NoteLoc = SecondBinOp->getLHS()->getExprLoc(); | ||||
6246 | NoteRange = SecondBinOp->getRHS()->getSourceRange(); | ||||
6247 | } | ||||
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6248 | } |
6249 | } | ||||
6250 | } | ||||
6251 | } | ||||
6252 | } else { | ||||
6253 | NoteLoc = ErrorLoc = Body->getLocStart(); | ||||
6254 | NoteRange = ErrorRange = | ||||
6255 | SourceRange(Body->getLocStart(), Body->getLocStart()); | ||||
6256 | ErrorFound = NotTwoSubstatements; | ||||
6257 | } | ||||
6258 | } else { | ||||
6259 | NoteLoc = ErrorLoc = Body->getLocStart(); | ||||
6260 | NoteRange = ErrorRange = | ||||
6261 | SourceRange(Body->getLocStart(), Body->getLocStart()); | ||||
6262 | ErrorFound = NotACompoundStatement; | ||||
6263 | } | ||||
6264 | if (ErrorFound != NoError) { | ||||
6265 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) | ||||
6266 | << ErrorRange; | ||||
6267 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | ||||
6268 | return StmtError(); | ||||
6269 | } else if (CurContext->isDependentContext()) { | ||||
6270 | UE = V = E = X = nullptr; | ||||
6271 | } | ||||
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 6272 | } |
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 6273 | } |
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 6274 | |
6275 | getCurFunction()->setHasBranchProtectedScope(); | ||||
6276 | |||||
Alexey Bataev | 62cec44 | 2014-11-18 10:14:22 +0000 | [diff] [blame] | 6277 | return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
Alexey Bataev | b78ca83 | 2015-04-01 03:33:17 +0000 | [diff] [blame] | 6278 | X, V, E, UE, IsXLHSInRHSPart, |
6279 | IsPostfixUpdate); | ||||
Alexey Bataev | 0162e45 | 2014-07-22 10:10:35 +0000 | [diff] [blame] | 6280 | } |
6281 | |||||
Alexey Bataev | 0bd520b | 2014-09-19 08:19:49 +0000 | [diff] [blame] | 6282 | StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, |
6283 | Stmt *AStmt, | ||||
6284 | SourceLocation StartLoc, | ||||
6285 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 6286 | if (!AStmt) |
6287 | return StmtError(); | ||||
6288 | |||||
Samuel Antao | 4af1b7b | 2015-12-02 17:44:43 +0000 | [diff] [blame] | 6289 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); |
6290 | // 1.2.2 OpenMP Language Terminology | ||||
6291 | // Structured block - An executable statement with a single entry at the | ||||
6292 | // top and a single exit at the bottom. | ||||
6293 | // The point of exit cannot be a branch out of the structured block. | ||||
6294 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6295 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | 0bd520b | 2014-09-19 08:19:49 +0000 | [diff] [blame] | 6296 | |
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 6297 | // OpenMP [2.16, Nesting of Regions] |
6298 | // If specified, a teams construct must be contained within a target | ||||
6299 | // construct. That target construct must contain no statements or directives | ||||
6300 | // outside of the teams construct. | ||||
6301 | if (DSAStack->hasInnerTeamsRegion()) { | ||||
6302 | auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); | ||||
6303 | bool OMPTeamsFound = true; | ||||
6304 | if (auto *CS = dyn_cast<CompoundStmt>(S)) { | ||||
6305 | auto I = CS->body_begin(); | ||||
6306 | while (I != CS->body_end()) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 6307 | auto *OED = dyn_cast<OMPExecutableDirective>(*I); |
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 6308 | if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { |
6309 | OMPTeamsFound = false; | ||||
6310 | break; | ||||
6311 | } | ||||
6312 | ++I; | ||||
6313 | } | ||||
6314 | assert(I != CS->body_end() && "Not found statement"); | ||||
6315 | S = *I; | ||||
Kelvin Li | 3834dce | 2016-06-27 19:15:43 +0000 | [diff] [blame] | 6316 | } else { |
6317 | auto *OED = dyn_cast<OMPExecutableDirective>(S); | ||||
6318 | OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); | ||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 6319 | } |
6320 | if (!OMPTeamsFound) { | ||||
6321 | Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); | ||||
6322 | Diag(DSAStack->getInnerTeamsRegionLoc(), | ||||
6323 | diag::note_omp_nested_teams_construct_here); | ||||
6324 | Diag(S->getLocStart(), diag::note_omp_nested_statement_here) | ||||
6325 | << isa<OMPExecutableDirective>(S); | ||||
6326 | return StmtError(); | ||||
6327 | } | ||||
6328 | } | ||||
6329 | |||||
Alexey Bataev | 0bd520b | 2014-09-19 08:19:49 +0000 | [diff] [blame] | 6330 | getCurFunction()->setHasBranchProtectedScope(); |
6331 | |||||
6332 | return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | ||||
6333 | } | ||||
6334 | |||||
Arpith Chacko Jacob | e955b3d | 2016-01-26 18:48:41 +0000 | [diff] [blame] | 6335 | StmtResult |
6336 | Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, | ||||
6337 | Stmt *AStmt, SourceLocation StartLoc, | ||||
6338 | SourceLocation EndLoc) { | ||||
6339 | if (!AStmt) | ||||
6340 | return StmtError(); | ||||
6341 | |||||
6342 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6343 | // 1.2.2 OpenMP Language Terminology | ||||
6344 | // Structured block - An executable statement with a single entry at the | ||||
6345 | // top and a single exit at the bottom. | ||||
6346 | // The point of exit cannot be a branch out of the structured block. | ||||
6347 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6348 | CS->getCapturedDecl()->setNothrow(); | ||||
6349 | |||||
6350 | getCurFunction()->setHasBranchProtectedScope(); | ||||
6351 | |||||
6352 | return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||
6353 | AStmt); | ||||
6354 | } | ||||
6355 | |||||
Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 6356 | StmtResult Sema::ActOnOpenMPTargetParallelForDirective( |
6357 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6358 | SourceLocation EndLoc, | ||||
6359 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
6360 | if (!AStmt) | ||||
6361 | return StmtError(); | ||||
6362 | |||||
6363 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6364 | // 1.2.2 OpenMP Language Terminology | ||||
6365 | // Structured block - An executable statement with a single entry at the | ||||
6366 | // top and a single exit at the bottom. | ||||
6367 | // The point of exit cannot be a branch out of the structured block. | ||||
6368 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6369 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 6370 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); |
6371 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6372 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6373 | // 1.2.2 OpenMP Language Terminology | ||||
6374 | // Structured block - An executable statement with a single entry at the | ||||
6375 | // top and a single exit at the bottom. | ||||
6376 | // The point of exit cannot be a branch out of the structured block. | ||||
6377 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6378 | CS->getCapturedDecl()->setNothrow(); | ||||
6379 | } | ||||
Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 6380 | |
6381 | OMPLoopDirective::HelperExprs B; | ||||
6382 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||
6383 | // define the nested loops number. | ||||
6384 | unsigned NestedLoopCount = | ||||
6385 | CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), | ||||
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 6386 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, |
Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 6387 | VarsWithImplicitDSA, B); |
6388 | if (NestedLoopCount == 0) | ||||
6389 | return StmtError(); | ||||
6390 | |||||
6391 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6392 | "omp target parallel for loop exprs were not built"); | ||||
6393 | |||||
6394 | if (!CurContext->isDependentContext()) { | ||||
6395 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
6396 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 6397 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 6398 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 6399 | B.NumIterations, *this, CurScope, |
6400 | DSAStack)) | ||||
Arpith Chacko Jacob | 05bebb5 | 2016-02-03 15:46:42 +0000 | [diff] [blame] | 6401 | return StmtError(); |
6402 | } | ||||
6403 | } | ||||
6404 | |||||
6405 | getCurFunction()->setHasBranchProtectedScope(); | ||||
6406 | return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, | ||||
6407 | NestedLoopCount, Clauses, AStmt, | ||||
6408 | B, DSAStack->isCancelRegion()); | ||||
6409 | } | ||||
6410 | |||||
Alexey Bataev | 95b64a9 | 2017-05-30 16:00:04 +0000 | [diff] [blame] | 6411 | /// Check for existence of a map clause in the list of clauses. |
6412 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, | ||||
6413 | const OpenMPClauseKind K) { | ||||
6414 | return llvm::any_of( | ||||
6415 | Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); | ||||
6416 | } | ||||
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 6417 | |
Alexey Bataev | 95b64a9 | 2017-05-30 16:00:04 +0000 | [diff] [blame] | 6418 | template <typename... Params> |
6419 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, | ||||
6420 | const Params... ClauseTypes) { | ||||
6421 | return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); | ||||
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 6422 | } |
6423 | |||||
Michael Wong | 65f367f | 2015-07-21 13:44:28 +0000 | [diff] [blame] | 6424 | StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, |
6425 | Stmt *AStmt, | ||||
6426 | SourceLocation StartLoc, | ||||
6427 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 6428 | if (!AStmt) |
6429 | return StmtError(); | ||||
6430 | |||||
6431 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
6432 | |||||
Arpith Chacko Jacob | 46a04bb | 2016-01-21 19:57:55 +0000 | [diff] [blame] | 6433 | // OpenMP [2.10.1, Restrictions, p. 97] |
6434 | // At least one map clause must appear on the directive. | ||||
Alexey Bataev | 95b64a9 | 2017-05-30 16:00:04 +0000 | [diff] [blame] | 6435 | if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { |
6436 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||
6437 | << "'map' or 'use_device_ptr'" | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 6438 | << getOpenMPDirectiveName(OMPD_target_data); |
Arpith Chacko Jacob | 46a04bb | 2016-01-21 19:57:55 +0000 | [diff] [blame] | 6439 | return StmtError(); |
6440 | } | ||||
6441 | |||||
Michael Wong | 65f367f | 2015-07-21 13:44:28 +0000 | [diff] [blame] | 6442 | getCurFunction()->setHasBranchProtectedScope(); |
6443 | |||||
6444 | return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||
6445 | AStmt); | ||||
6446 | } | ||||
6447 | |||||
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 6448 | StmtResult |
6449 | Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, | ||||
6450 | SourceLocation StartLoc, | ||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 6451 | SourceLocation EndLoc, Stmt *AStmt) { |
6452 | if (!AStmt) | ||||
6453 | return StmtError(); | ||||
6454 | |||||
6455 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6456 | // 1.2.2 OpenMP Language Terminology | ||||
6457 | // Structured block - An executable statement with a single entry at the | ||||
6458 | // top and a single exit at the bottom. | ||||
6459 | // The point of exit cannot be a branch out of the structured block. | ||||
6460 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6461 | CS->getCapturedDecl()->setNothrow(); | ||||
6462 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); | ||||
6463 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6464 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6465 | // 1.2.2 OpenMP Language Terminology | ||||
6466 | // Structured block - An executable statement with a single entry at the | ||||
6467 | // top and a single exit at the bottom. | ||||
6468 | // The point of exit cannot be a branch out of the structured block. | ||||
6469 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6470 | CS->getCapturedDecl()->setNothrow(); | ||||
6471 | } | ||||
6472 | |||||
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 6473 | // OpenMP [2.10.2, Restrictions, p. 99] |
6474 | // At least one map clause must appear on the directive. | ||||
Alexey Bataev | 95b64a9 | 2017-05-30 16:00:04 +0000 | [diff] [blame] | 6475 | if (!hasClauses(Clauses, OMPC_map)) { |
6476 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||
6477 | << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); | ||||
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 6478 | return StmtError(); |
6479 | } | ||||
6480 | |||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 6481 | return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, |
6482 | AStmt); | ||||
Samuel Antao | df67fc4 | 2016-01-19 19:15:56 +0000 | [diff] [blame] | 6483 | } |
6484 | |||||
Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 6485 | StmtResult |
6486 | Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, | ||||
6487 | SourceLocation StartLoc, | ||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 6488 | SourceLocation EndLoc, Stmt *AStmt) { |
6489 | if (!AStmt) | ||||
6490 | return StmtError(); | ||||
6491 | |||||
6492 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6493 | // 1.2.2 OpenMP Language Terminology | ||||
6494 | // Structured block - An executable statement with a single entry at the | ||||
6495 | // top and a single exit at the bottom. | ||||
6496 | // The point of exit cannot be a branch out of the structured block. | ||||
6497 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6498 | CS->getCapturedDecl()->setNothrow(); | ||||
6499 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); | ||||
6500 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6501 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6502 | // 1.2.2 OpenMP Language Terminology | ||||
6503 | // Structured block - An executable statement with a single entry at the | ||||
6504 | // top and a single exit at the bottom. | ||||
6505 | // The point of exit cannot be a branch out of the structured block. | ||||
6506 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6507 | CS->getCapturedDecl()->setNothrow(); | ||||
6508 | } | ||||
6509 | |||||
Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 6510 | // OpenMP [2.10.3, Restrictions, p. 102] |
6511 | // At least one map clause must appear on the directive. | ||||
Alexey Bataev | 95b64a9 | 2017-05-30 16:00:04 +0000 | [diff] [blame] | 6512 | if (!hasClauses(Clauses, OMPC_map)) { |
6513 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) | ||||
6514 | << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); | ||||
Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 6515 | return StmtError(); |
6516 | } | ||||
6517 | |||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 6518 | return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, |
6519 | AStmt); | ||||
Samuel Antao | 7259076 | 2016-01-19 20:04:50 +0000 | [diff] [blame] | 6520 | } |
6521 | |||||
Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 6522 | StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, |
6523 | SourceLocation StartLoc, | ||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 6524 | SourceLocation EndLoc, |
6525 | Stmt *AStmt) { | ||||
6526 | if (!AStmt) | ||||
6527 | return StmtError(); | ||||
6528 | |||||
6529 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6530 | // 1.2.2 OpenMP Language Terminology | ||||
6531 | // Structured block - An executable statement with a single entry at the | ||||
6532 | // top and a single exit at the bottom. | ||||
6533 | // The point of exit cannot be a branch out of the structured block. | ||||
6534 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6535 | CS->getCapturedDecl()->setNothrow(); | ||||
6536 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); | ||||
6537 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6538 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6539 | // 1.2.2 OpenMP Language Terminology | ||||
6540 | // Structured block - An executable statement with a single entry at the | ||||
6541 | // top and a single exit at the bottom. | ||||
6542 | // The point of exit cannot be a branch out of the structured block. | ||||
6543 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6544 | CS->getCapturedDecl()->setNothrow(); | ||||
6545 | } | ||||
6546 | |||||
Alexey Bataev | 95b64a9 | 2017-05-30 16:00:04 +0000 | [diff] [blame] | 6547 | if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { |
Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 6548 | Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); |
6549 | return StmtError(); | ||||
6550 | } | ||||
Alexey Bataev | 7828b25 | 2017-11-21 17:08:48 +0000 | [diff] [blame] | 6551 | return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, |
6552 | AStmt); | ||||
Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 6553 | } |
6554 | |||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 6555 | StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, |
6556 | Stmt *AStmt, SourceLocation StartLoc, | ||||
6557 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 6558 | if (!AStmt) |
6559 | return StmtError(); | ||||
6560 | |||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 6561 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); |
6562 | // 1.2.2 OpenMP Language Terminology | ||||
6563 | // Structured block - An executable statement with a single entry at the | ||||
6564 | // top and a single exit at the bottom. | ||||
6565 | // The point of exit cannot be a branch out of the structured block. | ||||
6566 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6567 | CS->getCapturedDecl()->setNothrow(); | ||||
6568 | |||||
6569 | getCurFunction()->setHasBranchProtectedScope(); | ||||
6570 | |||||
Alexey Bataev | ceabd41 | 2017-11-30 18:01:54 +0000 | [diff] [blame] | 6571 | DSAStack->setParentTeamsRegionLoc(StartLoc); |
6572 | |||||
Alexey Bataev | 13314bf | 2014-10-09 04:18:56 +0000 | [diff] [blame] | 6573 | return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); |
6574 | } | ||||
6575 | |||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 6576 | StmtResult |
6577 | Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, | ||||
6578 | SourceLocation EndLoc, | ||||
6579 | OpenMPDirectiveKind CancelRegion) { | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 6580 | if (DSAStack->isParentNowaitRegion()) { |
6581 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; | ||||
6582 | return StmtError(); | ||||
6583 | } | ||||
6584 | if (DSAStack->isParentOrderedRegion()) { | ||||
6585 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; | ||||
6586 | return StmtError(); | ||||
6587 | } | ||||
6588 | return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, | ||||
6589 | CancelRegion); | ||||
6590 | } | ||||
6591 | |||||
Alexey Bataev | 87933c7 | 2015-09-18 08:07:34 +0000 | [diff] [blame] | 6592 | StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, |
6593 | SourceLocation StartLoc, | ||||
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 6594 | SourceLocation EndLoc, |
6595 | OpenMPDirectiveKind CancelRegion) { | ||||
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 6596 | if (DSAStack->isParentNowaitRegion()) { |
6597 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; | ||||
6598 | return StmtError(); | ||||
6599 | } | ||||
6600 | if (DSAStack->isParentOrderedRegion()) { | ||||
6601 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; | ||||
6602 | return StmtError(); | ||||
6603 | } | ||||
Alexey Bataev | 25e5b44 | 2015-09-15 12:52:43 +0000 | [diff] [blame] | 6604 | DSAStack->setParentCancelRegion(/*Cancel=*/true); |
Alexey Bataev | 87933c7 | 2015-09-18 08:07:34 +0000 | [diff] [blame] | 6605 | return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, |
6606 | CancelRegion); | ||||
Alexey Bataev | 8090987 | 2015-07-02 11:25:17 +0000 | [diff] [blame] | 6607 | } |
6608 | |||||
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 6609 | static bool checkGrainsizeNumTasksClauses(Sema &S, |
6610 | ArrayRef<OMPClause *> Clauses) { | ||||
6611 | OMPClause *PrevClause = nullptr; | ||||
6612 | bool ErrorFound = false; | ||||
6613 | for (auto *C : Clauses) { | ||||
6614 | if (C->getClauseKind() == OMPC_grainsize || | ||||
6615 | C->getClauseKind() == OMPC_num_tasks) { | ||||
6616 | if (!PrevClause) | ||||
6617 | PrevClause = C; | ||||
6618 | else if (PrevClause->getClauseKind() != C->getClauseKind()) { | ||||
6619 | S.Diag(C->getLocStart(), | ||||
6620 | diag::err_omp_grainsize_num_tasks_mutually_exclusive) | ||||
6621 | << getOpenMPClauseName(C->getClauseKind()) | ||||
6622 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||
6623 | S.Diag(PrevClause->getLocStart(), | ||||
6624 | diag::note_omp_previous_grainsize_num_tasks) | ||||
6625 | << getOpenMPClauseName(PrevClause->getClauseKind()); | ||||
6626 | ErrorFound = true; | ||||
6627 | } | ||||
6628 | } | ||||
6629 | } | ||||
6630 | return ErrorFound; | ||||
6631 | } | ||||
6632 | |||||
Alexey Bataev | bcd0ae0 | 2017-07-11 19:16:44 +0000 | [diff] [blame] | 6633 | static bool checkReductionClauseWithNogroup(Sema &S, |
6634 | ArrayRef<OMPClause *> Clauses) { | ||||
6635 | OMPClause *ReductionClause = nullptr; | ||||
6636 | OMPClause *NogroupClause = nullptr; | ||||
6637 | for (auto *C : Clauses) { | ||||
6638 | if (C->getClauseKind() == OMPC_reduction) { | ||||
6639 | ReductionClause = C; | ||||
6640 | if (NogroupClause) | ||||
6641 | break; | ||||
6642 | continue; | ||||
6643 | } | ||||
6644 | if (C->getClauseKind() == OMPC_nogroup) { | ||||
6645 | NogroupClause = C; | ||||
6646 | if (ReductionClause) | ||||
6647 | break; | ||||
6648 | continue; | ||||
6649 | } | ||||
6650 | } | ||||
6651 | if (ReductionClause && NogroupClause) { | ||||
6652 | S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup) | ||||
6653 | << SourceRange(NogroupClause->getLocStart(), | ||||
6654 | NogroupClause->getLocEnd()); | ||||
6655 | return true; | ||||
6656 | } | ||||
6657 | return false; | ||||
6658 | } | ||||
6659 | |||||
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 6660 | StmtResult Sema::ActOnOpenMPTaskLoopDirective( |
6661 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6662 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 6663 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 6664 | if (!AStmt) |
6665 | return StmtError(); | ||||
6666 | |||||
6667 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
6668 | OMPLoopDirective::HelperExprs B; | ||||
6669 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||
6670 | // define the nested loops number. | ||||
6671 | unsigned NestedLoopCount = | ||||
6672 | CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), | ||||
Alexey Bataev | 0a6ed84 | 2015-12-03 09:40:15 +0000 | [diff] [blame] | 6673 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, |
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 6674 | VarsWithImplicitDSA, B); |
6675 | if (NestedLoopCount == 0) | ||||
6676 | return StmtError(); | ||||
6677 | |||||
6678 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6679 | "omp for loop exprs were not built"); | ||||
6680 | |||||
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 6681 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
6682 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||
6683 | // not appear on the same taskloop directive. | ||||
6684 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||
6685 | return StmtError(); | ||||
Alexey Bataev | bcd0ae0 | 2017-07-11 19:16:44 +0000 | [diff] [blame] | 6686 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
6687 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||
6688 | // clause must not be specified. | ||||
6689 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||
6690 | return StmtError(); | ||||
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 6691 | |
Alexey Bataev | 49f6e78 | 2015-12-01 04:18:41 +0000 | [diff] [blame] | 6692 | getCurFunction()->setHasBranchProtectedScope(); |
6693 | return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, | ||||
6694 | NestedLoopCount, Clauses, AStmt, B); | ||||
6695 | } | ||||
6696 | |||||
Alexey Bataev | 0a6ed84 | 2015-12-03 09:40:15 +0000 | [diff] [blame] | 6697 | StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( |
6698 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6699 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 6700 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Alexey Bataev | 0a6ed84 | 2015-12-03 09:40:15 +0000 | [diff] [blame] | 6701 | if (!AStmt) |
6702 | return StmtError(); | ||||
6703 | |||||
6704 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
6705 | OMPLoopDirective::HelperExprs B; | ||||
6706 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||
6707 | // define the nested loops number. | ||||
6708 | unsigned NestedLoopCount = | ||||
6709 | CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), | ||||
6710 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, | ||||
6711 | VarsWithImplicitDSA, B); | ||||
6712 | if (NestedLoopCount == 0) | ||||
6713 | return StmtError(); | ||||
6714 | |||||
6715 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6716 | "omp for loop exprs were not built"); | ||||
6717 | |||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 6718 | if (!CurContext->isDependentContext()) { |
6719 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
6720 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 6721 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 6722 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 6723 | B.NumIterations, *this, CurScope, |
6724 | DSAStack)) | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 6725 | return StmtError(); |
6726 | } | ||||
6727 | } | ||||
6728 | |||||
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 6729 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
6730 | // The grainsize clause and num_tasks clause are mutually exclusive and may | ||||
6731 | // not appear on the same taskloop directive. | ||||
6732 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) | ||||
6733 | return StmtError(); | ||||
Alexey Bataev | bcd0ae0 | 2017-07-11 19:16:44 +0000 | [diff] [blame] | 6734 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
6735 | // If a reduction clause is present on the taskloop directive, the nogroup | ||||
6736 | // clause must not be specified. | ||||
6737 | if (checkReductionClauseWithNogroup(*this, Clauses)) | ||||
6738 | return StmtError(); | ||||
Alexey Bataev | 438388c | 2017-11-22 18:34:02 +0000 | [diff] [blame] | 6739 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
6740 | return StmtError(); | ||||
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 6741 | |
Alexey Bataev | 0a6ed84 | 2015-12-03 09:40:15 +0000 | [diff] [blame] | 6742 | getCurFunction()->setHasBranchProtectedScope(); |
6743 | return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, | ||||
6744 | NestedLoopCount, Clauses, AStmt, B); | ||||
6745 | } | ||||
6746 | |||||
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 6747 | StmtResult Sema::ActOnOpenMPDistributeDirective( |
6748 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6749 | SourceLocation EndLoc, | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 6750 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { |
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 6751 | if (!AStmt) |
6752 | return StmtError(); | ||||
6753 | |||||
6754 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); | ||||
6755 | OMPLoopDirective::HelperExprs B; | ||||
6756 | // In presence of clause 'collapse' with number of loops, it will | ||||
6757 | // define the nested loops number. | ||||
6758 | unsigned NestedLoopCount = | ||||
6759 | CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), | ||||
6760 | nullptr /*ordered not a clause on distribute*/, AStmt, | ||||
6761 | *this, *DSAStack, VarsWithImplicitDSA, B); | ||||
6762 | if (NestedLoopCount == 0) | ||||
6763 | return StmtError(); | ||||
6764 | |||||
6765 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6766 | "omp for loop exprs were not built"); | ||||
6767 | |||||
6768 | getCurFunction()->setHasBranchProtectedScope(); | ||||
6769 | return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, | ||||
6770 | NestedLoopCount, Clauses, AStmt, B); | ||||
6771 | } | ||||
6772 | |||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 6773 | StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( |
6774 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6775 | SourceLocation EndLoc, | ||||
6776 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
6777 | if (!AStmt) | ||||
6778 | return StmtError(); | ||||
6779 | |||||
6780 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6781 | // 1.2.2 OpenMP Language Terminology | ||||
6782 | // Structured block - An executable statement with a single entry at the | ||||
6783 | // top and a single exit at the bottom. | ||||
6784 | // The point of exit cannot be a branch out of the structured block. | ||||
6785 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6786 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | 7f96c37 | 2017-11-22 17:19:31 +0000 | [diff] [blame] | 6787 | for (int ThisCaptureLevel = |
6788 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for); | ||||
6789 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6790 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6791 | // 1.2.2 OpenMP Language Terminology | ||||
6792 | // Structured block - An executable statement with a single entry at the | ||||
6793 | // top and a single exit at the bottom. | ||||
6794 | // The point of exit cannot be a branch out of the structured block. | ||||
6795 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6796 | CS->getCapturedDecl()->setNothrow(); | ||||
6797 | } | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 6798 | |
6799 | OMPLoopDirective::HelperExprs B; | ||||
6800 | // In presence of clause 'collapse' with number of loops, it will | ||||
6801 | // define the nested loops number. | ||||
6802 | unsigned NestedLoopCount = CheckOpenMPLoop( | ||||
6803 | OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||
Alexey Bataev | 7f96c37 | 2017-11-22 17:19:31 +0000 | [diff] [blame] | 6804 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, |
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 6805 | VarsWithImplicitDSA, B); |
6806 | if (NestedLoopCount == 0) | ||||
6807 | return StmtError(); | ||||
6808 | |||||
6809 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6810 | "omp for loop exprs were not built"); | ||||
6811 | |||||
6812 | getCurFunction()->setHasBranchProtectedScope(); | ||||
6813 | return OMPDistributeParallelForDirective::Create( | ||||
Alexey Bataev | dcb4b8fb | 2017-11-22 20:19:50 +0000 | [diff] [blame] | 6814 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
6815 | DSAStack->isCancelRegion()); | ||||
Carlo Bertolli | 9925f15 | 2016-06-27 14:55:37 +0000 | [diff] [blame] | 6816 | } |
6817 | |||||
Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 6818 | StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( |
6819 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6820 | SourceLocation EndLoc, | ||||
6821 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
6822 | if (!AStmt) | ||||
6823 | return StmtError(); | ||||
6824 | |||||
6825 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6826 | // 1.2.2 OpenMP Language Terminology | ||||
6827 | // Structured block - An executable statement with a single entry at the | ||||
6828 | // top and a single exit at the bottom. | ||||
6829 | // The point of exit cannot be a branch out of the structured block. | ||||
6830 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6831 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | 974acd6 | 2017-11-27 19:38:52 +0000 | [diff] [blame] | 6832 | for (int ThisCaptureLevel = |
6833 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); | ||||
6834 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6835 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6836 | // 1.2.2 OpenMP Language Terminology | ||||
6837 | // Structured block - An executable statement with a single entry at the | ||||
6838 | // top and a single exit at the bottom. | ||||
6839 | // The point of exit cannot be a branch out of the structured block. | ||||
6840 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6841 | CS->getCapturedDecl()->setNothrow(); | ||||
6842 | } | ||||
Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 6843 | |
6844 | OMPLoopDirective::HelperExprs B; | ||||
6845 | // In presence of clause 'collapse' with number of loops, it will | ||||
6846 | // define the nested loops number. | ||||
6847 | unsigned NestedLoopCount = CheckOpenMPLoop( | ||||
6848 | OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||
Alexey Bataev | 974acd6 | 2017-11-27 19:38:52 +0000 | [diff] [blame] | 6849 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, |
Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 6850 | VarsWithImplicitDSA, B); |
6851 | if (NestedLoopCount == 0) | ||||
6852 | return StmtError(); | ||||
6853 | |||||
6854 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6855 | "omp for loop exprs were not built"); | ||||
6856 | |||||
Alexey Bataev | 438388c | 2017-11-22 18:34:02 +0000 | [diff] [blame] | 6857 | if (!CurContext->isDependentContext()) { |
6858 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
6859 | for (auto C : Clauses) { | ||||
6860 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||
6861 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||
6862 | B.NumIterations, *this, CurScope, | ||||
6863 | DSAStack)) | ||||
6864 | return StmtError(); | ||||
6865 | } | ||||
6866 | } | ||||
6867 | |||||
Kelvin Li | c560949 | 2016-07-15 04:39:07 +0000 | [diff] [blame] | 6868 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
6869 | return StmtError(); | ||||
6870 | |||||
Kelvin Li | 4a39add | 2016-07-05 05:00:15 +0000 | [diff] [blame] | 6871 | getCurFunction()->setHasBranchProtectedScope(); |
6872 | return OMPDistributeParallelForSimdDirective::Create( | ||||
6873 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
6874 | } | ||||
6875 | |||||
Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 6876 | StmtResult Sema::ActOnOpenMPDistributeSimdDirective( |
6877 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6878 | SourceLocation EndLoc, | ||||
6879 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
6880 | if (!AStmt) | ||||
6881 | return StmtError(); | ||||
6882 | |||||
6883 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6884 | // 1.2.2 OpenMP Language Terminology | ||||
6885 | // Structured block - An executable statement with a single entry at the | ||||
6886 | // top and a single exit at the bottom. | ||||
6887 | // The point of exit cannot be a branch out of the structured block. | ||||
6888 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6889 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 6890 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); |
6891 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6892 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6893 | // 1.2.2 OpenMP Language Terminology | ||||
6894 | // Structured block - An executable statement with a single entry at the | ||||
6895 | // top and a single exit at the bottom. | ||||
6896 | // The point of exit cannot be a branch out of the structured block. | ||||
6897 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6898 | CS->getCapturedDecl()->setNothrow(); | ||||
6899 | } | ||||
Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 6900 | |
6901 | OMPLoopDirective::HelperExprs B; | ||||
6902 | // In presence of clause 'collapse' with number of loops, it will | ||||
6903 | // define the nested loops number. | ||||
6904 | unsigned NestedLoopCount = | ||||
6905 | CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), | ||||
Alexey Bataev | 617db5f | 2017-12-04 15:38:33 +0000 | [diff] [blame] | 6906 | nullptr /*ordered not a clause on distribute*/, CS, *this, |
6907 | *DSAStack, VarsWithImplicitDSA, B); | ||||
Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 6908 | if (NestedLoopCount == 0) |
6909 | return StmtError(); | ||||
6910 | |||||
6911 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6912 | "omp for loop exprs were not built"); | ||||
6913 | |||||
Alexey Bataev | 438388c | 2017-11-22 18:34:02 +0000 | [diff] [blame] | 6914 | if (!CurContext->isDependentContext()) { |
6915 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
6916 | for (auto C : Clauses) { | ||||
6917 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||
6918 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||
6919 | B.NumIterations, *this, CurScope, | ||||
6920 | DSAStack)) | ||||
6921 | return StmtError(); | ||||
6922 | } | ||||
6923 | } | ||||
6924 | |||||
Kelvin Li | c560949 | 2016-07-15 04:39:07 +0000 | [diff] [blame] | 6925 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
6926 | return StmtError(); | ||||
6927 | |||||
Kelvin Li | 787f3fc | 2016-07-06 04:45:38 +0000 | [diff] [blame] | 6928 | getCurFunction()->setHasBranchProtectedScope(); |
6929 | return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, | ||||
6930 | NestedLoopCount, Clauses, AStmt, B); | ||||
6931 | } | ||||
6932 | |||||
Kelvin Li | a579b91 | 2016-07-14 02:54:56 +0000 | [diff] [blame] | 6933 | StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( |
6934 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6935 | SourceLocation EndLoc, | ||||
6936 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
6937 | if (!AStmt) | ||||
6938 | return StmtError(); | ||||
6939 | |||||
6940 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6941 | // 1.2.2 OpenMP Language Terminology | ||||
6942 | // Structured block - An executable statement with a single entry at the | ||||
6943 | // top and a single exit at the bottom. | ||||
6944 | // The point of exit cannot be a branch out of the structured block. | ||||
6945 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6946 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 6947 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); |
6948 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
6949 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
6950 | // 1.2.2 OpenMP Language Terminology | ||||
6951 | // Structured block - An executable statement with a single entry at the | ||||
6952 | // top and a single exit at the bottom. | ||||
6953 | // The point of exit cannot be a branch out of the structured block. | ||||
6954 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
6955 | CS->getCapturedDecl()->setNothrow(); | ||||
6956 | } | ||||
Kelvin Li | a579b91 | 2016-07-14 02:54:56 +0000 | [diff] [blame] | 6957 | |
6958 | OMPLoopDirective::HelperExprs B; | ||||
6959 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will | ||||
6960 | // define the nested loops number. | ||||
6961 | unsigned NestedLoopCount = CheckOpenMPLoop( | ||||
6962 | OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||
Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 6963 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, |
Kelvin Li | a579b91 | 2016-07-14 02:54:56 +0000 | [diff] [blame] | 6964 | VarsWithImplicitDSA, B); |
6965 | if (NestedLoopCount == 0) | ||||
6966 | return StmtError(); | ||||
6967 | |||||
6968 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
6969 | "omp target parallel for simd loop exprs were not built"); | ||||
6970 | |||||
6971 | if (!CurContext->isDependentContext()) { | ||||
6972 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
6973 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 6974 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Kelvin Li | a579b91 | 2016-07-14 02:54:56 +0000 | [diff] [blame] | 6975 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
6976 | B.NumIterations, *this, CurScope, | ||||
6977 | DSAStack)) | ||||
6978 | return StmtError(); | ||||
6979 | } | ||||
6980 | } | ||||
Kelvin Li | c560949 | 2016-07-15 04:39:07 +0000 | [diff] [blame] | 6981 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
Kelvin Li | a579b91 | 2016-07-14 02:54:56 +0000 | [diff] [blame] | 6982 | return StmtError(); |
6983 | |||||
6984 | getCurFunction()->setHasBranchProtectedScope(); | ||||
6985 | return OMPTargetParallelForSimdDirective::Create( | ||||
6986 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
6987 | } | ||||
6988 | |||||
Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 6989 | StmtResult Sema::ActOnOpenMPTargetSimdDirective( |
6990 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
6991 | SourceLocation EndLoc, | ||||
6992 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
6993 | if (!AStmt) | ||||
6994 | return StmtError(); | ||||
6995 | |||||
6996 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
6997 | // 1.2.2 OpenMP Language Terminology | ||||
6998 | // Structured block - An executable statement with a single entry at the | ||||
6999 | // top and a single exit at the bottom. | ||||
7000 | // The point of exit cannot be a branch out of the structured block. | ||||
7001 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7002 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 7003 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); |
7004 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
7005 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
7006 | // 1.2.2 OpenMP Language Terminology | ||||
7007 | // Structured block - An executable statement with a single entry at the | ||||
7008 | // top and a single exit at the bottom. | ||||
7009 | // The point of exit cannot be a branch out of the structured block. | ||||
7010 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7011 | CS->getCapturedDecl()->setNothrow(); | ||||
7012 | } | ||||
7013 | |||||
Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 7014 | OMPLoopDirective::HelperExprs B; |
7015 | // In presence of clause 'collapse' with number of loops, it will define the | ||||
7016 | // nested loops number. | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 7017 | unsigned NestedLoopCount = |
Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 7018 | CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), |
Alexey Bataev | f836537 | 2017-11-17 17:57:25 +0000 | [diff] [blame] | 7019 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, |
Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 7020 | VarsWithImplicitDSA, B); |
7021 | if (NestedLoopCount == 0) | ||||
7022 | return StmtError(); | ||||
7023 | |||||
7024 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7025 | "omp target simd loop exprs were not built"); | ||||
7026 | |||||
7027 | if (!CurContext->isDependentContext()) { | ||||
7028 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
7029 | for (auto C : Clauses) { | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 7030 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
Kelvin Li | 986330c | 2016-07-20 22:57:10 +0000 | [diff] [blame] | 7031 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
7032 | B.NumIterations, *this, CurScope, | ||||
7033 | DSAStack)) | ||||
7034 | return StmtError(); | ||||
7035 | } | ||||
7036 | } | ||||
7037 | |||||
7038 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||
7039 | return StmtError(); | ||||
7040 | |||||
7041 | getCurFunction()->setHasBranchProtectedScope(); | ||||
7042 | return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, | ||||
7043 | NestedLoopCount, Clauses, AStmt, B); | ||||
7044 | } | ||||
7045 | |||||
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 7046 | StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( |
7047 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7048 | SourceLocation EndLoc, | ||||
7049 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7050 | if (!AStmt) | ||||
7051 | return StmtError(); | ||||
7052 | |||||
7053 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7054 | // 1.2.2 OpenMP Language Terminology | ||||
7055 | // Structured block - An executable statement with a single entry at the | ||||
7056 | // top and a single exit at the bottom. | ||||
7057 | // The point of exit cannot be a branch out of the structured block. | ||||
7058 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7059 | CS->getCapturedDecl()->setNothrow(); | ||||
Alexey Bataev | 95c6dd4 | 2017-11-29 15:14:16 +0000 | [diff] [blame] | 7060 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); |
7061 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
7062 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
7063 | // 1.2.2 OpenMP Language Terminology | ||||
7064 | // Structured block - An executable statement with a single entry at the | ||||
7065 | // top and a single exit at the bottom. | ||||
7066 | // The point of exit cannot be a branch out of the structured block. | ||||
7067 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7068 | CS->getCapturedDecl()->setNothrow(); | ||||
7069 | } | ||||
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 7070 | |
7071 | OMPLoopDirective::HelperExprs B; | ||||
7072 | // In presence of clause 'collapse' with number of loops, it will | ||||
7073 | // define the nested loops number. | ||||
7074 | unsigned NestedLoopCount = | ||||
7075 | CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), | ||||
Alexey Bataev | 95c6dd4 | 2017-11-29 15:14:16 +0000 | [diff] [blame] | 7076 | nullptr /*ordered not a clause on distribute*/, CS, *this, |
7077 | *DSAStack, VarsWithImplicitDSA, B); | ||||
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 7078 | if (NestedLoopCount == 0) |
7079 | return StmtError(); | ||||
7080 | |||||
7081 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7082 | "omp teams distribute loop exprs were not built"); | ||||
7083 | |||||
7084 | getCurFunction()->setHasBranchProtectedScope(); | ||||
Alexey Bataev | ceabd41 | 2017-11-30 18:01:54 +0000 | [diff] [blame] | 7085 | |
7086 | DSAStack->setParentTeamsRegionLoc(StartLoc); | ||||
7087 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 7088 | return OMPTeamsDistributeDirective::Create( |
7089 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
Kelvin Li | 0253287 | 2016-08-05 14:37:37 +0000 | [diff] [blame] | 7090 | } |
7091 | |||||
Kelvin Li | 4e325f7 | 2016-10-25 12:50:55 +0000 | [diff] [blame] | 7092 | StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( |
7093 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7094 | SourceLocation EndLoc, | ||||
7095 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7096 | if (!AStmt) | ||||
7097 | return StmtError(); | ||||
7098 | |||||
7099 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7100 | // 1.2.2 OpenMP Language Terminology | ||||
7101 | // Structured block - An executable statement with a single entry at the | ||||
7102 | // top and a single exit at the bottom. | ||||
7103 | // The point of exit cannot be a branch out of the structured block. | ||||
7104 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7105 | CS->getCapturedDecl()->setNothrow(); | ||||
7106 | |||||
7107 | OMPLoopDirective::HelperExprs B; | ||||
7108 | // In presence of clause 'collapse' with number of loops, it will | ||||
7109 | // define the nested loops number. | ||||
Samuel Antao | 4c8035b | 2016-12-12 18:00:20 +0000 | [diff] [blame] | 7110 | unsigned NestedLoopCount = CheckOpenMPLoop( |
7111 | OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), | ||||
7112 | nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, | ||||
7113 | VarsWithImplicitDSA, B); | ||||
Kelvin Li | 4e325f7 | 2016-10-25 12:50:55 +0000 | [diff] [blame] | 7114 | |
7115 | if (NestedLoopCount == 0) | ||||
7116 | return StmtError(); | ||||
7117 | |||||
7118 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7119 | "omp teams distribute simd loop exprs were not built"); | ||||
7120 | |||||
7121 | if (!CurContext->isDependentContext()) { | ||||
7122 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
7123 | for (auto C : Clauses) { | ||||
7124 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||
7125 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||
7126 | B.NumIterations, *this, CurScope, | ||||
7127 | DSAStack)) | ||||
7128 | return StmtError(); | ||||
7129 | } | ||||
7130 | } | ||||
7131 | |||||
7132 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||
7133 | return StmtError(); | ||||
7134 | |||||
7135 | getCurFunction()->setHasBranchProtectedScope(); | ||||
Alexey Bataev | ceabd41 | 2017-11-30 18:01:54 +0000 | [diff] [blame] | 7136 | |
7137 | DSAStack->setParentTeamsRegionLoc(StartLoc); | ||||
7138 | |||||
Kelvin Li | 4e325f7 | 2016-10-25 12:50:55 +0000 | [diff] [blame] | 7139 | return OMPTeamsDistributeSimdDirective::Create( |
7140 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
7141 | } | ||||
7142 | |||||
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 7143 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( |
7144 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7145 | SourceLocation EndLoc, | ||||
7146 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7147 | if (!AStmt) | ||||
7148 | return StmtError(); | ||||
7149 | |||||
7150 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7151 | // 1.2.2 OpenMP Language Terminology | ||||
7152 | // Structured block - An executable statement with a single entry at the | ||||
7153 | // top and a single exit at the bottom. | ||||
7154 | // The point of exit cannot be a branch out of the structured block. | ||||
7155 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7156 | CS->getCapturedDecl()->setNothrow(); | ||||
7157 | |||||
7158 | OMPLoopDirective::HelperExprs B; | ||||
7159 | // In presence of clause 'collapse' with number of loops, it will | ||||
7160 | // define the nested loops number. | ||||
7161 | auto NestedLoopCount = CheckOpenMPLoop( | ||||
7162 | OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), | ||||
7163 | nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, | ||||
7164 | VarsWithImplicitDSA, B); | ||||
7165 | |||||
7166 | if (NestedLoopCount == 0) | ||||
7167 | return StmtError(); | ||||
7168 | |||||
7169 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7170 | "omp for loop exprs were not built"); | ||||
7171 | |||||
7172 | if (!CurContext->isDependentContext()) { | ||||
7173 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
7174 | for (auto C : Clauses) { | ||||
7175 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||
7176 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||
7177 | B.NumIterations, *this, CurScope, | ||||
7178 | DSAStack)) | ||||
7179 | return StmtError(); | ||||
7180 | } | ||||
7181 | } | ||||
7182 | |||||
7183 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||
7184 | return StmtError(); | ||||
7185 | |||||
7186 | getCurFunction()->setHasBranchProtectedScope(); | ||||
Alexey Bataev | ceabd41 | 2017-11-30 18:01:54 +0000 | [diff] [blame] | 7187 | |
7188 | DSAStack->setParentTeamsRegionLoc(StartLoc); | ||||
7189 | |||||
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 7190 | return OMPTeamsDistributeParallelForSimdDirective::Create( |
7191 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
7192 | } | ||||
7193 | |||||
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 7194 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( |
7195 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7196 | SourceLocation EndLoc, | ||||
7197 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7198 | if (!AStmt) | ||||
7199 | return StmtError(); | ||||
7200 | |||||
7201 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7202 | // 1.2.2 OpenMP Language Terminology | ||||
7203 | // Structured block - An executable statement with a single entry at the | ||||
7204 | // top and a single exit at the bottom. | ||||
7205 | // The point of exit cannot be a branch out of the structured block. | ||||
7206 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7207 | CS->getCapturedDecl()->setNothrow(); | ||||
7208 | |||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7209 | for (int ThisCaptureLevel = |
7210 | getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); | ||||
7211 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
7212 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
7213 | // 1.2.2 OpenMP Language Terminology | ||||
7214 | // Structured block - An executable statement with a single entry at the | ||||
7215 | // top and a single exit at the bottom. | ||||
7216 | // The point of exit cannot be a branch out of the structured block. | ||||
7217 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7218 | CS->getCapturedDecl()->setNothrow(); | ||||
7219 | } | ||||
7220 | |||||
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 7221 | OMPLoopDirective::HelperExprs B; |
7222 | // In presence of clause 'collapse' with number of loops, it will | ||||
7223 | // define the nested loops number. | ||||
7224 | unsigned NestedLoopCount = CheckOpenMPLoop( | ||||
7225 | OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7226 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, |
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 7227 | VarsWithImplicitDSA, B); |
7228 | |||||
7229 | if (NestedLoopCount == 0) | ||||
7230 | return StmtError(); | ||||
7231 | |||||
7232 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7233 | "omp for loop exprs were not built"); | ||||
7234 | |||||
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 7235 | getCurFunction()->setHasBranchProtectedScope(); |
Alexey Bataev | ceabd41 | 2017-11-30 18:01:54 +0000 | [diff] [blame] | 7236 | |
7237 | DSAStack->setParentTeamsRegionLoc(StartLoc); | ||||
7238 | |||||
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 7239 | return OMPTeamsDistributeParallelForDirective::Create( |
Alexey Bataev | dcb4b8fb | 2017-11-22 20:19:50 +0000 | [diff] [blame] | 7240 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
7241 | DSAStack->isCancelRegion()); | ||||
Kelvin Li | 7ade93f | 2016-12-09 03:24:30 +0000 | [diff] [blame] | 7242 | } |
7243 | |||||
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 7244 | StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, |
7245 | Stmt *AStmt, | ||||
7246 | SourceLocation StartLoc, | ||||
7247 | SourceLocation EndLoc) { | ||||
7248 | if (!AStmt) | ||||
7249 | return StmtError(); | ||||
7250 | |||||
7251 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7252 | // 1.2.2 OpenMP Language Terminology | ||||
7253 | // Structured block - An executable statement with a single entry at the | ||||
7254 | // top and a single exit at the bottom. | ||||
7255 | // The point of exit cannot be a branch out of the structured block. | ||||
7256 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7257 | CS->getCapturedDecl()->setNothrow(); | ||||
7258 | |||||
Alexey Bataev | f9fc42e | 2017-11-22 14:25:55 +0000 | [diff] [blame] | 7259 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); |
7260 | ThisCaptureLevel > 1; --ThisCaptureLevel) { | ||||
7261 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); | ||||
7262 | // 1.2.2 OpenMP Language Terminology | ||||
7263 | // Structured block - An executable statement with a single entry at the | ||||
7264 | // top and a single exit at the bottom. | ||||
7265 | // The point of exit cannot be a branch out of the structured block. | ||||
7266 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7267 | CS->getCapturedDecl()->setNothrow(); | ||||
7268 | } | ||||
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 7269 | getCurFunction()->setHasBranchProtectedScope(); |
7270 | |||||
7271 | return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, | ||||
7272 | AStmt); | ||||
7273 | } | ||||
7274 | |||||
Kelvin Li | 83c451e | 2016-12-25 04:52:54 +0000 | [diff] [blame] | 7275 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( |
7276 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7277 | SourceLocation EndLoc, | ||||
7278 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7279 | if (!AStmt) | ||||
7280 | return StmtError(); | ||||
7281 | |||||
7282 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7283 | // 1.2.2 OpenMP Language Terminology | ||||
7284 | // Structured block - An executable statement with a single entry at the | ||||
7285 | // top and a single exit at the bottom. | ||||
7286 | // The point of exit cannot be a branch out of the structured block. | ||||
7287 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7288 | CS->getCapturedDecl()->setNothrow(); | ||||
7289 | |||||
7290 | OMPLoopDirective::HelperExprs B; | ||||
7291 | // In presence of clause 'collapse' with number of loops, it will | ||||
7292 | // define the nested loops number. | ||||
7293 | auto NestedLoopCount = CheckOpenMPLoop( | ||||
7294 | OMPD_target_teams_distribute, | ||||
7295 | getCollapseNumberExpr(Clauses), | ||||
7296 | nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, | ||||
7297 | VarsWithImplicitDSA, B); | ||||
7298 | if (NestedLoopCount == 0) | ||||
7299 | return StmtError(); | ||||
7300 | |||||
7301 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7302 | "omp target teams distribute loop exprs were not built"); | ||||
7303 | |||||
7304 | getCurFunction()->setHasBranchProtectedScope(); | ||||
7305 | return OMPTargetTeamsDistributeDirective::Create( | ||||
7306 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
7307 | } | ||||
7308 | |||||
Kelvin Li | 80e8f56 | 2016-12-29 22:16:30 +0000 | [diff] [blame] | 7309 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( |
7310 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7311 | SourceLocation EndLoc, | ||||
7312 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7313 | if (!AStmt) | ||||
7314 | return StmtError(); | ||||
7315 | |||||
7316 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7317 | // 1.2.2 OpenMP Language Terminology | ||||
7318 | // Structured block - An executable statement with a single entry at the | ||||
7319 | // top and a single exit at the bottom. | ||||
7320 | // The point of exit cannot be a branch out of the structured block. | ||||
7321 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7322 | CS->getCapturedDecl()->setNothrow(); | ||||
7323 | |||||
7324 | OMPLoopDirective::HelperExprs B; | ||||
7325 | // In presence of clause 'collapse' with number of loops, it will | ||||
7326 | // define the nested loops number. | ||||
7327 | auto NestedLoopCount = CheckOpenMPLoop( | ||||
7328 | OMPD_target_teams_distribute_parallel_for, | ||||
7329 | getCollapseNumberExpr(Clauses), | ||||
7330 | nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, | ||||
7331 | VarsWithImplicitDSA, B); | ||||
7332 | if (NestedLoopCount == 0) | ||||
7333 | return StmtError(); | ||||
7334 | |||||
7335 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7336 | "omp target teams distribute parallel for loop exprs were not built"); | ||||
7337 | |||||
Kelvin Li | 80e8f56 | 2016-12-29 22:16:30 +0000 | [diff] [blame] | 7338 | getCurFunction()->setHasBranchProtectedScope(); |
7339 | return OMPTargetTeamsDistributeParallelForDirective::Create( | ||||
Alexey Bataev | 16e7988 | 2017-11-22 21:12:03 +0000 | [diff] [blame] | 7340 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
7341 | DSAStack->isCancelRegion()); | ||||
Kelvin Li | 80e8f56 | 2016-12-29 22:16:30 +0000 | [diff] [blame] | 7342 | } |
7343 | |||||
Kelvin Li | 1851df5 | 2017-01-03 05:23:48 +0000 | [diff] [blame] | 7344 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( |
7345 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7346 | SourceLocation EndLoc, | ||||
7347 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7348 | if (!AStmt) | ||||
7349 | return StmtError(); | ||||
7350 | |||||
7351 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | ||||
7352 | // 1.2.2 OpenMP Language Terminology | ||||
7353 | // Structured block - An executable statement with a single entry at the | ||||
7354 | // top and a single exit at the bottom. | ||||
7355 | // The point of exit cannot be a branch out of the structured block. | ||||
7356 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7357 | CS->getCapturedDecl()->setNothrow(); | ||||
7358 | |||||
7359 | OMPLoopDirective::HelperExprs B; | ||||
7360 | // In presence of clause 'collapse' with number of loops, it will | ||||
7361 | // define the nested loops number. | ||||
7362 | auto NestedLoopCount = CheckOpenMPLoop( | ||||
7363 | OMPD_target_teams_distribute_parallel_for_simd, | ||||
7364 | getCollapseNumberExpr(Clauses), | ||||
7365 | nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, | ||||
7366 | VarsWithImplicitDSA, B); | ||||
7367 | if (NestedLoopCount == 0) | ||||
7368 | return StmtError(); | ||||
7369 | |||||
7370 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7371 | "omp target teams distribute parallel for simd loop exprs were not " | ||||
7372 | "built"); | ||||
7373 | |||||
7374 | if (!CurContext->isDependentContext()) { | ||||
7375 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
7376 | for (auto C : Clauses) { | ||||
7377 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||
7378 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||
7379 | B.NumIterations, *this, CurScope, | ||||
7380 | DSAStack)) | ||||
7381 | return StmtError(); | ||||
7382 | } | ||||
7383 | } | ||||
7384 | |||||
Alexey Bataev | 438388c | 2017-11-22 18:34:02 +0000 | [diff] [blame] | 7385 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
7386 | return StmtError(); | ||||
7387 | |||||
Kelvin Li | 1851df5 | 2017-01-03 05:23:48 +0000 | [diff] [blame] | 7388 | getCurFunction()->setHasBranchProtectedScope(); |
7389 | return OMPTargetTeamsDistributeParallelForSimdDirective::Create( | ||||
7390 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
7391 | } | ||||
7392 | |||||
Kelvin Li | da68118 | 2017-01-10 18:08:18 +0000 | [diff] [blame] | 7393 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( |
7394 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | ||||
7395 | SourceLocation EndLoc, | ||||
7396 | llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { | ||||
7397 | if (!AStmt) | ||||
7398 | return StmtError(); | ||||
7399 | |||||
7400 | auto *CS = cast<CapturedStmt>(AStmt); | ||||
7401 | // 1.2.2 OpenMP Language Terminology | ||||
7402 | // Structured block - An executable statement with a single entry at the | ||||
7403 | // top and a single exit at the bottom. | ||||
7404 | // The point of exit cannot be a branch out of the structured block. | ||||
7405 | // longjmp() and throw() must not violate the entry/exit criteria. | ||||
7406 | CS->getCapturedDecl()->setNothrow(); | ||||
7407 | |||||
7408 | OMPLoopDirective::HelperExprs B; | ||||
7409 | // In presence of clause 'collapse' with number of loops, it will | ||||
7410 | // define the nested loops number. | ||||
7411 | auto NestedLoopCount = CheckOpenMPLoop( | ||||
7412 | OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), | ||||
7413 | nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, | ||||
7414 | VarsWithImplicitDSA, B); | ||||
7415 | if (NestedLoopCount == 0) | ||||
7416 | return StmtError(); | ||||
7417 | |||||
7418 | assert((CurContext->isDependentContext() || B.builtAll()) && | ||||
7419 | "omp target teams distribute simd loop exprs were not built"); | ||||
7420 | |||||
Alexey Bataev | 438388c | 2017-11-22 18:34:02 +0000 | [diff] [blame] | 7421 | if (!CurContext->isDependentContext()) { |
7422 | // Finalize the clauses that need pre-built expressions for CodeGen. | ||||
7423 | for (auto C : Clauses) { | ||||
7424 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) | ||||
7425 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | ||||
7426 | B.NumIterations, *this, CurScope, | ||||
7427 | DSAStack)) | ||||
7428 | return StmtError(); | ||||
7429 | } | ||||
7430 | } | ||||
7431 | |||||
7432 | if (checkSimdlenSafelenSpecified(*this, Clauses)) | ||||
7433 | return StmtError(); | ||||
7434 | |||||
Kelvin Li | da68118 | 2017-01-10 18:08:18 +0000 | [diff] [blame] | 7435 | getCurFunction()->setHasBranchProtectedScope(); |
7436 | return OMPTargetTeamsDistributeSimdDirective::Create( | ||||
7437 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | ||||
7438 | } | ||||
7439 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 7440 | OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7441 | SourceLocation StartLoc, |
7442 | SourceLocation LParenLoc, | ||||
7443 | SourceLocation EndLoc) { | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 7444 | OMPClause *Res = nullptr; |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7445 | switch (Kind) { |
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 7446 | case OMPC_final: |
7447 | Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7448 | break; | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 7449 | case OMPC_num_threads: |
7450 | Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7451 | break; | ||||
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 7452 | case OMPC_safelen: |
7453 | Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7454 | break; | ||||
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 7455 | case OMPC_simdlen: |
7456 | Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7457 | break; | ||||
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 7458 | case OMPC_collapse: |
7459 | Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7460 | break; | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 7461 | case OMPC_ordered: |
7462 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); | ||||
7463 | break; | ||||
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 7464 | case OMPC_device: |
7465 | Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7466 | break; | ||||
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 7467 | case OMPC_num_teams: |
7468 | Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7469 | break; | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 7470 | case OMPC_thread_limit: |
7471 | Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7472 | break; | ||||
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 7473 | case OMPC_priority: |
7474 | Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7475 | break; | ||||
Alexey Bataev | 1fd4aed | 2015-12-07 12:52:51 +0000 | [diff] [blame] | 7476 | case OMPC_grainsize: |
7477 | Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7478 | break; | ||||
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 7479 | case OMPC_num_tasks: |
7480 | Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7481 | break; | ||||
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 7482 | case OMPC_hint: |
7483 | Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); | ||||
7484 | break; | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 7485 | case OMPC_if: |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7486 | case OMPC_default: |
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 7487 | case OMPC_proc_bind: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 7488 | case OMPC_schedule: |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7489 | case OMPC_private: |
7490 | case OMPC_firstprivate: | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 7491 | case OMPC_lastprivate: |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7492 | case OMPC_shared: |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 7493 | case OMPC_reduction: |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 7494 | case OMPC_task_reduction: |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 7495 | case OMPC_in_reduction: |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 7496 | case OMPC_linear: |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 7497 | case OMPC_aligned: |
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 7498 | case OMPC_copyin: |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 7499 | case OMPC_copyprivate: |
Alexey Bataev | 236070f | 2014-06-20 11:19:47 +0000 | [diff] [blame] | 7500 | case OMPC_nowait: |
Alexey Bataev | 7aea99a | 2014-07-17 12:19:31 +0000 | [diff] [blame] | 7501 | case OMPC_untied: |
Alexey Bataev | 74ba3a5 | 2014-07-17 12:47:03 +0000 | [diff] [blame] | 7502 | case OMPC_mergeable: |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7503 | case OMPC_threadprivate: |
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 7504 | case OMPC_flush: |
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 7505 | case OMPC_read: |
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 7506 | case OMPC_write: |
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 7507 | case OMPC_update: |
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 7508 | case OMPC_capture: |
Alexey Bataev | 82bad8b | 2014-07-24 08:55:34 +0000 | [diff] [blame] | 7509 | case OMPC_seq_cst: |
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 7510 | case OMPC_depend: |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 7511 | case OMPC_threads: |
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 7512 | case OMPC_simd: |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 7513 | case OMPC_map: |
Alexey Bataev | b825de1 | 2015-12-07 10:51:44 +0000 | [diff] [blame] | 7514 | case OMPC_nogroup: |
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 7515 | case OMPC_dist_schedule: |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 7516 | case OMPC_defaultmap: |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7517 | case OMPC_unknown: |
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 7518 | case OMPC_uniform: |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 7519 | case OMPC_to: |
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 7520 | case OMPC_from: |
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 7521 | case OMPC_use_device_ptr: |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 7522 | case OMPC_is_device_ptr: |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 7523 | llvm_unreachable("Clause is not allowed."); |
7524 | } | ||||
7525 | return Res; | ||||
7526 | } | ||||
7527 | |||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7528 | // An OpenMP directive such as 'target parallel' has two captured regions: |
7529 | // for the 'target' and 'parallel' respectively. This function returns | ||||
7530 | // the region in which to capture expressions associated with a clause. | ||||
7531 | // A return value of OMPD_unknown signifies that the expression should not | ||||
7532 | // be captured. | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7533 | static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( |
7534 | OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, | ||||
7535 | OpenMPDirectiveKind NameModifier = OMPD_unknown) { | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7536 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7537 | switch (CKind) { |
7538 | case OMPC_if: | ||||
7539 | switch (DKind) { | ||||
7540 | case OMPD_target_parallel: | ||||
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 7541 | case OMPD_target_parallel_for: |
Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 7542 | case OMPD_target_parallel_for_simd: |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7543 | case OMPD_target_teams_distribute_parallel_for: |
7544 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7545 | // If this clause applies to the nested 'parallel' region, capture within |
7546 | // the 'target' region, otherwise do not capture. | ||||
7547 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) | ||||
7548 | CaptureRegion = OMPD_target; | ||||
7549 | break; | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7550 | case OMPD_teams_distribute_parallel_for: |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7551 | case OMPD_teams_distribute_parallel_for_simd: |
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7552 | CaptureRegion = OMPD_teams; |
7553 | break; | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7554 | case OMPD_cancel: |
7555 | case OMPD_parallel: | ||||
7556 | case OMPD_parallel_sections: | ||||
7557 | case OMPD_parallel_for: | ||||
7558 | case OMPD_parallel_for_simd: | ||||
7559 | case OMPD_target: | ||||
7560 | case OMPD_target_simd: | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7561 | case OMPD_target_teams: |
7562 | case OMPD_target_teams_distribute: | ||||
7563 | case OMPD_target_teams_distribute_simd: | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7564 | case OMPD_distribute_parallel_for: |
7565 | case OMPD_distribute_parallel_for_simd: | ||||
7566 | case OMPD_task: | ||||
7567 | case OMPD_taskloop: | ||||
7568 | case OMPD_taskloop_simd: | ||||
7569 | case OMPD_target_data: | ||||
7570 | case OMPD_target_enter_data: | ||||
7571 | case OMPD_target_exit_data: | ||||
7572 | case OMPD_target_update: | ||||
7573 | // Do not capture if-clause expressions. | ||||
7574 | break; | ||||
7575 | case OMPD_threadprivate: | ||||
7576 | case OMPD_taskyield: | ||||
7577 | case OMPD_barrier: | ||||
7578 | case OMPD_taskwait: | ||||
7579 | case OMPD_cancellation_point: | ||||
7580 | case OMPD_flush: | ||||
7581 | case OMPD_declare_reduction: | ||||
7582 | case OMPD_declare_simd: | ||||
7583 | case OMPD_declare_target: | ||||
7584 | case OMPD_end_declare_target: | ||||
7585 | case OMPD_teams: | ||||
7586 | case OMPD_simd: | ||||
7587 | case OMPD_for: | ||||
7588 | case OMPD_for_simd: | ||||
7589 | case OMPD_sections: | ||||
7590 | case OMPD_section: | ||||
7591 | case OMPD_single: | ||||
7592 | case OMPD_master: | ||||
7593 | case OMPD_critical: | ||||
7594 | case OMPD_taskgroup: | ||||
7595 | case OMPD_distribute: | ||||
7596 | case OMPD_ordered: | ||||
7597 | case OMPD_atomic: | ||||
7598 | case OMPD_distribute_simd: | ||||
7599 | case OMPD_teams_distribute: | ||||
7600 | case OMPD_teams_distribute_simd: | ||||
7601 | llvm_unreachable("Unexpected OpenMP directive with if-clause"); | ||||
7602 | case OMPD_unknown: | ||||
7603 | llvm_unreachable("Unknown OpenMP directive"); | ||||
7604 | } | ||||
7605 | break; | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7606 | case OMPC_num_threads: |
7607 | switch (DKind) { | ||||
7608 | case OMPD_target_parallel: | ||||
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 7609 | case OMPD_target_parallel_for: |
Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 7610 | case OMPD_target_parallel_for_simd: |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7611 | case OMPD_target_teams_distribute_parallel_for: |
7612 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7613 | CaptureRegion = OMPD_target; |
7614 | break; | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7615 | case OMPD_teams_distribute_parallel_for: |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7616 | case OMPD_teams_distribute_parallel_for_simd: |
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7617 | CaptureRegion = OMPD_teams; |
7618 | break; | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7619 | case OMPD_parallel: |
7620 | case OMPD_parallel_sections: | ||||
7621 | case OMPD_parallel_for: | ||||
7622 | case OMPD_parallel_for_simd: | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7623 | case OMPD_distribute_parallel_for: |
7624 | case OMPD_distribute_parallel_for_simd: | ||||
7625 | // Do not capture num_threads-clause expressions. | ||||
7626 | break; | ||||
7627 | case OMPD_target_data: | ||||
7628 | case OMPD_target_enter_data: | ||||
7629 | case OMPD_target_exit_data: | ||||
7630 | case OMPD_target_update: | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7631 | case OMPD_target: |
7632 | case OMPD_target_simd: | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7633 | case OMPD_target_teams: |
7634 | case OMPD_target_teams_distribute: | ||||
7635 | case OMPD_target_teams_distribute_simd: | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7636 | case OMPD_cancel: |
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7637 | case OMPD_task: |
7638 | case OMPD_taskloop: | ||||
7639 | case OMPD_taskloop_simd: | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 7640 | case OMPD_threadprivate: |
7641 | case OMPD_taskyield: | ||||
7642 | case OMPD_barrier: | ||||
7643 | case OMPD_taskwait: | ||||
7644 | case OMPD_cancellation_point: | ||||
7645 | case OMPD_flush: | ||||
7646 | case OMPD_declare_reduction: | ||||
7647 | case OMPD_declare_simd: | ||||
7648 | case OMPD_declare_target: | ||||
7649 | case OMPD_end_declare_target: | ||||
7650 | case OMPD_teams: | ||||
7651 | case OMPD_simd: | ||||
7652 | case OMPD_for: | ||||
7653 | case OMPD_for_simd: | ||||
7654 | case OMPD_sections: | ||||
7655 | case OMPD_section: | ||||
7656 | case OMPD_single: | ||||
7657 | case OMPD_master: | ||||
7658 | case OMPD_critical: | ||||
7659 | case OMPD_taskgroup: | ||||
7660 | case OMPD_distribute: | ||||
7661 | case OMPD_ordered: | ||||
7662 | case OMPD_atomic: | ||||
7663 | case OMPD_distribute_simd: | ||||
7664 | case OMPD_teams_distribute: | ||||
7665 | case OMPD_teams_distribute_simd: | ||||
7666 | llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); | ||||
7667 | case OMPD_unknown: | ||||
7668 | llvm_unreachable("Unknown OpenMP directive"); | ||||
7669 | } | ||||
7670 | break; | ||||
Arpith Chacko Jacob | bc12634 | 2017-01-25 11:28:18 +0000 | [diff] [blame] | 7671 | case OMPC_num_teams: |
7672 | switch (DKind) { | ||||
7673 | case OMPD_target_teams: | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7674 | case OMPD_target_teams_distribute: |
7675 | case OMPD_target_teams_distribute_simd: | ||||
7676 | case OMPD_target_teams_distribute_parallel_for: | ||||
7677 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||
Arpith Chacko Jacob | bc12634 | 2017-01-25 11:28:18 +0000 | [diff] [blame] | 7678 | CaptureRegion = OMPD_target; |
7679 | break; | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7680 | case OMPD_teams_distribute_parallel_for: |
7681 | case OMPD_teams_distribute_parallel_for_simd: | ||||
7682 | case OMPD_teams: | ||||
7683 | case OMPD_teams_distribute: | ||||
7684 | case OMPD_teams_distribute_simd: | ||||
7685 | // Do not capture num_teams-clause expressions. | ||||
7686 | break; | ||||
7687 | case OMPD_distribute_parallel_for: | ||||
7688 | case OMPD_distribute_parallel_for_simd: | ||||
7689 | case OMPD_task: | ||||
7690 | case OMPD_taskloop: | ||||
7691 | case OMPD_taskloop_simd: | ||||
7692 | case OMPD_target_data: | ||||
7693 | case OMPD_target_enter_data: | ||||
7694 | case OMPD_target_exit_data: | ||||
7695 | case OMPD_target_update: | ||||
Arpith Chacko Jacob | bc12634 | 2017-01-25 11:28:18 +0000 | [diff] [blame] | 7696 | case OMPD_cancel: |
7697 | case OMPD_parallel: | ||||
7698 | case OMPD_parallel_sections: | ||||
7699 | case OMPD_parallel_for: | ||||
7700 | case OMPD_parallel_for_simd: | ||||
7701 | case OMPD_target: | ||||
7702 | case OMPD_target_simd: | ||||
7703 | case OMPD_target_parallel: | ||||
7704 | case OMPD_target_parallel_for: | ||||
7705 | case OMPD_target_parallel_for_simd: | ||||
Arpith Chacko Jacob | bc12634 | 2017-01-25 11:28:18 +0000 | [diff] [blame] | 7706 | case OMPD_threadprivate: |
7707 | case OMPD_taskyield: | ||||
7708 | case OMPD_barrier: | ||||
7709 | case OMPD_taskwait: | ||||
7710 | case OMPD_cancellation_point: | ||||
7711 | case OMPD_flush: | ||||
7712 | case OMPD_declare_reduction: | ||||
7713 | case OMPD_declare_simd: | ||||
7714 | case OMPD_declare_target: | ||||
7715 | case OMPD_end_declare_target: | ||||
7716 | case OMPD_simd: | ||||
7717 | case OMPD_for: | ||||
7718 | case OMPD_for_simd: | ||||
7719 | case OMPD_sections: | ||||
7720 | case OMPD_section: | ||||
7721 | case OMPD_single: | ||||
7722 | case OMPD_master: | ||||
7723 | case OMPD_critical: | ||||
7724 | case OMPD_taskgroup: | ||||
7725 | case OMPD_distribute: | ||||
7726 | case OMPD_ordered: | ||||
7727 | case OMPD_atomic: | ||||
7728 | case OMPD_distribute_simd: | ||||
7729 | llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); | ||||
7730 | case OMPD_unknown: | ||||
7731 | llvm_unreachable("Unknown OpenMP directive"); | ||||
7732 | } | ||||
7733 | break; | ||||
Arpith Chacko Jacob | 7ecc0b7 | 2017-01-25 11:44:35 +0000 | [diff] [blame] | 7734 | case OMPC_thread_limit: |
7735 | switch (DKind) { | ||||
7736 | case OMPD_target_teams: | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7737 | case OMPD_target_teams_distribute: |
7738 | case OMPD_target_teams_distribute_simd: | ||||
7739 | case OMPD_target_teams_distribute_parallel_for: | ||||
7740 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||
Arpith Chacko Jacob | 7ecc0b7 | 2017-01-25 11:44:35 +0000 | [diff] [blame] | 7741 | CaptureRegion = OMPD_target; |
7742 | break; | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7743 | case OMPD_teams_distribute_parallel_for: |
7744 | case OMPD_teams_distribute_parallel_for_simd: | ||||
7745 | case OMPD_teams: | ||||
7746 | case OMPD_teams_distribute: | ||||
7747 | case OMPD_teams_distribute_simd: | ||||
7748 | // Do not capture thread_limit-clause expressions. | ||||
7749 | break; | ||||
7750 | case OMPD_distribute_parallel_for: | ||||
7751 | case OMPD_distribute_parallel_for_simd: | ||||
7752 | case OMPD_task: | ||||
7753 | case OMPD_taskloop: | ||||
7754 | case OMPD_taskloop_simd: | ||||
7755 | case OMPD_target_data: | ||||
7756 | case OMPD_target_enter_data: | ||||
7757 | case OMPD_target_exit_data: | ||||
7758 | case OMPD_target_update: | ||||
Arpith Chacko Jacob | 7ecc0b7 | 2017-01-25 11:44:35 +0000 | [diff] [blame] | 7759 | case OMPD_cancel: |
7760 | case OMPD_parallel: | ||||
7761 | case OMPD_parallel_sections: | ||||
7762 | case OMPD_parallel_for: | ||||
7763 | case OMPD_parallel_for_simd: | ||||
7764 | case OMPD_target: | ||||
7765 | case OMPD_target_simd: | ||||
7766 | case OMPD_target_parallel: | ||||
7767 | case OMPD_target_parallel_for: | ||||
7768 | case OMPD_target_parallel_for_simd: | ||||
Arpith Chacko Jacob | 7ecc0b7 | 2017-01-25 11:44:35 +0000 | [diff] [blame] | 7769 | case OMPD_threadprivate: |
7770 | case OMPD_taskyield: | ||||
7771 | case OMPD_barrier: | ||||
7772 | case OMPD_taskwait: | ||||
7773 | case OMPD_cancellation_point: | ||||
7774 | case OMPD_flush: | ||||
7775 | case OMPD_declare_reduction: | ||||
7776 | case OMPD_declare_simd: | ||||
7777 | case OMPD_declare_target: | ||||
7778 | case OMPD_end_declare_target: | ||||
7779 | case OMPD_simd: | ||||
7780 | case OMPD_for: | ||||
7781 | case OMPD_for_simd: | ||||
7782 | case OMPD_sections: | ||||
7783 | case OMPD_section: | ||||
7784 | case OMPD_single: | ||||
7785 | case OMPD_master: | ||||
7786 | case OMPD_critical: | ||||
7787 | case OMPD_taskgroup: | ||||
7788 | case OMPD_distribute: | ||||
7789 | case OMPD_ordered: | ||||
7790 | case OMPD_atomic: | ||||
7791 | case OMPD_distribute_simd: | ||||
7792 | llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); | ||||
7793 | case OMPD_unknown: | ||||
7794 | llvm_unreachable("Unknown OpenMP directive"); | ||||
7795 | } | ||||
7796 | break; | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7797 | case OMPC_schedule: |
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 7798 | switch (DKind) { |
7799 | case OMPD_target_parallel_for: | ||||
Alexey Bataev | 5d7edca | 2017-11-09 17:32:15 +0000 | [diff] [blame] | 7800 | case OMPD_target_parallel_for_simd: |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7801 | case OMPD_target_teams_distribute_parallel_for: |
7802 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 7803 | CaptureRegion = OMPD_target; |
7804 | break; | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7805 | case OMPD_teams_distribute_parallel_for: |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7806 | case OMPD_teams_distribute_parallel_for_simd: |
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7807 | CaptureRegion = OMPD_teams; |
7808 | break; | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7809 | case OMPD_parallel_for: |
7810 | case OMPD_parallel_for_simd: | ||||
Alexey Bataev | 7f96c37 | 2017-11-22 17:19:31 +0000 | [diff] [blame] | 7811 | case OMPD_distribute_parallel_for: |
Alexey Bataev | 974acd6 | 2017-11-27 19:38:52 +0000 | [diff] [blame] | 7812 | case OMPD_distribute_parallel_for_simd: |
Alexey Bataev | 7f96c37 | 2017-11-22 17:19:31 +0000 | [diff] [blame] | 7813 | CaptureRegion = OMPD_parallel; |
7814 | break; | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7815 | case OMPD_for: |
7816 | case OMPD_for_simd: | ||||
7817 | // Do not capture schedule-clause expressions. | ||||
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 7818 | break; |
7819 | case OMPD_task: | ||||
7820 | case OMPD_taskloop: | ||||
7821 | case OMPD_taskloop_simd: | ||||
7822 | case OMPD_target_data: | ||||
7823 | case OMPD_target_enter_data: | ||||
7824 | case OMPD_target_exit_data: | ||||
7825 | case OMPD_target_update: | ||||
7826 | case OMPD_teams: | ||||
7827 | case OMPD_teams_distribute: | ||||
7828 | case OMPD_teams_distribute_simd: | ||||
7829 | case OMPD_target_teams_distribute: | ||||
7830 | case OMPD_target_teams_distribute_simd: | ||||
7831 | case OMPD_target: | ||||
7832 | case OMPD_target_simd: | ||||
7833 | case OMPD_target_parallel: | ||||
7834 | case OMPD_cancel: | ||||
7835 | case OMPD_parallel: | ||||
7836 | case OMPD_parallel_sections: | ||||
7837 | case OMPD_threadprivate: | ||||
7838 | case OMPD_taskyield: | ||||
7839 | case OMPD_barrier: | ||||
7840 | case OMPD_taskwait: | ||||
7841 | case OMPD_cancellation_point: | ||||
7842 | case OMPD_flush: | ||||
7843 | case OMPD_declare_reduction: | ||||
7844 | case OMPD_declare_simd: | ||||
7845 | case OMPD_declare_target: | ||||
7846 | case OMPD_end_declare_target: | ||||
7847 | case OMPD_simd: | ||||
Alexey Bataev | fb0ebec | 2017-11-08 20:16:14 +0000 | [diff] [blame] | 7848 | case OMPD_sections: |
7849 | case OMPD_section: | ||||
7850 | case OMPD_single: | ||||
7851 | case OMPD_master: | ||||
7852 | case OMPD_critical: | ||||
7853 | case OMPD_taskgroup: | ||||
7854 | case OMPD_distribute: | ||||
7855 | case OMPD_ordered: | ||||
7856 | case OMPD_atomic: | ||||
7857 | case OMPD_distribute_simd: | ||||
7858 | case OMPD_target_teams: | ||||
7859 | llvm_unreachable("Unexpected OpenMP directive with schedule clause"); | ||||
7860 | case OMPD_unknown: | ||||
7861 | llvm_unreachable("Unknown OpenMP directive"); | ||||
7862 | } | ||||
7863 | break; | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7864 | case OMPC_dist_schedule: |
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7865 | switch (DKind) { |
7866 | case OMPD_teams_distribute_parallel_for: | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7867 | case OMPD_teams_distribute_parallel_for_simd: |
7868 | case OMPD_teams_distribute: | ||||
7869 | case OMPD_teams_distribute_simd: | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7870 | CaptureRegion = OMPD_teams; |
7871 | break; | ||||
7872 | case OMPD_target_teams_distribute_parallel_for: | ||||
7873 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7874 | case OMPD_target_teams_distribute: |
7875 | case OMPD_target_teams_distribute_simd: | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7876 | CaptureRegion = OMPD_target; |
7877 | break; | ||||
7878 | case OMPD_distribute_parallel_for: | ||||
7879 | case OMPD_distribute_parallel_for_simd: | ||||
7880 | CaptureRegion = OMPD_parallel; | ||||
7881 | break; | ||||
7882 | case OMPD_distribute: | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7883 | case OMPD_distribute_simd: |
7884 | // Do not capture thread_limit-clause expressions. | ||||
7885 | break; | ||||
7886 | case OMPD_parallel_for: | ||||
7887 | case OMPD_parallel_for_simd: | ||||
7888 | case OMPD_target_parallel_for_simd: | ||||
7889 | case OMPD_target_parallel_for: | ||||
7890 | case OMPD_task: | ||||
7891 | case OMPD_taskloop: | ||||
7892 | case OMPD_taskloop_simd: | ||||
7893 | case OMPD_target_data: | ||||
7894 | case OMPD_target_enter_data: | ||||
7895 | case OMPD_target_exit_data: | ||||
7896 | case OMPD_target_update: | ||||
7897 | case OMPD_teams: | ||||
7898 | case OMPD_target: | ||||
7899 | case OMPD_target_simd: | ||||
7900 | case OMPD_target_parallel: | ||||
7901 | case OMPD_cancel: | ||||
7902 | case OMPD_parallel: | ||||
7903 | case OMPD_parallel_sections: | ||||
7904 | case OMPD_threadprivate: | ||||
7905 | case OMPD_taskyield: | ||||
7906 | case OMPD_barrier: | ||||
7907 | case OMPD_taskwait: | ||||
7908 | case OMPD_cancellation_point: | ||||
7909 | case OMPD_flush: | ||||
7910 | case OMPD_declare_reduction: | ||||
7911 | case OMPD_declare_simd: | ||||
7912 | case OMPD_declare_target: | ||||
7913 | case OMPD_end_declare_target: | ||||
7914 | case OMPD_simd: | ||||
7915 | case OMPD_for: | ||||
7916 | case OMPD_for_simd: | ||||
7917 | case OMPD_sections: | ||||
7918 | case OMPD_section: | ||||
7919 | case OMPD_single: | ||||
7920 | case OMPD_master: | ||||
7921 | case OMPD_critical: | ||||
7922 | case OMPD_taskgroup: | ||||
Carlo Bertolli | 62fae15 | 2017-11-20 20:46:39 +0000 | [diff] [blame] | 7923 | case OMPD_ordered: |
7924 | case OMPD_atomic: | ||||
7925 | case OMPD_target_teams: | ||||
7926 | llvm_unreachable("Unexpected OpenMP directive with schedule clause"); | ||||
7927 | case OMPD_unknown: | ||||
7928 | llvm_unreachable("Unknown OpenMP directive"); | ||||
7929 | } | ||||
7930 | break; | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 7931 | case OMPC_device: |
7932 | switch (DKind) { | ||||
7933 | case OMPD_target_teams: | ||||
7934 | case OMPD_target_teams_distribute: | ||||
7935 | case OMPD_target_teams_distribute_simd: | ||||
7936 | case OMPD_target_teams_distribute_parallel_for: | ||||
7937 | case OMPD_target_teams_distribute_parallel_for_simd: | ||||
7938 | case OMPD_target_data: | ||||
7939 | case OMPD_target_enter_data: | ||||
7940 | case OMPD_target_exit_data: | ||||
7941 | case OMPD_target_update: | ||||
7942 | case OMPD_target: | ||||
7943 | case OMPD_target_simd: | ||||
7944 | case OMPD_target_parallel: | ||||
7945 | case OMPD_target_parallel_for: | ||||
7946 | case OMPD_target_parallel_for_simd: | ||||
7947 | // Do not capture device-clause expressions. | ||||
7948 | break; | ||||
7949 | case OMPD_teams_distribute_parallel_for: | ||||
7950 | case OMPD_teams_distribute_parallel_for_simd: | ||||
7951 | case OMPD_teams: | ||||
7952 | case OMPD_teams_distribute: | ||||
7953 | case OMPD_teams_distribute_simd: | ||||
7954 | case OMPD_distribute_parallel_for: | ||||
7955 | case OMPD_distribute_parallel_for_simd: | ||||
7956 | case OMPD_task: | ||||
7957 | case OMPD_taskloop: | ||||
7958 | case OMPD_taskloop_simd: | ||||
7959 | case OMPD_cancel: | ||||
7960 | case OMPD_parallel: | ||||
7961 | case OMPD_parallel_sections: | ||||
7962 | case OMPD_parallel_for: | ||||
7963 | case OMPD_parallel_for_simd: | ||||
7964 | case OMPD_threadprivate: | ||||
7965 | case OMPD_taskyield: | ||||
7966 | case OMPD_barrier: | ||||
7967 | case OMPD_taskwait: | ||||
7968 | case OMPD_cancellation_point: | ||||
7969 | case OMPD_flush: | ||||
7970 | case OMPD_declare_reduction: | ||||
7971 | case OMPD_declare_simd: | ||||
7972 | case OMPD_declare_target: | ||||
7973 | case OMPD_end_declare_target: | ||||
7974 | case OMPD_simd: | ||||
7975 | case OMPD_for: | ||||
7976 | case OMPD_for_simd: | ||||
7977 | case OMPD_sections: | ||||
7978 | case OMPD_section: | ||||
7979 | case OMPD_single: | ||||
7980 | case OMPD_master: | ||||
7981 | case OMPD_critical: | ||||
7982 | case OMPD_taskgroup: | ||||
7983 | case OMPD_distribute: | ||||
7984 | case OMPD_ordered: | ||||
7985 | case OMPD_atomic: | ||||
7986 | case OMPD_distribute_simd: | ||||
7987 | llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); | ||||
7988 | case OMPD_unknown: | ||||
7989 | llvm_unreachable("Unknown OpenMP directive"); | ||||
7990 | } | ||||
7991 | break; | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7992 | case OMPC_firstprivate: |
7993 | case OMPC_lastprivate: | ||||
7994 | case OMPC_reduction: | ||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 7995 | case OMPC_task_reduction: |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 7996 | case OMPC_in_reduction: |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 7997 | case OMPC_linear: |
7998 | case OMPC_default: | ||||
7999 | case OMPC_proc_bind: | ||||
8000 | case OMPC_final: | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 8001 | case OMPC_safelen: |
8002 | case OMPC_simdlen: | ||||
8003 | case OMPC_collapse: | ||||
8004 | case OMPC_private: | ||||
8005 | case OMPC_shared: | ||||
8006 | case OMPC_aligned: | ||||
8007 | case OMPC_copyin: | ||||
8008 | case OMPC_copyprivate: | ||||
8009 | case OMPC_ordered: | ||||
8010 | case OMPC_nowait: | ||||
8011 | case OMPC_untied: | ||||
8012 | case OMPC_mergeable: | ||||
8013 | case OMPC_threadprivate: | ||||
8014 | case OMPC_flush: | ||||
8015 | case OMPC_read: | ||||
8016 | case OMPC_write: | ||||
8017 | case OMPC_update: | ||||
8018 | case OMPC_capture: | ||||
8019 | case OMPC_seq_cst: | ||||
8020 | case OMPC_depend: | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 8021 | case OMPC_threads: |
8022 | case OMPC_simd: | ||||
8023 | case OMPC_map: | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 8024 | case OMPC_priority: |
8025 | case OMPC_grainsize: | ||||
8026 | case OMPC_nogroup: | ||||
8027 | case OMPC_num_tasks: | ||||
8028 | case OMPC_hint: | ||||
8029 | case OMPC_defaultmap: | ||||
8030 | case OMPC_unknown: | ||||
8031 | case OMPC_uniform: | ||||
8032 | case OMPC_to: | ||||
8033 | case OMPC_from: | ||||
8034 | case OMPC_use_device_ptr: | ||||
8035 | case OMPC_is_device_ptr: | ||||
8036 | llvm_unreachable("Unexpected OpenMP clause."); | ||||
8037 | } | ||||
8038 | return CaptureRegion; | ||||
8039 | } | ||||
8040 | |||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 8041 | OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, |
8042 | Expr *Condition, SourceLocation StartLoc, | ||||
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8043 | SourceLocation LParenLoc, |
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 8044 | SourceLocation NameModifierLoc, |
8045 | SourceLocation ColonLoc, | ||||
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8046 | SourceLocation EndLoc) { |
8047 | Expr *ValExpr = Condition; | ||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 8048 | Stmt *HelperValStmt = nullptr; |
8049 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; | ||||
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8050 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && |
8051 | !Condition->isInstantiationDependent() && | ||||
8052 | !Condition->containsUnexpandedParameterPack()) { | ||||
Richard Smith | 03a4aa3 | 2016-06-23 19:02:52 +0000 | [diff] [blame] | 8053 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8054 | if (Val.isInvalid()) |
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 8055 | return nullptr; |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8056 | |
Richard Smith | 03a4aa3 | 2016-06-23 19:02:52 +0000 | [diff] [blame] | 8057 | ValExpr = MakeFullExpr(Val.get()).get(); |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 8058 | |
8059 | OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); | ||||
8060 | CaptureRegion = | ||||
8061 | getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 8062 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { |
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 8063 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
8064 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||
8065 | HelperValStmt = buildPreInits(Context, Captures); | ||||
8066 | } | ||||
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8067 | } |
8068 | |||||
Arpith Chacko Jacob | fe4890a | 2017-01-18 20:40:48 +0000 | [diff] [blame] | 8069 | return new (Context) |
8070 | OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, | ||||
8071 | LParenLoc, NameModifierLoc, ColonLoc, EndLoc); | ||||
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8072 | } |
8073 | |||||
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 8074 | OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, |
8075 | SourceLocation StartLoc, | ||||
8076 | SourceLocation LParenLoc, | ||||
8077 | SourceLocation EndLoc) { | ||||
8078 | Expr *ValExpr = Condition; | ||||
8079 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && | ||||
8080 | !Condition->isInstantiationDependent() && | ||||
8081 | !Condition->containsUnexpandedParameterPack()) { | ||||
Richard Smith | 03a4aa3 | 2016-06-23 19:02:52 +0000 | [diff] [blame] | 8082 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); |
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 8083 | if (Val.isInvalid()) |
8084 | return nullptr; | ||||
8085 | |||||
Richard Smith | 03a4aa3 | 2016-06-23 19:02:52 +0000 | [diff] [blame] | 8086 | ValExpr = MakeFullExpr(Val.get()).get(); |
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 8087 | } |
8088 | |||||
8089 | return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); | ||||
8090 | } | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 8091 | ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, |
8092 | Expr *Op) { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8093 | if (!Op) |
8094 | return ExprError(); | ||||
8095 | |||||
8096 | class IntConvertDiagnoser : public ICEConvertDiagnoser { | ||||
8097 | public: | ||||
8098 | IntConvertDiagnoser() | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8099 | : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} |
Craig Topper | e14c0f8 | 2014-03-12 04:55:44 +0000 | [diff] [blame] | 8100 | SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, |
8101 | QualType T) override { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8102 | return S.Diag(Loc, diag::err_omp_not_integral) << T; |
8103 | } | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8104 | SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, |
8105 | QualType T) override { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8106 | return S.Diag(Loc, diag::err_omp_incomplete_type) << T; |
8107 | } | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8108 | SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, |
8109 | QualType T, | ||||
8110 | QualType ConvTy) override { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8111 | return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; |
8112 | } | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8113 | SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, |
8114 | QualType ConvTy) override { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8115 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8116 | << ConvTy->isEnumeralType() << ConvTy; |
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8117 | } |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8118 | SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, |
8119 | QualType T) override { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8120 | return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; |
8121 | } | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8122 | SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, |
8123 | QualType ConvTy) override { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8124 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8125 | << ConvTy->isEnumeralType() << ConvTy; |
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8126 | } |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8127 | SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, |
8128 | QualType) override { | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8129 | llvm_unreachable("conversion functions are permitted"); |
8130 | } | ||||
8131 | } ConvertDiagnoser; | ||||
8132 | return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); | ||||
8133 | } | ||||
8134 | |||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8135 | static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, |
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8136 | OpenMPClauseKind CKind, |
8137 | bool StrictlyPositive) { | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8138 | if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && |
8139 | !ValExpr->isInstantiationDependent()) { | ||||
8140 | SourceLocation Loc = ValExpr->getExprLoc(); | ||||
8141 | ExprResult Value = | ||||
8142 | SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); | ||||
8143 | if (Value.isInvalid()) | ||||
8144 | return false; | ||||
8145 | |||||
8146 | ValExpr = Value.get(); | ||||
8147 | // The expression must evaluate to a non-negative integer value. | ||||
8148 | llvm::APSInt Result; | ||||
8149 | if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && | ||||
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8150 | Result.isSigned() && |
8151 | !((!StrictlyPositive && Result.isNonNegative()) || | ||||
8152 | (StrictlyPositive && Result.isStrictlyPositive()))) { | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8153 | SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) |
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8154 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) |
8155 | << ValExpr->getSourceRange(); | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8156 | return false; |
8157 | } | ||||
8158 | } | ||||
8159 | return true; | ||||
8160 | } | ||||
8161 | |||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8162 | OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, |
8163 | SourceLocation StartLoc, | ||||
8164 | SourceLocation LParenLoc, | ||||
8165 | SourceLocation EndLoc) { | ||||
8166 | Expr *ValExpr = NumThreads; | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 8167 | Stmt *HelperValStmt = nullptr; |
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8168 | |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8169 | // OpenMP [2.5, Restrictions] |
8170 | // The num_threads expression must evaluate to a positive integer value. | ||||
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8171 | if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, |
8172 | /*StrictlyPositive=*/true)) | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8173 | return nullptr; |
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8174 | |
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 8175 | OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 8176 | OpenMPDirectiveKind CaptureRegion = |
8177 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); | ||||
8178 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||
Arpith Chacko Jacob | 33c849a | 2017-01-25 00:57:16 +0000 | [diff] [blame] | 8179 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
8180 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||
8181 | HelperValStmt = buildPreInits(Context, Captures); | ||||
8182 | } | ||||
8183 | |||||
8184 | return new (Context) OMPNumThreadsClause( | ||||
8185 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); | ||||
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8186 | } |
8187 | |||||
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8188 | ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 8189 | OpenMPClauseKind CKind, |
8190 | bool StrictlyPositive) { | ||||
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8191 | if (!E) |
8192 | return ExprError(); | ||||
8193 | if (E->isValueDependent() || E->isTypeDependent() || | ||||
8194 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) | ||||
Nikola Smiljanic | 03ff259 | 2014-05-29 14:05:12 +0000 | [diff] [blame] | 8195 | return E; |
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8196 | llvm::APSInt Result; |
8197 | ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); | ||||
8198 | if (ICE.isInvalid()) | ||||
8199 | return ExprError(); | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 8200 | if ((StrictlyPositive && !Result.isStrictlyPositive()) || |
8201 | (!StrictlyPositive && !Result.isNonNegative())) { | ||||
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8202 | Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 8203 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) |
8204 | << E->getSourceRange(); | ||||
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8205 | return ExprError(); |
8206 | } | ||||
Alexander Musman | 09184fe | 2014-09-30 05:29:28 +0000 | [diff] [blame] | 8207 | if (CKind == OMPC_aligned && !Result.isPowerOf2()) { |
8208 | Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) | ||||
8209 | << E->getSourceRange(); | ||||
8210 | return ExprError(); | ||||
8211 | } | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 8212 | if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) |
8213 | DSAStack->setAssociatedLoops(Result.getExtValue()); | ||||
Alexey Bataev | 7b6bc88 | 2015-11-26 07:50:39 +0000 | [diff] [blame] | 8214 | else if (CKind == OMPC_ordered) |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 8215 | DSAStack->setAssociatedLoops(Result.getExtValue()); |
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8216 | return ICE; |
8217 | } | ||||
8218 | |||||
8219 | OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, | ||||
8220 | SourceLocation LParenLoc, | ||||
8221 | SourceLocation EndLoc) { | ||||
8222 | // OpenMP [2.8.1, simd construct, Description] | ||||
8223 | // The parameter of the safelen clause must be a constant | ||||
8224 | // positive integer expression. | ||||
8225 | ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); | ||||
8226 | if (Safelen.isInvalid()) | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 8227 | return nullptr; |
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8228 | return new (Context) |
Nikola Smiljanic | 01a7598 | 2014-05-29 10:55:11 +0000 | [diff] [blame] | 8229 | OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); |
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8230 | } |
8231 | |||||
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 8232 | OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, |
8233 | SourceLocation LParenLoc, | ||||
8234 | SourceLocation EndLoc) { | ||||
8235 | // OpenMP [2.8.1, simd construct, Description] | ||||
8236 | // The parameter of the simdlen clause must be a constant | ||||
8237 | // positive integer expression. | ||||
8238 | ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); | ||||
8239 | if (Simdlen.isInvalid()) | ||||
8240 | return nullptr; | ||||
8241 | return new (Context) | ||||
8242 | OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); | ||||
8243 | } | ||||
8244 | |||||
Alexander Musman | 64d33f1 | 2014-06-04 07:53:32 +0000 | [diff] [blame] | 8245 | OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, |
8246 | SourceLocation StartLoc, | ||||
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 8247 | SourceLocation LParenLoc, |
8248 | SourceLocation EndLoc) { | ||||
Alexander Musman | 64d33f1 | 2014-06-04 07:53:32 +0000 | [diff] [blame] | 8249 | // OpenMP [2.7.1, loop construct, Description] |
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 8250 | // OpenMP [2.8.1, simd construct, Description] |
Alexander Musman | 64d33f1 | 2014-06-04 07:53:32 +0000 | [diff] [blame] | 8251 | // OpenMP [2.9.6, distribute construct, Description] |
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 8252 | // The parameter of the collapse clause must be a constant |
8253 | // positive integer expression. | ||||
Alexander Musman | 64d33f1 | 2014-06-04 07:53:32 +0000 | [diff] [blame] | 8254 | ExprResult NumForLoopsResult = |
8255 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); | ||||
8256 | if (NumForLoopsResult.isInvalid()) | ||||
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 8257 | return nullptr; |
8258 | return new (Context) | ||||
Alexander Musman | 64d33f1 | 2014-06-04 07:53:32 +0000 | [diff] [blame] | 8259 | OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); |
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 8260 | } |
8261 | |||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 8262 | OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, |
8263 | SourceLocation EndLoc, | ||||
8264 | SourceLocation LParenLoc, | ||||
8265 | Expr *NumForLoops) { | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 8266 | // OpenMP [2.7.1, loop construct, Description] |
8267 | // OpenMP [2.8.1, simd construct, Description] | ||||
8268 | // OpenMP [2.9.6, distribute construct, Description] | ||||
8269 | // The parameter of the ordered clause must be a constant | ||||
8270 | // positive integer expression if any. | ||||
8271 | if (NumForLoops && LParenLoc.isValid()) { | ||||
8272 | ExprResult NumForLoopsResult = | ||||
8273 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); | ||||
8274 | if (NumForLoopsResult.isInvalid()) | ||||
8275 | return nullptr; | ||||
8276 | NumForLoops = NumForLoopsResult.get(); | ||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 8277 | } else |
8278 | NumForLoops = nullptr; | ||||
8279 | DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); | ||||
Alexey Bataev | 10e775f | 2015-07-30 11:36:16 +0000 | [diff] [blame] | 8280 | return new (Context) |
8281 | OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); | ||||
8282 | } | ||||
8283 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8284 | OMPClause *Sema::ActOnOpenMPSimpleClause( |
8285 | OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, | ||||
8286 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 8287 | OMPClause *Res = nullptr; |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8288 | switch (Kind) { |
8289 | case OMPC_default: | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8290 | Res = |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8291 | ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), |
8292 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8293 | break; |
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 8294 | case OMPC_proc_bind: |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8295 | Res = ActOnOpenMPProcBindClause( |
8296 | static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, | ||||
8297 | LParenLoc, EndLoc); | ||||
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 8298 | break; |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8299 | case OMPC_if: |
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 8300 | case OMPC_final: |
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8301 | case OMPC_num_threads: |
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8302 | case OMPC_safelen: |
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 8303 | case OMPC_simdlen: |
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 8304 | case OMPC_collapse: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8305 | case OMPC_schedule: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8306 | case OMPC_private: |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 8307 | case OMPC_firstprivate: |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 8308 | case OMPC_lastprivate: |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8309 | case OMPC_shared: |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 8310 | case OMPC_reduction: |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 8311 | case OMPC_task_reduction: |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 8312 | case OMPC_in_reduction: |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 8313 | case OMPC_linear: |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 8314 | case OMPC_aligned: |
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 8315 | case OMPC_copyin: |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 8316 | case OMPC_copyprivate: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8317 | case OMPC_ordered: |
Alexey Bataev | 236070f | 2014-06-20 11:19:47 +0000 | [diff] [blame] | 8318 | case OMPC_nowait: |
Alexey Bataev | 7aea99a | 2014-07-17 12:19:31 +0000 | [diff] [blame] | 8319 | case OMPC_untied: |
Alexey Bataev | 74ba3a5 | 2014-07-17 12:47:03 +0000 | [diff] [blame] | 8320 | case OMPC_mergeable: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8321 | case OMPC_threadprivate: |
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 8322 | case OMPC_flush: |
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 8323 | case OMPC_read: |
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 8324 | case OMPC_write: |
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 8325 | case OMPC_update: |
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 8326 | case OMPC_capture: |
Alexey Bataev | 82bad8b | 2014-07-24 08:55:34 +0000 | [diff] [blame] | 8327 | case OMPC_seq_cst: |
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 8328 | case OMPC_depend: |
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 8329 | case OMPC_device: |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 8330 | case OMPC_threads: |
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 8331 | case OMPC_simd: |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 8332 | case OMPC_map: |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 8333 | case OMPC_num_teams: |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8334 | case OMPC_thread_limit: |
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8335 | case OMPC_priority: |
Alexey Bataev | 1fd4aed | 2015-12-07 12:52:51 +0000 | [diff] [blame] | 8336 | case OMPC_grainsize: |
Alexey Bataev | b825de1 | 2015-12-07 10:51:44 +0000 | [diff] [blame] | 8337 | case OMPC_nogroup: |
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 8338 | case OMPC_num_tasks: |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 8339 | case OMPC_hint: |
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 8340 | case OMPC_dist_schedule: |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 8341 | case OMPC_defaultmap: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8342 | case OMPC_unknown: |
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 8343 | case OMPC_uniform: |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 8344 | case OMPC_to: |
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 8345 | case OMPC_from: |
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 8346 | case OMPC_use_device_ptr: |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 8347 | case OMPC_is_device_ptr: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8348 | llvm_unreachable("Clause is not allowed."); |
8349 | } | ||||
8350 | return Res; | ||||
8351 | } | ||||
8352 | |||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8353 | static std::string |
8354 | getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, | ||||
8355 | ArrayRef<unsigned> Exclude = llvm::None) { | ||||
8356 | std::string Values; | ||||
8357 | unsigned Bound = Last >= 2 ? Last - 2 : 0; | ||||
8358 | unsigned Skipped = Exclude.size(); | ||||
8359 | auto S = Exclude.begin(), E = Exclude.end(); | ||||
8360 | for (unsigned i = First; i < Last; ++i) { | ||||
8361 | if (std::find(S, E, i) != E) { | ||||
8362 | --Skipped; | ||||
8363 | continue; | ||||
8364 | } | ||||
8365 | Values += "'"; | ||||
8366 | Values += getOpenMPSimpleClauseTypeName(K, i); | ||||
8367 | Values += "'"; | ||||
8368 | if (i == Bound - Skipped) | ||||
8369 | Values += " or "; | ||||
8370 | else if (i != Bound + 1 - Skipped) | ||||
8371 | Values += ", "; | ||||
8372 | } | ||||
8373 | return Values; | ||||
8374 | } | ||||
8375 | |||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8376 | OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, |
8377 | SourceLocation KindKwLoc, | ||||
8378 | SourceLocation StartLoc, | ||||
8379 | SourceLocation LParenLoc, | ||||
8380 | SourceLocation EndLoc) { | ||||
8381 | if (Kind == OMPC_DEFAULT_unknown) { | ||||
Alexey Bataev | 4ca40ed | 2014-05-12 04:23:46 +0000 | [diff] [blame] | 8382 | static_assert(OMPC_DEFAULT_unknown > 0, |
8383 | "OMPC_DEFAULT_unknown not greater than 0"); | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8384 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8385 | << getListOfPossibleValues(OMPC_default, /*First=*/0, |
8386 | /*Last=*/OMPC_DEFAULT_unknown) | ||||
8387 | << getOpenMPClauseName(OMPC_default); | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 8388 | return nullptr; |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8389 | } |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8390 | switch (Kind) { |
8391 | case OMPC_DEFAULT_none: | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 8392 | DSAStack->setDefaultDSANone(KindKwLoc); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8393 | break; |
8394 | case OMPC_DEFAULT_shared: | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 8395 | DSAStack->setDefaultDSAShared(KindKwLoc); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8396 | break; |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8397 | case OMPC_DEFAULT_unknown: |
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8398 | llvm_unreachable("Clause kind is not allowed."); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8399 | break; |
8400 | } | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8401 | return new (Context) |
8402 | OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8403 | } |
8404 | |||||
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 8405 | OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, |
8406 | SourceLocation KindKwLoc, | ||||
8407 | SourceLocation StartLoc, | ||||
8408 | SourceLocation LParenLoc, | ||||
8409 | SourceLocation EndLoc) { | ||||
8410 | if (Kind == OMPC_PROC_BIND_unknown) { | ||||
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 8411 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8412 | << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, |
8413 | /*Last=*/OMPC_PROC_BIND_unknown) | ||||
8414 | << getOpenMPClauseName(OMPC_proc_bind); | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 8415 | return nullptr; |
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 8416 | } |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8417 | return new (Context) |
8418 | OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | ||||
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 8419 | } |
8420 | |||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8421 | OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8422 | OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8423 | SourceLocation StartLoc, SourceLocation LParenLoc, |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8424 | ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8425 | SourceLocation EndLoc) { |
8426 | OMPClause *Res = nullptr; | ||||
8427 | switch (Kind) { | ||||
8428 | case OMPC_schedule: | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8429 | enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; |
8430 | assert(Argument.size() == NumberOfElements && | ||||
8431 | ArgumentLoc.size() == NumberOfElements); | ||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8432 | Res = ActOnOpenMPScheduleClause( |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8433 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), |
8434 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), | ||||
8435 | static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, | ||||
8436 | StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], | ||||
8437 | ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); | ||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8438 | break; |
8439 | case OMPC_if: | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8440 | assert(Argument.size() == 1 && ArgumentLoc.size() == 1); |
8441 | Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), | ||||
8442 | Expr, StartLoc, LParenLoc, ArgumentLoc.back(), | ||||
8443 | DelimLoc, EndLoc); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 8444 | break; |
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 8445 | case OMPC_dist_schedule: |
8446 | Res = ActOnOpenMPDistScheduleClause( | ||||
8447 | static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, | ||||
8448 | StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); | ||||
8449 | break; | ||||
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 8450 | case OMPC_defaultmap: |
8451 | enum { Modifier, DefaultmapKind }; | ||||
8452 | Res = ActOnOpenMPDefaultmapClause( | ||||
8453 | static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), | ||||
8454 | static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 8455 | StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], |
8456 | EndLoc); | ||||
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 8457 | break; |
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 8458 | case OMPC_final: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8459 | case OMPC_num_threads: |
8460 | case OMPC_safelen: | ||||
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 8461 | case OMPC_simdlen: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8462 | case OMPC_collapse: |
8463 | case OMPC_default: | ||||
8464 | case OMPC_proc_bind: | ||||
8465 | case OMPC_private: | ||||
8466 | case OMPC_firstprivate: | ||||
8467 | case OMPC_lastprivate: | ||||
8468 | case OMPC_shared: | ||||
8469 | case OMPC_reduction: | ||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 8470 | case OMPC_task_reduction: |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 8471 | case OMPC_in_reduction: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8472 | case OMPC_linear: |
8473 | case OMPC_aligned: | ||||
8474 | case OMPC_copyin: | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 8475 | case OMPC_copyprivate: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8476 | case OMPC_ordered: |
Alexey Bataev | 236070f | 2014-06-20 11:19:47 +0000 | [diff] [blame] | 8477 | case OMPC_nowait: |
Alexey Bataev | 7aea99a | 2014-07-17 12:19:31 +0000 | [diff] [blame] | 8478 | case OMPC_untied: |
Alexey Bataev | 74ba3a5 | 2014-07-17 12:47:03 +0000 | [diff] [blame] | 8479 | case OMPC_mergeable: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8480 | case OMPC_threadprivate: |
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 8481 | case OMPC_flush: |
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 8482 | case OMPC_read: |
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 8483 | case OMPC_write: |
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 8484 | case OMPC_update: |
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 8485 | case OMPC_capture: |
Alexey Bataev | 82bad8b | 2014-07-24 08:55:34 +0000 | [diff] [blame] | 8486 | case OMPC_seq_cst: |
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 8487 | case OMPC_depend: |
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 8488 | case OMPC_device: |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 8489 | case OMPC_threads: |
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 8490 | case OMPC_simd: |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 8491 | case OMPC_map: |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 8492 | case OMPC_num_teams: |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8493 | case OMPC_thread_limit: |
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8494 | case OMPC_priority: |
Alexey Bataev | 1fd4aed | 2015-12-07 12:52:51 +0000 | [diff] [blame] | 8495 | case OMPC_grainsize: |
Alexey Bataev | b825de1 | 2015-12-07 10:51:44 +0000 | [diff] [blame] | 8496 | case OMPC_nogroup: |
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 8497 | case OMPC_num_tasks: |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 8498 | case OMPC_hint: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8499 | case OMPC_unknown: |
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 8500 | case OMPC_uniform: |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 8501 | case OMPC_to: |
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 8502 | case OMPC_from: |
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 8503 | case OMPC_use_device_ptr: |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 8504 | case OMPC_is_device_ptr: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8505 | llvm_unreachable("Clause is not allowed."); |
8506 | } | ||||
8507 | return Res; | ||||
8508 | } | ||||
8509 | |||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8510 | static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, |
8511 | OpenMPScheduleClauseModifier M2, | ||||
8512 | SourceLocation M1Loc, SourceLocation M2Loc) { | ||||
8513 | if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { | ||||
8514 | SmallVector<unsigned, 2> Excluded; | ||||
8515 | if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) | ||||
8516 | Excluded.push_back(M2); | ||||
8517 | if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) | ||||
8518 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); | ||||
8519 | if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) | ||||
8520 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); | ||||
8521 | S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) | ||||
8522 | << getListOfPossibleValues(OMPC_schedule, | ||||
8523 | /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, | ||||
8524 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, | ||||
8525 | Excluded) | ||||
8526 | << getOpenMPClauseName(OMPC_schedule); | ||||
8527 | return true; | ||||
8528 | } | ||||
8529 | return false; | ||||
8530 | } | ||||
8531 | |||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8532 | OMPClause *Sema::ActOnOpenMPScheduleClause( |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8533 | OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8534 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8535 | SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, |
8536 | SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { | ||||
8537 | if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || | ||||
8538 | checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) | ||||
8539 | return nullptr; | ||||
8540 | // OpenMP, 2.7.1, Loop Construct, Restrictions | ||||
8541 | // Either the monotonic modifier or the nonmonotonic modifier can be specified | ||||
8542 | // but not both. | ||||
8543 | if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || | ||||
8544 | (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && | ||||
8545 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || | ||||
8546 | (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && | ||||
8547 | M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { | ||||
8548 | Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) | ||||
8549 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) | ||||
8550 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); | ||||
8551 | return nullptr; | ||||
8552 | } | ||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8553 | if (Kind == OMPC_SCHEDULE_unknown) { |
8554 | std::string Values; | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8555 | if (M1Loc.isInvalid() && M2Loc.isInvalid()) { |
8556 | unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; | ||||
8557 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, | ||||
8558 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, | ||||
8559 | Exclude); | ||||
8560 | } else { | ||||
8561 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, | ||||
8562 | /*Last=*/OMPC_SCHEDULE_unknown); | ||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8563 | } |
8564 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||
8565 | << Values << getOpenMPClauseName(OMPC_schedule); | ||||
8566 | return nullptr; | ||||
8567 | } | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8568 | // OpenMP, 2.7.1, Loop Construct, Restrictions |
8569 | // The nonmonotonic modifier can only be specified with schedule(dynamic) or | ||||
8570 | // schedule(guided). | ||||
8571 | if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || | ||||
8572 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && | ||||
8573 | Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { | ||||
8574 | Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, | ||||
8575 | diag::err_omp_schedule_nonmonotonic_static); | ||||
8576 | return nullptr; | ||||
8577 | } | ||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8578 | Expr *ValExpr = ChunkSize; |
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 8579 | Stmt *HelperValStmt = nullptr; |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8580 | if (ChunkSize) { |
8581 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && | ||||
8582 | !ChunkSize->isInstantiationDependent() && | ||||
8583 | !ChunkSize->containsUnexpandedParameterPack()) { | ||||
8584 | SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); | ||||
8585 | ExprResult Val = | ||||
8586 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); | ||||
8587 | if (Val.isInvalid()) | ||||
8588 | return nullptr; | ||||
8589 | |||||
8590 | ValExpr = Val.get(); | ||||
8591 | |||||
8592 | // OpenMP [2.7.1, Restrictions] | ||||
8593 | // chunk_size must be a loop invariant integer expression with a positive | ||||
8594 | // value. | ||||
8595 | llvm::APSInt Result; | ||||
Alexey Bataev | 040d540 | 2015-05-12 08:35:28 +0000 | [diff] [blame] | 8596 | if (ValExpr->isIntegerConstantExpr(Result, Context)) { |
8597 | if (Result.isSigned() && !Result.isStrictlyPositive()) { | ||||
8598 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) | ||||
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8599 | << "schedule" << 1 << ChunkSize->getSourceRange(); |
Alexey Bataev | 040d540 | 2015-05-12 08:35:28 +0000 | [diff] [blame] | 8600 | return nullptr; |
8601 | } | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 8602 | } else if (getOpenMPCaptureRegionForClause( |
8603 | DSAStack->getCurrentDirective(), OMPC_schedule) != | ||||
8604 | OMPD_unknown && | ||||
Alexey Bataev | b46cdea | 2016-06-15 11:20:48 +0000 | [diff] [blame] | 8605 | !CurContext->isDependentContext()) { |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 8606 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
8607 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||
8608 | HelperValStmt = buildPreInits(Context, Captures); | ||||
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8609 | } |
8610 | } | ||||
8611 | } | ||||
8612 | |||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 8613 | return new (Context) |
8614 | OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, | ||||
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 8615 | ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8616 | } |
8617 | |||||
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8618 | OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, |
8619 | SourceLocation StartLoc, | ||||
8620 | SourceLocation EndLoc) { | ||||
8621 | OMPClause *Res = nullptr; | ||||
8622 | switch (Kind) { | ||||
8623 | case OMPC_ordered: | ||||
8624 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); | ||||
8625 | break; | ||||
Alexey Bataev | 236070f | 2014-06-20 11:19:47 +0000 | [diff] [blame] | 8626 | case OMPC_nowait: |
8627 | Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); | ||||
8628 | break; | ||||
Alexey Bataev | 7aea99a | 2014-07-17 12:19:31 +0000 | [diff] [blame] | 8629 | case OMPC_untied: |
8630 | Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); | ||||
8631 | break; | ||||
Alexey Bataev | 74ba3a5 | 2014-07-17 12:47:03 +0000 | [diff] [blame] | 8632 | case OMPC_mergeable: |
8633 | Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); | ||||
8634 | break; | ||||
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 8635 | case OMPC_read: |
8636 | Res = ActOnOpenMPReadClause(StartLoc, EndLoc); | ||||
8637 | break; | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 8638 | case OMPC_write: |
8639 | Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); | ||||
8640 | break; | ||||
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 8641 | case OMPC_update: |
8642 | Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); | ||||
8643 | break; | ||||
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 8644 | case OMPC_capture: |
8645 | Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); | ||||
8646 | break; | ||||
Alexey Bataev | 82bad8b | 2014-07-24 08:55:34 +0000 | [diff] [blame] | 8647 | case OMPC_seq_cst: |
8648 | Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); | ||||
8649 | break; | ||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 8650 | case OMPC_threads: |
8651 | Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); | ||||
8652 | break; | ||||
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 8653 | case OMPC_simd: |
8654 | Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); | ||||
8655 | break; | ||||
Alexey Bataev | b825de1 | 2015-12-07 10:51:44 +0000 | [diff] [blame] | 8656 | case OMPC_nogroup: |
8657 | Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); | ||||
8658 | break; | ||||
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8659 | case OMPC_if: |
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 8660 | case OMPC_final: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8661 | case OMPC_num_threads: |
8662 | case OMPC_safelen: | ||||
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 8663 | case OMPC_simdlen: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8664 | case OMPC_collapse: |
8665 | case OMPC_schedule: | ||||
8666 | case OMPC_private: | ||||
8667 | case OMPC_firstprivate: | ||||
8668 | case OMPC_lastprivate: | ||||
8669 | case OMPC_shared: | ||||
8670 | case OMPC_reduction: | ||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 8671 | case OMPC_task_reduction: |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 8672 | case OMPC_in_reduction: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8673 | case OMPC_linear: |
8674 | case OMPC_aligned: | ||||
8675 | case OMPC_copyin: | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 8676 | case OMPC_copyprivate: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8677 | case OMPC_default: |
8678 | case OMPC_proc_bind: | ||||
8679 | case OMPC_threadprivate: | ||||
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 8680 | case OMPC_flush: |
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 8681 | case OMPC_depend: |
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 8682 | case OMPC_device: |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 8683 | case OMPC_map: |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 8684 | case OMPC_num_teams: |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8685 | case OMPC_thread_limit: |
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8686 | case OMPC_priority: |
Alexey Bataev | 1fd4aed | 2015-12-07 12:52:51 +0000 | [diff] [blame] | 8687 | case OMPC_grainsize: |
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 8688 | case OMPC_num_tasks: |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 8689 | case OMPC_hint: |
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 8690 | case OMPC_dist_schedule: |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 8691 | case OMPC_defaultmap: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8692 | case OMPC_unknown: |
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 8693 | case OMPC_uniform: |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 8694 | case OMPC_to: |
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 8695 | case OMPC_from: |
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 8696 | case OMPC_use_device_ptr: |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 8697 | case OMPC_is_device_ptr: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8698 | llvm_unreachable("Clause is not allowed."); |
8699 | } | ||||
8700 | return Res; | ||||
8701 | } | ||||
8702 | |||||
Alexey Bataev | 236070f | 2014-06-20 11:19:47 +0000 | [diff] [blame] | 8703 | OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, |
8704 | SourceLocation EndLoc) { | ||||
Alexey Bataev | 6d4ed05 | 2015-07-01 06:57:41 +0000 | [diff] [blame] | 8705 | DSAStack->setNowaitRegion(); |
Alexey Bataev | 236070f | 2014-06-20 11:19:47 +0000 | [diff] [blame] | 8706 | return new (Context) OMPNowaitClause(StartLoc, EndLoc); |
8707 | } | ||||
8708 | |||||
Alexey Bataev | 7aea99a | 2014-07-17 12:19:31 +0000 | [diff] [blame] | 8709 | OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, |
8710 | SourceLocation EndLoc) { | ||||
8711 | return new (Context) OMPUntiedClause(StartLoc, EndLoc); | ||||
8712 | } | ||||
8713 | |||||
Alexey Bataev | 74ba3a5 | 2014-07-17 12:47:03 +0000 | [diff] [blame] | 8714 | OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, |
8715 | SourceLocation EndLoc) { | ||||
8716 | return new (Context) OMPMergeableClause(StartLoc, EndLoc); | ||||
8717 | } | ||||
8718 | |||||
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 8719 | OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, |
8720 | SourceLocation EndLoc) { | ||||
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 8721 | return new (Context) OMPReadClause(StartLoc, EndLoc); |
8722 | } | ||||
8723 | |||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 8724 | OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, |
8725 | SourceLocation EndLoc) { | ||||
8726 | return new (Context) OMPWriteClause(StartLoc, EndLoc); | ||||
8727 | } | ||||
8728 | |||||
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 8729 | OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, |
8730 | SourceLocation EndLoc) { | ||||
8731 | return new (Context) OMPUpdateClause(StartLoc, EndLoc); | ||||
8732 | } | ||||
8733 | |||||
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 8734 | OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, |
8735 | SourceLocation EndLoc) { | ||||
8736 | return new (Context) OMPCaptureClause(StartLoc, EndLoc); | ||||
8737 | } | ||||
8738 | |||||
Alexey Bataev | 82bad8b | 2014-07-24 08:55:34 +0000 | [diff] [blame] | 8739 | OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, |
8740 | SourceLocation EndLoc) { | ||||
8741 | return new (Context) OMPSeqCstClause(StartLoc, EndLoc); | ||||
8742 | } | ||||
8743 | |||||
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 8744 | OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, |
8745 | SourceLocation EndLoc) { | ||||
8746 | return new (Context) OMPThreadsClause(StartLoc, EndLoc); | ||||
8747 | } | ||||
8748 | |||||
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 8749 | OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, |
8750 | SourceLocation EndLoc) { | ||||
8751 | return new (Context) OMPSIMDClause(StartLoc, EndLoc); | ||||
8752 | } | ||||
8753 | |||||
Alexey Bataev | b825de1 | 2015-12-07 10:51:44 +0000 | [diff] [blame] | 8754 | OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, |
8755 | SourceLocation EndLoc) { | ||||
8756 | return new (Context) OMPNogroupClause(StartLoc, EndLoc); | ||||
8757 | } | ||||
8758 | |||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 8759 | OMPClause *Sema::ActOnOpenMPVarListClause( |
8760 | OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, | ||||
8761 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, | ||||
8762 | SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, | ||||
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 8763 | const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, |
Samuel Antao | 23abd72 | 2016-01-19 20:40:49 +0000 | [diff] [blame] | 8764 | OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, |
8765 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, | ||||
8766 | SourceLocation DepLinMapLoc) { | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 8767 | OMPClause *Res = nullptr; |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8768 | switch (Kind) { |
8769 | case OMPC_private: | ||||
8770 | Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8771 | break; | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 8772 | case OMPC_firstprivate: |
8773 | Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8774 | break; | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 8775 | case OMPC_lastprivate: |
8776 | Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8777 | break; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8778 | case OMPC_shared: |
8779 | Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8780 | break; | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 8781 | case OMPC_reduction: |
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 8782 | Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, |
8783 | EndLoc, ReductionIdScopeSpec, ReductionId); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 8784 | break; |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 8785 | case OMPC_task_reduction: |
8786 | Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, | ||||
8787 | EndLoc, ReductionIdScopeSpec, | ||||
8788 | ReductionId); | ||||
8789 | break; | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 8790 | case OMPC_in_reduction: |
8791 | Res = | ||||
8792 | ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, | ||||
8793 | EndLoc, ReductionIdScopeSpec, ReductionId); | ||||
8794 | break; | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 8795 | case OMPC_linear: |
8796 | Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 8797 | LinKind, DepLinMapLoc, ColonLoc, EndLoc); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 8798 | break; |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 8799 | case OMPC_aligned: |
8800 | Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, | ||||
8801 | ColonLoc, EndLoc); | ||||
8802 | break; | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 8803 | case OMPC_copyin: |
8804 | Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8805 | break; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 8806 | case OMPC_copyprivate: |
8807 | Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8808 | break; | ||||
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 8809 | case OMPC_flush: |
8810 | Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8811 | break; | ||||
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 8812 | case OMPC_depend: |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 8813 | Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 8814 | StartLoc, LParenLoc, EndLoc); |
8815 | break; | ||||
8816 | case OMPC_map: | ||||
Samuel Antao | 23abd72 | 2016-01-19 20:40:49 +0000 | [diff] [blame] | 8817 | Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, |
8818 | DepLinMapLoc, ColonLoc, VarList, StartLoc, | ||||
8819 | LParenLoc, EndLoc); | ||||
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 8820 | break; |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 8821 | case OMPC_to: |
8822 | Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8823 | break; | ||||
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 8824 | case OMPC_from: |
8825 | Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8826 | break; | ||||
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 8827 | case OMPC_use_device_ptr: |
8828 | Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8829 | break; | ||||
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 8830 | case OMPC_is_device_ptr: |
8831 | Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); | ||||
8832 | break; | ||||
Alexey Bataev | aadd52e | 2014-02-13 05:29:23 +0000 | [diff] [blame] | 8833 | case OMPC_if: |
Alexey Bataev | 3778b60 | 2014-07-17 07:32:53 +0000 | [diff] [blame] | 8834 | case OMPC_final: |
Alexey Bataev | 568a833 | 2014-03-06 06:15:19 +0000 | [diff] [blame] | 8835 | case OMPC_num_threads: |
Alexey Bataev | 62c87d2 | 2014-03-21 04:51:18 +0000 | [diff] [blame] | 8836 | case OMPC_safelen: |
Alexey Bataev | 66b15b5 | 2015-08-21 11:14:16 +0000 | [diff] [blame] | 8837 | case OMPC_simdlen: |
Alexander Musman | 8bd31e6 | 2014-05-27 15:12:19 +0000 | [diff] [blame] | 8838 | case OMPC_collapse: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8839 | case OMPC_default: |
Alexey Bataev | bcbadb6 | 2014-05-06 06:04:14 +0000 | [diff] [blame] | 8840 | case OMPC_proc_bind: |
Alexey Bataev | 56dafe8 | 2014-06-20 07:16:17 +0000 | [diff] [blame] | 8841 | case OMPC_schedule: |
Alexey Bataev | 142e1fc | 2014-06-20 09:44:06 +0000 | [diff] [blame] | 8842 | case OMPC_ordered: |
Alexey Bataev | 236070f | 2014-06-20 11:19:47 +0000 | [diff] [blame] | 8843 | case OMPC_nowait: |
Alexey Bataev | 7aea99a | 2014-07-17 12:19:31 +0000 | [diff] [blame] | 8844 | case OMPC_untied: |
Alexey Bataev | 74ba3a5 | 2014-07-17 12:47:03 +0000 | [diff] [blame] | 8845 | case OMPC_mergeable: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8846 | case OMPC_threadprivate: |
Alexey Bataev | f98b00c | 2014-07-23 02:27:21 +0000 | [diff] [blame] | 8847 | case OMPC_read: |
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 8848 | case OMPC_write: |
Alexey Bataev | 67a4f22 | 2014-07-23 10:25:33 +0000 | [diff] [blame] | 8849 | case OMPC_update: |
Alexey Bataev | 459dec0 | 2014-07-24 06:46:57 +0000 | [diff] [blame] | 8850 | case OMPC_capture: |
Alexey Bataev | 82bad8b | 2014-07-24 08:55:34 +0000 | [diff] [blame] | 8851 | case OMPC_seq_cst: |
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 8852 | case OMPC_device: |
Alexey Bataev | 346265e | 2015-09-25 10:37:12 +0000 | [diff] [blame] | 8853 | case OMPC_threads: |
Alexey Bataev | d14d1e6 | 2015-09-28 06:39:35 +0000 | [diff] [blame] | 8854 | case OMPC_simd: |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 8855 | case OMPC_num_teams: |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 8856 | case OMPC_thread_limit: |
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 8857 | case OMPC_priority: |
Alexey Bataev | 1fd4aed | 2015-12-07 12:52:51 +0000 | [diff] [blame] | 8858 | case OMPC_grainsize: |
Alexey Bataev | b825de1 | 2015-12-07 10:51:44 +0000 | [diff] [blame] | 8859 | case OMPC_nogroup: |
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 8860 | case OMPC_num_tasks: |
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 8861 | case OMPC_hint: |
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 8862 | case OMPC_dist_schedule: |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 8863 | case OMPC_defaultmap: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8864 | case OMPC_unknown: |
Alexey Bataev | e48a5fc | 2016-04-12 05:28:34 +0000 | [diff] [blame] | 8865 | case OMPC_uniform: |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8866 | llvm_unreachable("Clause is not allowed."); |
8867 | } | ||||
8868 | return Res; | ||||
8869 | } | ||||
8870 | |||||
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 8871 | ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, |
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 8872 | ExprObjectKind OK, SourceLocation Loc) { |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 8873 | ExprResult Res = BuildDeclRefExpr( |
8874 | Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); | ||||
8875 | if (!Res.isUsable()) | ||||
8876 | return ExprError(); | ||||
8877 | if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { | ||||
8878 | Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); | ||||
8879 | if (!Res.isUsable()) | ||||
8880 | return ExprError(); | ||||
8881 | } | ||||
8882 | if (VK != VK_LValue && Res.get()->isGLValue()) { | ||||
8883 | Res = DefaultLvalueConversion(Res.get()); | ||||
8884 | if (!Res.isUsable()) | ||||
8885 | return ExprError(); | ||||
8886 | } | ||||
8887 | return Res; | ||||
8888 | } | ||||
8889 | |||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 8890 | static std::pair<ValueDecl *, bool> |
8891 | getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, | ||||
8892 | SourceRange &ERange, bool AllowArraySection = false) { | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 8893 | if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || |
8894 | RefExpr->containsUnexpandedParameterPack()) | ||||
8895 | return std::make_pair(nullptr, true); | ||||
8896 | |||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 8897 | // OpenMP [3.1, C/C++] |
8898 | // A list item is a variable name. | ||||
8899 | // OpenMP [2.9.3.3, Restrictions, p.1] | ||||
8900 | // A variable that is part of another variable (as an array or | ||||
8901 | // structure element) cannot appear in a private clause. | ||||
8902 | RefExpr = RefExpr->IgnoreParens(); | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 8903 | enum { |
8904 | NoArrayExpr = -1, | ||||
8905 | ArraySubscript = 0, | ||||
8906 | OMPArraySection = 1 | ||||
8907 | } IsArrayExpr = NoArrayExpr; | ||||
8908 | if (AllowArraySection) { | ||||
8909 | if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { | ||||
8910 | auto *Base = ASE->getBase()->IgnoreParenImpCasts(); | ||||
8911 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) | ||||
8912 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||
8913 | RefExpr = Base; | ||||
8914 | IsArrayExpr = ArraySubscript; | ||||
8915 | } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { | ||||
8916 | auto *Base = OASE->getBase()->IgnoreParenImpCasts(); | ||||
8917 | while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) | ||||
8918 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); | ||||
8919 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) | ||||
8920 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||
8921 | RefExpr = Base; | ||||
8922 | IsArrayExpr = OMPArraySection; | ||||
8923 | } | ||||
8924 | } | ||||
8925 | ELoc = RefExpr->getExprLoc(); | ||||
8926 | ERange = RefExpr->getSourceRange(); | ||||
8927 | RefExpr = RefExpr->IgnoreParenImpCasts(); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 8928 | auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); |
8929 | auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); | ||||
8930 | if ((!DE || !isa<VarDecl>(DE->getDecl())) && | ||||
8931 | (S.getCurrentThisType().isNull() || !ME || | ||||
8932 | !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || | ||||
8933 | !isa<FieldDecl>(ME->getMemberDecl()))) { | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 8934 | if (IsArrayExpr != NoArrayExpr) |
8935 | S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr | ||||
8936 | << ERange; | ||||
8937 | else { | ||||
8938 | S.Diag(ELoc, | ||||
8939 | AllowArraySection | ||||
8940 | ? diag::err_omp_expected_var_name_member_expr_or_array_item | ||||
8941 | : diag::err_omp_expected_var_name_member_expr) | ||||
8942 | << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; | ||||
8943 | } | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 8944 | return std::make_pair(nullptr, false); |
8945 | } | ||||
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 8946 | return std::make_pair( |
8947 | getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 8948 | } |
8949 | |||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8950 | OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, |
8951 | SourceLocation StartLoc, | ||||
8952 | SourceLocation LParenLoc, | ||||
8953 | SourceLocation EndLoc) { | ||||
8954 | SmallVector<Expr *, 8> Vars; | ||||
Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 8955 | SmallVector<Expr *, 8> PrivateCopies; |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8956 | for (auto &RefExpr : VarList) { |
8957 | assert(RefExpr && "NULL expr in OpenMP private clause."); | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 8958 | SourceLocation ELoc; |
8959 | SourceRange ERange; | ||||
8960 | Expr *SimpleRefExpr = RefExpr; | ||||
8961 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 8962 | if (Res.second) { |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8963 | // It will be analyzed later. |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8964 | Vars.push_back(RefExpr); |
Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 8965 | PrivateCopies.push_back(nullptr); |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8966 | } |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 8967 | ValueDecl *D = Res.first; |
8968 | if (!D) | ||||
8969 | continue; | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8970 | |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 8971 | QualType Type = D->getType(); |
8972 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8973 | |
8974 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||
8975 | // A variable that appears in a private clause must not have an incomplete | ||||
8976 | // type or a reference type. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 8977 | if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8978 | continue; |
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 8979 | Type = Type.getNonReferenceType(); |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 8980 | |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8981 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
8982 | // in a Construct] | ||||
8983 | // Variables with the predetermined data-sharing attributes may not be | ||||
8984 | // listed in data-sharing attributes clauses, except for the cases | ||||
8985 | // listed below. For these exceptions only, listing a predetermined | ||||
8986 | // variable in a data-sharing attribute clause is allowed and overrides | ||||
8987 | // the variable's predetermined data-sharing attributes. | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 8988 | DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8989 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 8990 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) |
8991 | << getOpenMPClauseName(OMPC_private); | ||||
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 8992 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 8993 | continue; |
8994 | } | ||||
8995 | |||||
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 8996 | auto CurrDir = DSAStack->getCurrentDirective(); |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 8997 | // Variably modified types are not supported for tasks. |
Alexey Bataev | 5129d3a | 2015-05-21 09:47:46 +0000 | [diff] [blame] | 8998 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && |
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 8999 | isOpenMPTaskingDirective(CurrDir)) { |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9000 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) |
9001 | << getOpenMPClauseName(OMPC_private) << Type | ||||
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 9002 | << getOpenMPDirectiveName(CurrDir); |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9003 | bool IsDecl = |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 9004 | !VD || |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9005 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 9006 | Diag(D->getLocation(), |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9007 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 9008 | << D; |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9009 | continue; |
9010 | } | ||||
9011 | |||||
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 9012 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] |
9013 | // A list item cannot appear in both a map clause and a data-sharing | ||||
9014 | // attribute clause on the same construct | ||||
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 9015 | if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || |
Kelvin Li | da68118 | 2017-01-10 18:08:18 +0000 | [diff] [blame] | 9016 | CurrDir == OMPD_target_teams || |
Kelvin Li | 80e8f56 | 2016-12-29 22:16:30 +0000 | [diff] [blame] | 9017 | CurrDir == OMPD_target_teams_distribute || |
Kelvin Li | 1851df5 | 2017-01-03 05:23:48 +0000 | [diff] [blame] | 9018 | CurrDir == OMPD_target_teams_distribute_parallel_for || |
Kelvin Li | c4bfc6f | 2017-01-10 04:26:44 +0000 | [diff] [blame] | 9019 | CurrDir == OMPD_target_teams_distribute_parallel_for_simd || |
Kelvin Li | da68118 | 2017-01-10 18:08:18 +0000 | [diff] [blame] | 9020 | CurrDir == OMPD_target_teams_distribute_simd || |
Kelvin Li | 4101032 | 2017-01-10 05:15:35 +0000 | [diff] [blame] | 9021 | CurrDir == OMPD_target_parallel_for_simd || |
9022 | CurrDir == OMPD_target_parallel_for) { | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 9023 | OpenMPClauseKind ConflictKind; |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 9024 | if (DSAStack->checkMappableExprComponentListsForDecl( |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 9025 | VD, /*CurrentRegionOnly=*/true, |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 9026 | [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, |
9027 | OpenMPClauseKind WhereFoundClauseKind) -> bool { | ||||
9028 | ConflictKind = WhereFoundClauseKind; | ||||
9029 | return true; | ||||
9030 | })) { | ||||
9031 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 9032 | << getOpenMPClauseName(OMPC_private) |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 9033 | << getOpenMPClauseName(ConflictKind) |
Kelvin Li | bf594a5 | 2016-12-17 05:48:59 +0000 | [diff] [blame] | 9034 | << getOpenMPDirectiveName(CurrDir); |
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 9035 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
9036 | continue; | ||||
9037 | } | ||||
9038 | } | ||||
9039 | |||||
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9040 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] |
9041 | // A variable of class type (or array thereof) that appears in a private | ||||
9042 | // clause requires an accessible, unambiguous default constructor for the | ||||
9043 | // class type. | ||||
Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 9044 | // Generate helper private variable and initialize it with the default |
9045 | // value. The address of the original variable is replaced by the address of | ||||
9046 | // the new private variable in CodeGen. This new variable is not added to | ||||
9047 | // IdResolver, so the code in the OpenMP region uses original variable for | ||||
9048 | // proper diagnostics. | ||||
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9049 | Type = Type.getUnqualifiedType(); |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 9050 | auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), |
9051 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 9052 | ActOnUninitializedDecl(VDPrivate); |
Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 9053 | if (VDPrivate->isInvalidDecl()) |
9054 | continue; | ||||
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9055 | auto VDPrivateRefExpr = buildDeclRefExpr( |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 9056 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); |
Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 9057 | |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 9058 | DeclRefExpr *Ref = nullptr; |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9059 | if (!VD && !CurContext->isDependentContext()) |
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 9060 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); |
Alexey Bataev | 90c228f | 2016-02-08 09:29:13 +0000 | [diff] [blame] | 9061 | DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9062 | Vars.push_back((VD || CurContext->isDependentContext()) |
9063 | ? RefExpr->IgnoreParens() | ||||
9064 | : Ref); | ||||
Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 9065 | PrivateCopies.push_back(VDPrivateRefExpr); |
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 9066 | } |
9067 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9068 | if (Vars.empty()) |
9069 | return nullptr; | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 9070 | |
Alexey Bataev | 03b340a | 2014-10-21 03:16:40 +0000 | [diff] [blame] | 9071 | return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, |
9072 | PrivateCopies); | ||||
Alexey Bataev | 5ec3eb1 | 2013-07-19 03:13:43 +0000 | [diff] [blame] | 9073 | } |
9074 | |||||
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9075 | namespace { |
9076 | class DiagsUninitializedSeveretyRAII { | ||||
9077 | private: | ||||
9078 | DiagnosticsEngine &Diags; | ||||
9079 | SourceLocation SavedLoc; | ||||
9080 | bool IsIgnored; | ||||
9081 | |||||
9082 | public: | ||||
9083 | DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, | ||||
9084 | bool IsIgnored) | ||||
9085 | : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { | ||||
9086 | if (!IsIgnored) { | ||||
9087 | Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, | ||||
9088 | /*Map*/ diag::Severity::Ignored, Loc); | ||||
9089 | } | ||||
9090 | } | ||||
9091 | ~DiagsUninitializedSeveretyRAII() { | ||||
9092 | if (!IsIgnored) | ||||
9093 | Diags.popMappings(SavedLoc); | ||||
9094 | } | ||||
9095 | }; | ||||
Alexander Kornienko | ab9db51 | 2015-06-22 23:07:51 +0000 | [diff] [blame] | 9096 | } |
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9097 | |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9098 | OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, |
9099 | SourceLocation StartLoc, | ||||
9100 | SourceLocation LParenLoc, | ||||
9101 | SourceLocation EndLoc) { | ||||
9102 | SmallVector<Expr *, 8> Vars; | ||||
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9103 | SmallVector<Expr *, 8> PrivateCopies; |
9104 | SmallVector<Expr *, 8> Inits; | ||||
Alexey Bataev | 417089f | 2016-02-17 13:19:37 +0000 | [diff] [blame] | 9105 | SmallVector<Decl *, 4> ExprCaptures; |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9106 | bool IsImplicitClause = |
9107 | StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); | ||||
9108 | auto ImplicitClauseLoc = DSAStack->getConstructLoc(); | ||||
9109 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9110 | for (auto &RefExpr : VarList) { |
9111 | assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9112 | SourceLocation ELoc; |
9113 | SourceRange ERange; | ||||
9114 | Expr *SimpleRefExpr = RefExpr; | ||||
9115 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9116 | if (Res.second) { |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9117 | // It will be analyzed later. |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9118 | Vars.push_back(RefExpr); |
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9119 | PrivateCopies.push_back(nullptr); |
9120 | Inits.push_back(nullptr); | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9121 | } |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9122 | ValueDecl *D = Res.first; |
9123 | if (!D) | ||||
9124 | continue; | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9125 | |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9126 | ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9127 | QualType Type = D->getType(); |
9128 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9129 | |
9130 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | ||||
9131 | // A variable that appears in a private clause must not have an incomplete | ||||
9132 | // type or a reference type. | ||||
9133 | if (RequireCompleteType(ELoc, Type, | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9134 | diag::err_omp_firstprivate_incomplete_type)) |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9135 | continue; |
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 9136 | Type = Type.getNonReferenceType(); |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9137 | |
9138 | // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] | ||||
9139 | // A variable of class type (or array thereof) that appears in a private | ||||
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 9140 | // clause requires an accessible, unambiguous copy constructor for the |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9141 | // class type. |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9142 | auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9143 | |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9144 | // If an implicit firstprivate variable found it was checked already. |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9145 | DSAStackTy::DSAVarData TopDVar; |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9146 | if (!IsImplicitClause) { |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9147 | DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9148 | TopDVar = DVar; |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9149 | OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9150 | bool IsConstant = ElemType.isConstant(Context); |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9151 | // OpenMP [2.4.13, Data-sharing Attribute Clauses] |
9152 | // A list item that specifies a given variable may not appear in more | ||||
9153 | // than one clause on the same directive, except that a variable may be | ||||
9154 | // specified in both firstprivate and lastprivate clauses. | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9155 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] |
9156 | // A list item may appear in a firstprivate or lastprivate clause but not | ||||
9157 | // both. | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9158 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && |
Alexey Bataev | b358f99 | 2017-12-01 17:40:15 +0000 | [diff] [blame] | 9159 | (isOpenMPDistributeDirective(CurrDir) || |
9160 | DVar.CKind != OMPC_lastprivate) && | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9161 | DVar.RefExpr) { |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9162 | Diag(ELoc, diag::err_omp_wrong_dsa) |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9163 | << getOpenMPClauseName(DVar.CKind) |
9164 | << getOpenMPClauseName(OMPC_firstprivate); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9165 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9166 | continue; |
9167 | } | ||||
9168 | |||||
9169 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
9170 | // in a Construct] | ||||
9171 | // Variables with the predetermined data-sharing attributes may not be | ||||
9172 | // listed in data-sharing attributes clauses, except for the cases | ||||
9173 | // listed below. For these exceptions only, listing a predetermined | ||||
9174 | // variable in a data-sharing attribute clause is allowed and overrides | ||||
9175 | // the variable's predetermined data-sharing attributes. | ||||
9176 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | ||||
9177 | // in a Construct, C/C++, p.2] | ||||
9178 | // Variables with const-qualified type having no mutable member may be | ||||
9179 | // listed in a firstprivate clause, even if they are static data members. | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9180 | if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9181 | DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { |
9182 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9183 | << getOpenMPClauseName(DVar.CKind) |
9184 | << getOpenMPClauseName(OMPC_firstprivate); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9185 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9186 | continue; |
9187 | } | ||||
9188 | |||||
9189 | // OpenMP [2.9.3.4, Restrictions, p.2] | ||||
9190 | // A list item that is private within a parallel region must not appear | ||||
9191 | // in a firstprivate clause on a worksharing construct if any of the | ||||
9192 | // worksharing regions arising from the worksharing construct ever bind | ||||
9193 | // to any of the parallel regions arising from the parallel construct. | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9194 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] |
9195 | // A list item that is private within a teams region must not appear in a | ||||
9196 | // firstprivate clause on a distribute construct if any of the distribute | ||||
9197 | // regions arising from the distribute construct ever bind to any of the | ||||
9198 | // teams regions arising from the teams construct. | ||||
9199 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] | ||||
9200 | // A list item that appears in a reduction clause of a teams construct | ||||
9201 | // must not appear in a firstprivate clause on a distribute construct if | ||||
9202 | // any of the distribute regions arising from the distribute construct | ||||
9203 | // ever bind to any of the teams regions arising from the teams construct. | ||||
9204 | if ((isOpenMPWorksharingDirective(CurrDir) || | ||||
9205 | isOpenMPDistributeDirective(CurrDir)) && | ||||
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 9206 | !isOpenMPParallelDirective(CurrDir) && |
9207 | !isOpenMPTeamsDirective(CurrDir)) { | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9208 | DVar = DSAStack->getImplicitDSA(D, true); |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9209 | if (DVar.CKind != OMPC_shared && |
9210 | (isOpenMPParallelDirective(DVar.DKind) || | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9211 | isOpenMPTeamsDirective(DVar.DKind) || |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9212 | DVar.DKind == OMPD_unknown)) { |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 9213 | Diag(ELoc, diag::err_omp_required_access) |
9214 | << getOpenMPClauseName(OMPC_firstprivate) | ||||
9215 | << getOpenMPClauseName(OMPC_shared); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9216 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 9217 | continue; |
9218 | } | ||||
9219 | } | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9220 | // OpenMP [2.9.3.4, Restrictions, p.3] |
9221 | // A list item that appears in a reduction clause of a parallel construct | ||||
9222 | // must not appear in a firstprivate clause on a worksharing or task | ||||
9223 | // construct if any of the worksharing or task regions arising from the | ||||
9224 | // worksharing or task construct ever bind to any of the parallel regions | ||||
9225 | // arising from the parallel construct. | ||||
9226 | // OpenMP [2.9.3.4, Restrictions, p.4] | ||||
9227 | // A list item that appears in a reduction clause in worksharing | ||||
9228 | // construct must not appear in a firstprivate clause in a task construct | ||||
9229 | // encountered during execution of any of the worksharing regions arising | ||||
9230 | // from the worksharing construct. | ||||
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 9231 | if (isOpenMPTaskingDirective(CurrDir)) { |
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 9232 | DVar = DSAStack->hasInnermostDSA( |
9233 | D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, | ||||
9234 | [](OpenMPDirectiveKind K) -> bool { | ||||
9235 | return isOpenMPParallelDirective(K) || | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9236 | isOpenMPWorksharingDirective(K) || |
9237 | isOpenMPTeamsDirective(K); | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 9238 | }, |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9239 | /*FromParent=*/true); |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9240 | if (DVar.CKind == OMPC_reduction && |
9241 | (isOpenMPParallelDirective(DVar.DKind) || | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9242 | isOpenMPWorksharingDirective(DVar.DKind) || |
9243 | isOpenMPTeamsDirective(DVar.DKind))) { | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9244 | Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) |
9245 | << getOpenMPDirectiveName(DVar.DKind); | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9246 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9247 | continue; |
9248 | } | ||||
9249 | } | ||||
Carlo Bertolli | 6200a3d | 2015-12-14 14:51:25 +0000 | [diff] [blame] | 9250 | |
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 9251 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] |
9252 | // A list item cannot appear in both a map clause and a data-sharing | ||||
9253 | // attribute clause on the same construct | ||||
Alexey Bataev | b358f99 | 2017-12-01 17:40:15 +0000 | [diff] [blame] | 9254 | if (isOpenMPTargetExecutionDirective(CurrDir)) { |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 9255 | OpenMPClauseKind ConflictKind; |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 9256 | if (DSAStack->checkMappableExprComponentListsForDecl( |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 9257 | VD, /*CurrentRegionOnly=*/true, |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 9258 | [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, |
9259 | OpenMPClauseKind WhereFoundClauseKind) -> bool { | ||||
9260 | ConflictKind = WhereFoundClauseKind; | ||||
9261 | return true; | ||||
9262 | })) { | ||||
9263 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 9264 | << getOpenMPClauseName(OMPC_firstprivate) |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 9265 | << getOpenMPClauseName(ConflictKind) |
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 9266 | << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); |
9267 | ReportOriginalDSA(*this, DSAStack, D, DVar); | ||||
9268 | continue; | ||||
9269 | } | ||||
9270 | } | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9271 | } |
9272 | |||||
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9273 | // Variably modified types are not supported for tasks. |
Alexey Bataev | 5129d3a | 2015-05-21 09:47:46 +0000 | [diff] [blame] | 9274 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && |
Alexey Bataev | 35aaee6 | 2016-04-13 13:36:48 +0000 | [diff] [blame] | 9275 | isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9276 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) |
9277 | << getOpenMPClauseName(OMPC_firstprivate) << Type | ||||
9278 | << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); | ||||
9279 | bool IsDecl = | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9280 | !VD || |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9281 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9282 | Diag(D->getLocation(), |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9283 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9284 | << D; |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 9285 | continue; |
9286 | } | ||||
9287 | |||||
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9288 | Type = Type.getUnqualifiedType(); |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9289 | auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), |
9290 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9291 | // Generate helper private variable and initialize it with the value of the |
9292 | // original variable. The address of the original variable is replaced by | ||||
9293 | // the address of the new private variable in the CodeGen. This new variable | ||||
9294 | // is not added to IdResolver, so the code in the OpenMP region uses | ||||
9295 | // original variable for proper diagnostics and variable capturing. | ||||
9296 | Expr *VDInitRefExpr = nullptr; | ||||
9297 | // For arrays generate initializer for single element and replace it by the | ||||
9298 | // original array element in CodeGen. | ||||
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9299 | if (Type->isArrayType()) { |
9300 | auto VDInit = | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9301 | buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9302 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); |
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9303 | auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9304 | ElemType = ElemType.getUnqualifiedType(); |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9305 | auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 9306 | ".firstprivate.temp"); |
Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 9307 | InitializedEntity Entity = |
9308 | InitializedEntity::InitializeVariable(VDInitTemp); | ||||
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9309 | InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); |
9310 | |||||
9311 | InitializationSequence InitSeq(*this, Entity, Kind, Init); | ||||
9312 | ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); | ||||
9313 | if (Result.isInvalid()) | ||||
9314 | VDPrivate->setInvalidDecl(); | ||||
9315 | else | ||||
9316 | VDPrivate->setInit(Result.getAs<Expr>()); | ||||
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 9317 | // Remove temp variable declaration. |
9318 | Context.Deallocate(VDInitTemp); | ||||
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9319 | } else { |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9320 | auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, |
9321 | ".firstprivate.temp"); | ||||
9322 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), | ||||
9323 | RefExpr->getExprLoc()); | ||||
Alexey Bataev | 69c62a9 | 2015-04-15 04:52:20 +0000 | [diff] [blame] | 9324 | AddInitializerToDecl(VDPrivate, |
9325 | DefaultLvalueConversion(VDInitRefExpr).get(), | ||||
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 9326 | /*DirectInit=*/false); |
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9327 | } |
9328 | if (VDPrivate->isInvalidDecl()) { | ||||
9329 | if (IsImplicitClause) { | ||||
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9330 | Diag(RefExpr->getExprLoc(), |
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9331 | diag::note_omp_task_predetermined_firstprivate_here); |
9332 | } | ||||
9333 | continue; | ||||
9334 | } | ||||
9335 | CurContext->addDecl(VDPrivate); | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 9336 | auto VDPrivateRefExpr = buildDeclRefExpr( |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9337 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), |
9338 | RefExpr->getExprLoc()); | ||||
9339 | DeclRefExpr *Ref = nullptr; | ||||
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9340 | if (!VD && !CurContext->isDependentContext()) { |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9341 | if (TopDVar.CKind == OMPC_lastprivate) |
9342 | Ref = TopDVar.PrivateCopy; | ||||
9343 | else { | ||||
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 9344 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9345 | if (!IsOpenMPCapturedDecl(D)) |
9346 | ExprCaptures.push_back(Ref->getDecl()); | ||||
9347 | } | ||||
Alexey Bataev | 417089f | 2016-02-17 13:19:37 +0000 | [diff] [blame] | 9348 | } |
Alexey Bataev | d985eda | 2016-02-10 11:29:16 +0000 | [diff] [blame] | 9349 | DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9350 | Vars.push_back((VD || CurContext->isDependentContext()) |
9351 | ? RefExpr->IgnoreParens() | ||||
9352 | : Ref); | ||||
Alexey Bataev | 4a5bb77 | 2014-10-08 14:01:46 +0000 | [diff] [blame] | 9353 | PrivateCopies.push_back(VDPrivateRefExpr); |
9354 | Inits.push_back(VDInitRefExpr); | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9355 | } |
9356 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9357 | if (Vars.empty()) |
9358 | return nullptr; | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9359 | |
9360 | return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 9361 | Vars, PrivateCopies, Inits, |
9362 | buildPreInits(Context, ExprCaptures)); | ||||
Alexey Bataev | d5af8e4 | 2013-10-01 05:32:34 +0000 | [diff] [blame] | 9363 | } |
9364 | |||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9365 | OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, |
9366 | SourceLocation StartLoc, | ||||
9367 | SourceLocation LParenLoc, | ||||
9368 | SourceLocation EndLoc) { | ||||
9369 | SmallVector<Expr *, 8> Vars; | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9370 | SmallVector<Expr *, 8> SrcExprs; |
9371 | SmallVector<Expr *, 8> DstExprs; | ||||
9372 | SmallVector<Expr *, 8> AssignmentOps; | ||||
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9373 | SmallVector<Decl *, 4> ExprCaptures; |
9374 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9375 | for (auto &RefExpr : VarList) { |
9376 | assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9377 | SourceLocation ELoc; |
9378 | SourceRange ERange; | ||||
9379 | Expr *SimpleRefExpr = RefExpr; | ||||
9380 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9381 | if (Res.second) { |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9382 | // It will be analyzed later. |
9383 | Vars.push_back(RefExpr); | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9384 | SrcExprs.push_back(nullptr); |
9385 | DstExprs.push_back(nullptr); | ||||
9386 | AssignmentOps.push_back(nullptr); | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9387 | } |
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9388 | ValueDecl *D = Res.first; |
9389 | if (!D) | ||||
9390 | continue; | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9391 | |
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9392 | QualType Type = D->getType(); |
9393 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9394 | |
9395 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] | ||||
9396 | // A variable that appears in a lastprivate clause must not have an | ||||
9397 | // incomplete type or a reference type. | ||||
9398 | if (RequireCompleteType(ELoc, Type, | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9399 | diag::err_omp_lastprivate_incomplete_type)) |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9400 | continue; |
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 9401 | Type = Type.getNonReferenceType(); |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9402 | |
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9403 | OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9404 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced |
9405 | // in a Construct] | ||||
9406 | // Variables with the predetermined data-sharing attributes may not be | ||||
9407 | // listed in data-sharing attributes clauses, except for the cases | ||||
9408 | // listed below. | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9409 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] |
9410 | // A list item may appear in a firstprivate or lastprivate clause but not | ||||
9411 | // both. | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9412 | DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9413 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && |
Alexey Bataev | b358f99 | 2017-12-01 17:40:15 +0000 | [diff] [blame] | 9414 | (isOpenMPDistributeDirective(CurrDir) || |
9415 | DVar.CKind != OMPC_firstprivate) && | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9416 | (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { |
9417 | Diag(ELoc, diag::err_omp_wrong_dsa) | ||||
9418 | << getOpenMPClauseName(DVar.CKind) | ||||
9419 | << getOpenMPClauseName(OMPC_lastprivate); | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9420 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9421 | continue; |
9422 | } | ||||
9423 | |||||
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 9424 | // OpenMP [2.14.3.5, Restrictions, p.2] |
9425 | // A list item that is private within a parallel region, or that appears in | ||||
9426 | // the reduction clause of a parallel construct, must not appear in a | ||||
9427 | // lastprivate clause on a worksharing construct if any of the corresponding | ||||
9428 | // worksharing regions ever binds to any of the corresponding parallel | ||||
9429 | // regions. | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 9430 | DSAStackTy::DSAVarData TopDVar = DVar; |
Alexey Bataev | 549210e | 2014-06-24 04:39:47 +0000 | [diff] [blame] | 9431 | if (isOpenMPWorksharingDirective(CurrDir) && |
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 9432 | !isOpenMPParallelDirective(CurrDir) && |
9433 | !isOpenMPTeamsDirective(CurrDir)) { | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9434 | DVar = DSAStack->getImplicitDSA(D, true); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 9435 | if (DVar.CKind != OMPC_shared) { |
9436 | Diag(ELoc, diag::err_omp_required_access) | ||||
9437 | << getOpenMPClauseName(OMPC_lastprivate) | ||||
9438 | << getOpenMPClauseName(OMPC_shared); | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9439 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 9440 | continue; |
9441 | } | ||||
9442 | } | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9443 | |
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9444 | // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 9445 | // A variable of class type (or array thereof) that appears in a |
9446 | // lastprivate clause requires an accessible, unambiguous default | ||||
9447 | // constructor for the class type, unless the list item is also specified | ||||
9448 | // in a firstprivate clause. | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9449 | // A variable of class type (or array thereof) that appears in a |
9450 | // lastprivate clause requires an accessible, unambiguous copy assignment | ||||
9451 | // operator for the class type. | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9452 | Type = Context.getBaseElementType(Type).getNonReferenceType(); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9453 | auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), |
Alexey Bataev | 1d7f0fa | 2015-09-10 09:48:30 +0000 | [diff] [blame] | 9454 | Type.getUnqualifiedType(), ".lastprivate.src", |
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9455 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
9456 | auto *PseudoSrcExpr = | ||||
9457 | buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9458 | auto *DstVD = |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9459 | buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", |
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9460 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
9461 | auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9462 | // For arrays generate assignment operation for single element and replace |
9463 | // it by the original array element in CodeGen. | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9464 | auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, |
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9465 | PseudoDstExpr, PseudoSrcExpr); |
9466 | if (AssignmentOp.isInvalid()) | ||||
9467 | continue; | ||||
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9468 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, |
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9469 | /*DiscardedValue=*/true); |
9470 | if (AssignmentOp.isInvalid()) | ||||
9471 | continue; | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9472 | |
Alexey Bataev | 74caaf2 | 2016-02-20 04:09:36 +0000 | [diff] [blame] | 9473 | DeclRefExpr *Ref = nullptr; |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9474 | if (!VD && !CurContext->isDependentContext()) { |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9475 | if (TopDVar.CKind == OMPC_firstprivate) |
9476 | Ref = TopDVar.PrivateCopy; | ||||
9477 | else { | ||||
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 9478 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9479 | if (!IsOpenMPCapturedDecl(D)) |
9480 | ExprCaptures.push_back(Ref->getDecl()); | ||||
9481 | } | ||||
9482 | if (TopDVar.CKind == OMPC_firstprivate || | ||||
9483 | (!IsOpenMPCapturedDecl(D) && | ||||
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 9484 | Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { |
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9485 | ExprResult RefRes = DefaultLvalueConversion(Ref); |
9486 | if (!RefRes.isUsable()) | ||||
9487 | continue; | ||||
9488 | ExprResult PostUpdateRes = | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9489 | BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, |
9490 | RefRes.get()); | ||||
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9491 | if (!PostUpdateRes.isUsable()) |
9492 | continue; | ||||
Alexey Bataev | 78849fb | 2016-03-09 09:49:00 +0000 | [diff] [blame] | 9493 | ExprPostUpdates.push_back( |
9494 | IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9495 | } |
9496 | } | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 9497 | DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9498 | Vars.push_back((VD || CurContext->isDependentContext()) |
9499 | ? RefExpr->IgnoreParens() | ||||
9500 | : Ref); | ||||
Alexey Bataev | 38e8953 | 2015-04-16 04:54:05 +0000 | [diff] [blame] | 9501 | SrcExprs.push_back(PseudoSrcExpr); |
9502 | DstExprs.push_back(PseudoDstExpr); | ||||
9503 | AssignmentOps.push_back(AssignmentOp.get()); | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9504 | } |
9505 | |||||
9506 | if (Vars.empty()) | ||||
9507 | return nullptr; | ||||
9508 | |||||
9509 | return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||
Alexey Bataev | 005248a | 2016-02-25 05:25:57 +0000 | [diff] [blame] | 9510 | Vars, SrcExprs, DstExprs, AssignmentOps, |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 9511 | buildPreInits(Context, ExprCaptures), |
9512 | buildPostUpdate(*this, ExprPostUpdates)); | ||||
Alexander Musman | 1bb328c | 2014-06-04 13:06:39 +0000 | [diff] [blame] | 9513 | } |
9514 | |||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9515 | OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, |
9516 | SourceLocation StartLoc, | ||||
9517 | SourceLocation LParenLoc, | ||||
9518 | SourceLocation EndLoc) { | ||||
9519 | SmallVector<Expr *, 8> Vars; | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9520 | for (auto &RefExpr : VarList) { |
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9521 | assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9522 | SourceLocation ELoc; |
9523 | SourceRange ERange; | ||||
9524 | Expr *SimpleRefExpr = RefExpr; | ||||
9525 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9526 | if (Res.second) { |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9527 | // It will be analyzed later. |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9528 | Vars.push_back(RefExpr); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9529 | } |
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9530 | ValueDecl *D = Res.first; |
9531 | if (!D) | ||||
9532 | continue; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9533 | |
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9534 | auto *VD = dyn_cast<VarDecl>(D); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9535 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
9536 | // in a Construct] | ||||
9537 | // Variables with the predetermined data-sharing attributes may not be | ||||
9538 | // listed in data-sharing attributes clauses, except for the cases | ||||
9539 | // listed below. For these exceptions only, listing a predetermined | ||||
9540 | // variable in a data-sharing attribute clause is allowed and overrides | ||||
9541 | // the variable's predetermined data-sharing attributes. | ||||
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9542 | DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9543 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && |
9544 | DVar.RefExpr) { | ||||
9545 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||
9546 | << getOpenMPClauseName(OMPC_shared); | ||||
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9547 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9548 | continue; |
9549 | } | ||||
9550 | |||||
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9551 | DeclRefExpr *Ref = nullptr; |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9552 | if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) |
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 9553 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); |
Alexey Bataev | b7a34b6 | 2016-02-25 03:59:29 +0000 | [diff] [blame] | 9554 | DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 9555 | Vars.push_back((VD || !Ref || CurContext->isDependentContext()) |
9556 | ? RefExpr->IgnoreParens() | ||||
9557 | : Ref); | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9558 | } |
9559 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 9560 | if (Vars.empty()) |
9561 | return nullptr; | ||||
Alexey Bataev | 758e55e | 2013-09-06 18:03:48 +0000 | [diff] [blame] | 9562 | |
9563 | return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | ||||
9564 | } | ||||
9565 | |||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9566 | namespace { |
9567 | class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { | ||||
9568 | DSAStackTy *Stack; | ||||
9569 | |||||
9570 | public: | ||||
9571 | bool VisitDeclRefExpr(DeclRefExpr *E) { | ||||
9572 | if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { | ||||
Alexey Bataev | 9c2e8ee | 2014-07-11 11:25:16 +0000 | [diff] [blame] | 9573 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9574 | if (DVar.CKind == OMPC_shared && !DVar.RefExpr) |
9575 | return false; | ||||
9576 | if (DVar.CKind != OMPC_unknown) | ||||
9577 | return true; | ||||
Alexey Bataev | 7ace49d | 2016-05-17 08:55:33 +0000 | [diff] [blame] | 9578 | DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( |
9579 | VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, | ||||
Alexey Bataev | effbdf1 | 2017-07-21 17:24:30 +0000 | [diff] [blame] | 9580 | /*FromParent=*/true); |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 9581 | if (DVarPrivate.CKind != OMPC_unknown) |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9582 | return true; |
9583 | return false; | ||||
9584 | } | ||||
9585 | return false; | ||||
9586 | } | ||||
9587 | bool VisitStmt(Stmt *S) { | ||||
9588 | for (auto Child : S->children()) { | ||||
9589 | if (Child && Visit(Child)) | ||||
9590 | return true; | ||||
9591 | } | ||||
9592 | return false; | ||||
9593 | } | ||||
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 9594 | explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9595 | }; |
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 9596 | } // namespace |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9597 | |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9598 | namespace { |
9599 | // Transform MemberExpression for specified FieldDecl of current class to | ||||
9600 | // DeclRefExpr to specified OMPCapturedExprDecl. | ||||
9601 | class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { | ||||
9602 | typedef TreeTransform<TransformExprToCaptures> BaseTransform; | ||||
9603 | ValueDecl *Field; | ||||
9604 | DeclRefExpr *CapturedExpr; | ||||
9605 | |||||
9606 | public: | ||||
9607 | TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) | ||||
9608 | : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} | ||||
9609 | |||||
9610 | ExprResult TransformMemberExpr(MemberExpr *E) { | ||||
9611 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && | ||||
9612 | E->getMemberDecl() == Field) { | ||||
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 9613 | CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9614 | return CapturedExpr; |
9615 | } | ||||
9616 | return BaseTransform::TransformMemberExpr(E); | ||||
9617 | } | ||||
9618 | DeclRefExpr *getCapturedExpr() { return CapturedExpr; } | ||||
9619 | }; | ||||
9620 | } // namespace | ||||
9621 | |||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9622 | template <typename T> |
9623 | static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, | ||||
9624 | const llvm::function_ref<T(ValueDecl *)> &Gen) { | ||||
9625 | for (auto &Set : Lookups) { | ||||
9626 | for (auto *D : Set) { | ||||
9627 | if (auto Res = Gen(cast<ValueDecl>(D))) | ||||
9628 | return Res; | ||||
9629 | } | ||||
9630 | } | ||||
9631 | return T(); | ||||
9632 | } | ||||
9633 | |||||
9634 | static ExprResult | ||||
9635 | buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, | ||||
9636 | Scope *S, CXXScopeSpec &ReductionIdScopeSpec, | ||||
9637 | const DeclarationNameInfo &ReductionId, QualType Ty, | ||||
9638 | CXXCastPath &BasePath, Expr *UnresolvedReduction) { | ||||
9639 | if (ReductionIdScopeSpec.isInvalid()) | ||||
9640 | return ExprError(); | ||||
9641 | SmallVector<UnresolvedSet<8>, 4> Lookups; | ||||
9642 | if (S) { | ||||
9643 | LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); | ||||
9644 | Lookup.suppressDiagnostics(); | ||||
9645 | while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { | ||||
9646 | auto *D = Lookup.getRepresentativeDecl(); | ||||
9647 | do { | ||||
9648 | S = S->getParent(); | ||||
9649 | } while (S && !S->isDeclScope(D)); | ||||
9650 | if (S) | ||||
9651 | S = S->getParent(); | ||||
9652 | Lookups.push_back(UnresolvedSet<8>()); | ||||
9653 | Lookups.back().append(Lookup.begin(), Lookup.end()); | ||||
9654 | Lookup.clear(); | ||||
9655 | } | ||||
9656 | } else if (auto *ULE = | ||||
9657 | cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { | ||||
9658 | Lookups.push_back(UnresolvedSet<8>()); | ||||
9659 | Decl *PrevD = nullptr; | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 9660 | for (auto *D : ULE->decls()) { |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9661 | if (D == PrevD) |
9662 | Lookups.push_back(UnresolvedSet<8>()); | ||||
9663 | else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) | ||||
9664 | Lookups.back().addDecl(DRD); | ||||
9665 | PrevD = D; | ||||
9666 | } | ||||
9667 | } | ||||
Alexey Bataev | fdc2035 | 2017-08-25 15:43:55 +0000 | [diff] [blame] | 9668 | if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || |
9669 | Ty->isInstantiationDependentType() || | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9670 | Ty->containsUnexpandedParameterPack() || |
9671 | filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { | ||||
9672 | return !D->isInvalidDecl() && | ||||
9673 | (D->getType()->isDependentType() || | ||||
9674 | D->getType()->isInstantiationDependentType() || | ||||
9675 | D->getType()->containsUnexpandedParameterPack()); | ||||
9676 | })) { | ||||
9677 | UnresolvedSet<8> ResSet; | ||||
9678 | for (auto &Set : Lookups) { | ||||
9679 | ResSet.append(Set.begin(), Set.end()); | ||||
9680 | // The last item marks the end of all declarations at the specified scope. | ||||
9681 | ResSet.addDecl(Set[Set.size() - 1]); | ||||
9682 | } | ||||
9683 | return UnresolvedLookupExpr::Create( | ||||
9684 | SemaRef.Context, /*NamingClass=*/nullptr, | ||||
9685 | ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, | ||||
9686 | /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); | ||||
9687 | } | ||||
9688 | if (auto *VD = filterLookupForUDR<ValueDecl *>( | ||||
9689 | Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { | ||||
9690 | if (!D->isInvalidDecl() && | ||||
9691 | SemaRef.Context.hasSameType(D->getType(), Ty)) | ||||
9692 | return D; | ||||
9693 | return nullptr; | ||||
9694 | })) | ||||
9695 | return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); | ||||
9696 | if (auto *VD = filterLookupForUDR<ValueDecl *>( | ||||
9697 | Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { | ||||
9698 | if (!D->isInvalidDecl() && | ||||
9699 | SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && | ||||
9700 | !Ty.isMoreQualifiedThan(D->getType())) | ||||
9701 | return D; | ||||
9702 | return nullptr; | ||||
9703 | })) { | ||||
9704 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||
9705 | /*DetectVirtual=*/false); | ||||
9706 | if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { | ||||
9707 | if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( | ||||
9708 | VD->getType().getUnqualifiedType()))) { | ||||
9709 | if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), | ||||
9710 | /*DiagID=*/0) != | ||||
9711 | Sema::AR_inaccessible) { | ||||
9712 | SemaRef.BuildBasePathArray(Paths, BasePath); | ||||
9713 | return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); | ||||
9714 | } | ||||
9715 | } | ||||
9716 | } | ||||
9717 | } | ||||
9718 | if (ReductionIdScopeSpec.isSet()) { | ||||
9719 | SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; | ||||
9720 | return ExprError(); | ||||
9721 | } | ||||
9722 | return ExprEmpty(); | ||||
9723 | } | ||||
9724 | |||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9725 | namespace { |
9726 | /// Data for the reduction-based clauses. | ||||
9727 | struct ReductionData { | ||||
9728 | /// List of original reduction items. | ||||
9729 | SmallVector<Expr *, 8> Vars; | ||||
9730 | /// List of private copies of the reduction items. | ||||
9731 | SmallVector<Expr *, 8> Privates; | ||||
9732 | /// LHS expressions for the reduction_op expressions. | ||||
9733 | SmallVector<Expr *, 8> LHSs; | ||||
9734 | /// RHS expressions for the reduction_op expressions. | ||||
9735 | SmallVector<Expr *, 8> RHSs; | ||||
9736 | /// Reduction operation expression. | ||||
9737 | SmallVector<Expr *, 8> ReductionOps; | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 9738 | /// Taskgroup descriptors for the corresponding reduction items in |
9739 | /// in_reduction clauses. | ||||
9740 | SmallVector<Expr *, 8> TaskgroupDescriptors; | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9741 | /// List of captures for clause. |
9742 | SmallVector<Decl *, 4> ExprCaptures; | ||||
9743 | /// List of postupdate expressions. | ||||
9744 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||
9745 | ReductionData() = delete; | ||||
9746 | /// Reserves required memory for the reduction data. | ||||
9747 | ReductionData(unsigned Size) { | ||||
9748 | Vars.reserve(Size); | ||||
9749 | Privates.reserve(Size); | ||||
9750 | LHSs.reserve(Size); | ||||
9751 | RHSs.reserve(Size); | ||||
9752 | ReductionOps.reserve(Size); | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 9753 | TaskgroupDescriptors.reserve(Size); |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9754 | ExprCaptures.reserve(Size); |
9755 | ExprPostUpdates.reserve(Size); | ||||
9756 | } | ||||
9757 | /// Stores reduction item and reduction operation only (required for dependent | ||||
9758 | /// reduction item). | ||||
9759 | void push(Expr *Item, Expr *ReductionOp) { | ||||
9760 | Vars.emplace_back(Item); | ||||
9761 | Privates.emplace_back(nullptr); | ||||
9762 | LHSs.emplace_back(nullptr); | ||||
9763 | RHSs.emplace_back(nullptr); | ||||
9764 | ReductionOps.emplace_back(ReductionOp); | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 9765 | TaskgroupDescriptors.emplace_back(nullptr); |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9766 | } |
9767 | /// Stores reduction data. | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 9768 | void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, |
9769 | Expr *TaskgroupDescriptor) { | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9770 | Vars.emplace_back(Item); |
9771 | Privates.emplace_back(Private); | ||||
9772 | LHSs.emplace_back(LHS); | ||||
9773 | RHSs.emplace_back(RHS); | ||||
9774 | ReductionOps.emplace_back(ReductionOp); | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 9775 | TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9776 | } |
9777 | }; | ||||
9778 | } // namespace | ||||
9779 | |||||
Jonas Hahnfeld | 4525c82 | 2017-10-23 19:01:35 +0000 | [diff] [blame] | 9780 | static bool CheckOMPArraySectionConstantForReduction( |
9781 | ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, | ||||
9782 | SmallVectorImpl<llvm::APSInt> &ArraySizes) { | ||||
9783 | const Expr *Length = OASE->getLength(); | ||||
9784 | if (Length == nullptr) { | ||||
9785 | // For array sections of the form [1:] or [:], we would need to analyze | ||||
9786 | // the lower bound... | ||||
9787 | if (OASE->getColonLoc().isValid()) | ||||
9788 | return false; | ||||
9789 | |||||
9790 | // This is an array subscript which has implicit length 1! | ||||
9791 | SingleElement = true; | ||||
9792 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||
9793 | } else { | ||||
9794 | llvm::APSInt ConstantLengthValue; | ||||
9795 | if (!Length->EvaluateAsInt(ConstantLengthValue, Context)) | ||||
9796 | return false; | ||||
9797 | |||||
9798 | SingleElement = (ConstantLengthValue.getSExtValue() == 1); | ||||
9799 | ArraySizes.push_back(ConstantLengthValue); | ||||
9800 | } | ||||
9801 | |||||
9802 | // Get the base of this array section and walk up from there. | ||||
9803 | const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); | ||||
9804 | |||||
9805 | // We require length = 1 for all array sections except the right-most to | ||||
9806 | // guarantee that the memory region is contiguous and has no holes in it. | ||||
9807 | while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { | ||||
9808 | Length = TempOASE->getLength(); | ||||
9809 | if (Length == nullptr) { | ||||
9810 | // For array sections of the form [1:] or [:], we would need to analyze | ||||
9811 | // the lower bound... | ||||
9812 | if (OASE->getColonLoc().isValid()) | ||||
9813 | return false; | ||||
9814 | |||||
9815 | // This is an array subscript which has implicit length 1! | ||||
9816 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||
9817 | } else { | ||||
9818 | llvm::APSInt ConstantLengthValue; | ||||
9819 | if (!Length->EvaluateAsInt(ConstantLengthValue, Context) || | ||||
9820 | ConstantLengthValue.getSExtValue() != 1) | ||||
9821 | return false; | ||||
9822 | |||||
9823 | ArraySizes.push_back(ConstantLengthValue); | ||||
9824 | } | ||||
9825 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); | ||||
9826 | } | ||||
9827 | |||||
9828 | // If we have a single element, we don't need to add the implicit lengths. | ||||
9829 | if (!SingleElement) { | ||||
9830 | while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { | ||||
9831 | // Has implicit length 1! | ||||
9832 | ArraySizes.push_back(llvm::APSInt::get(1)); | ||||
9833 | Base = TempASE->getBase()->IgnoreParenImpCasts(); | ||||
9834 | } | ||||
9835 | } | ||||
9836 | |||||
9837 | // This array section can be privatized as a single value or as a constant | ||||
9838 | // sized array. | ||||
9839 | return true; | ||||
9840 | } | ||||
9841 | |||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9842 | static bool ActOnOMPReductionKindClause( |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 9843 | Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, |
9844 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||
9845 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||
9846 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9847 | ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9848 | auto DN = ReductionId.getName(); |
9849 | auto OOK = DN.getCXXOverloadedOperator(); | ||||
9850 | BinaryOperatorKind BOK = BO_Comma; | ||||
9851 | |||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9852 | ASTContext &Context = S.Context; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9853 | // OpenMP [2.14.3.6, reduction clause] |
9854 | // C | ||||
9855 | // reduction-identifier is either an identifier or one of the following | ||||
9856 | // operators: +, -, *, &, |, ^, && and || | ||||
9857 | // C++ | ||||
9858 | // reduction-identifier is either an id-expression or one of the following | ||||
9859 | // operators: +, -, *, &, |, ^, && and || | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9860 | switch (OOK) { |
9861 | case OO_Plus: | ||||
9862 | case OO_Minus: | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9863 | BOK = BO_Add; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9864 | break; |
9865 | case OO_Star: | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9866 | BOK = BO_Mul; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9867 | break; |
9868 | case OO_Amp: | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9869 | BOK = BO_And; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9870 | break; |
9871 | case OO_Pipe: | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9872 | BOK = BO_Or; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9873 | break; |
9874 | case OO_Caret: | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9875 | BOK = BO_Xor; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9876 | break; |
9877 | case OO_AmpAmp: | ||||
9878 | BOK = BO_LAnd; | ||||
9879 | break; | ||||
9880 | case OO_PipePipe: | ||||
9881 | BOK = BO_LOr; | ||||
9882 | break; | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9883 | case OO_New: |
9884 | case OO_Delete: | ||||
9885 | case OO_Array_New: | ||||
9886 | case OO_Array_Delete: | ||||
9887 | case OO_Slash: | ||||
9888 | case OO_Percent: | ||||
9889 | case OO_Tilde: | ||||
9890 | case OO_Exclaim: | ||||
9891 | case OO_Equal: | ||||
9892 | case OO_Less: | ||||
9893 | case OO_Greater: | ||||
9894 | case OO_LessEqual: | ||||
9895 | case OO_GreaterEqual: | ||||
9896 | case OO_PlusEqual: | ||||
9897 | case OO_MinusEqual: | ||||
9898 | case OO_StarEqual: | ||||
9899 | case OO_SlashEqual: | ||||
9900 | case OO_PercentEqual: | ||||
9901 | case OO_CaretEqual: | ||||
9902 | case OO_AmpEqual: | ||||
9903 | case OO_PipeEqual: | ||||
9904 | case OO_LessLess: | ||||
9905 | case OO_GreaterGreater: | ||||
9906 | case OO_LessLessEqual: | ||||
9907 | case OO_GreaterGreaterEqual: | ||||
9908 | case OO_EqualEqual: | ||||
9909 | case OO_ExclaimEqual: | ||||
Richard Smith | d30b23d | 2017-12-01 02:13:10 +0000 | [diff] [blame] | 9910 | case OO_Spaceship: |
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9911 | case OO_PlusPlus: |
9912 | case OO_MinusMinus: | ||||
9913 | case OO_Comma: | ||||
9914 | case OO_ArrowStar: | ||||
9915 | case OO_Arrow: | ||||
9916 | case OO_Call: | ||||
9917 | case OO_Subscript: | ||||
9918 | case OO_Conditional: | ||||
Richard Smith | 9be594e | 2015-10-22 05:12:22 +0000 | [diff] [blame] | 9919 | case OO_Coawait: |
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 9920 | case NUM_OVERLOADED_OPERATORS: |
9921 | llvm_unreachable("Unexpected reduction identifier"); | ||||
9922 | case OO_None: | ||||
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 9923 | if (auto *II = DN.getAsIdentifierInfo()) { |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9924 | if (II->isStr("max")) |
9925 | BOK = BO_GT; | ||||
9926 | else if (II->isStr("min")) | ||||
9927 | BOK = BO_LT; | ||||
9928 | } | ||||
9929 | break; | ||||
9930 | } | ||||
9931 | SourceRange ReductionIdRange; | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9932 | if (ReductionIdScopeSpec.isValid()) |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9933 | ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 9934 | else |
9935 | ReductionIdRange.setBegin(ReductionId.getBeginLoc()); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9936 | ReductionIdRange.setEnd(ReductionId.getEndLoc()); |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9937 | |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9938 | auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); |
9939 | bool FirstIter = true; | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9940 | for (auto RefExpr : VarList) { |
9941 | assert(RefExpr && "nullptr expr in OpenMP reduction clause."); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9942 | // OpenMP [2.1, C/C++] |
9943 | // A list item is a variable or array section, subject to the restrictions | ||||
9944 | // specified in Section 2.4 on page 42 and in each of the sections | ||||
9945 | // describing clauses and directives for which a list appears. | ||||
9946 | // OpenMP [2.14.3.3, Restrictions, p.1] | ||||
9947 | // A variable that is part of another variable (as an array or | ||||
9948 | // structure element) cannot appear in a private clause. | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9949 | if (!FirstIter && IR != ER) |
9950 | ++IR; | ||||
9951 | FirstIter = false; | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9952 | SourceLocation ELoc; |
9953 | SourceRange ERange; | ||||
9954 | Expr *SimpleRefExpr = RefExpr; | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9955 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9956 | /*AllowArraySection=*/true); |
9957 | if (Res.second) { | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9958 | // Try to find 'declare reduction' corresponding construct before using |
9959 | // builtin/overloaded operators. | ||||
9960 | QualType Type = Context.DependentTy; | ||||
9961 | CXXCastPath BasePath; | ||||
9962 | ExprResult DeclareReductionRef = buildDeclareReductionRef( | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9963 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9964 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9965 | Expr *ReductionOp = nullptr; |
9966 | if (S.CurContext->isDependentContext() && | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 9967 | (DeclareReductionRef.isUnset() || |
9968 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9969 | ReductionOp = DeclareReductionRef.get(); |
9970 | // It will be analyzed later. | ||||
9971 | RD.push(RefExpr, ReductionOp); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9972 | } |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9973 | ValueDecl *D = Res.first; |
9974 | if (!D) | ||||
9975 | continue; | ||||
9976 | |||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 9977 | Expr *TaskgroupDescriptor = nullptr; |
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 9978 | QualType Type; |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9979 | auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); |
9980 | auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); | ||||
9981 | if (ASE) | ||||
Alexey Bataev | 31300ed | 2016-02-04 11:27:03 +0000 | [diff] [blame] | 9982 | Type = ASE->getType().getNonReferenceType(); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9983 | else if (OASE) { |
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 9984 | auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); |
9985 | if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) | ||||
9986 | Type = ATy->getElementType(); | ||||
9987 | else | ||||
9988 | Type = BaseType->getPointeeType(); | ||||
Alexey Bataev | 31300ed | 2016-02-04 11:27:03 +0000 | [diff] [blame] | 9989 | Type = Type.getNonReferenceType(); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 9990 | } else |
9991 | Type = Context.getBaseElementType(D->getType().getNonReferenceType()); | ||||
9992 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 9993 | |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9994 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] |
9995 | // A variable that appears in a private clause must not have an incomplete | ||||
9996 | // type or a reference type. | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 9997 | if (S.RequireCompleteType(ELoc, Type, |
9998 | diag::err_omp_reduction_incomplete_type)) | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 9999 | continue; |
10000 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10001 | // A list item that appears in a reduction clause must not be |
10002 | // const-qualified. | ||||
10003 | if (Type.getNonReferenceType().isConstant(Context)) { | ||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10004 | S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10005 | if (!ASE && !OASE) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10006 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
10007 | VarDecl::DeclarationOnly; | ||||
10008 | S.Diag(D->getLocation(), | ||||
10009 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10010 | << D; |
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 10011 | } |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10012 | continue; |
10013 | } | ||||
10014 | // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] | ||||
10015 | // If a list-item is a reference type then it must bind to the same object | ||||
10016 | // for all threads of the team. | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10017 | if (!ASE && !OASE && VD) { |
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 10018 | VarDecl *VDDef = VD->getDefinition(); |
David Sheinkman | 9258999 | 2016-10-04 14:41:36 +0000 | [diff] [blame] | 10019 | if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10020 | DSARefChecker Check(Stack); |
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 10021 | if (Check.Visit(VDDef->getInit())) { |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10022 | S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) |
10023 | << getOpenMPClauseName(ClauseKind) << ERange; | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10024 | S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; |
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 10025 | continue; |
10026 | } | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10027 | } |
10028 | } | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10029 | |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10030 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced |
10031 | // in a Construct] | ||||
10032 | // Variables with the predetermined data-sharing attributes may not be | ||||
10033 | // listed in data-sharing attributes clauses, except for the cases | ||||
10034 | // listed below. For these exceptions only, listing a predetermined | ||||
10035 | // variable in a data-sharing attribute clause is allowed and overrides | ||||
10036 | // the variable's predetermined data-sharing attributes. | ||||
10037 | // OpenMP [2.14.3.6, Restrictions, p.3] | ||||
10038 | // Any number of reduction clauses can be specified on the directive, | ||||
10039 | // but a list item can appear only once in the reduction clauses for that | ||||
10040 | // directive. | ||||
Alexey Bataev | a176421 | 2015-09-30 09:22:36 +0000 | [diff] [blame] | 10041 | DSAStackTy::DSAVarData DVar; |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10042 | DVar = Stack->getTopDSA(D, false); |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10043 | if (DVar.CKind == OMPC_reduction) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10044 | S.Diag(ELoc, diag::err_omp_once_referenced) |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10045 | << getOpenMPClauseName(ClauseKind); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10046 | if (DVar.RefExpr) |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10047 | S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 10048 | continue; |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10049 | } else if (DVar.CKind != OMPC_unknown) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10050 | S.Diag(ELoc, diag::err_omp_wrong_dsa) |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10051 | << getOpenMPClauseName(DVar.CKind) |
10052 | << getOpenMPClauseName(OMPC_reduction); | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10053 | ReportOriginalDSA(S, Stack, D, DVar); |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10054 | continue; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10055 | } |
10056 | |||||
10057 | // OpenMP [2.14.3.6, Restrictions, p.1] | ||||
10058 | // A list item that appears in a reduction clause of a worksharing | ||||
10059 | // construct must be shared in the parallel regions to which any of the | ||||
10060 | // worksharing regions arising from the worksharing construct bind. | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10061 | OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10062 | if (isOpenMPWorksharingDirective(CurrDir) && |
Kelvin Li | 579e41c | 2016-11-30 23:51:03 +0000 | [diff] [blame] | 10063 | !isOpenMPParallelDirective(CurrDir) && |
10064 | !isOpenMPTeamsDirective(CurrDir)) { | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10065 | DVar = Stack->getImplicitDSA(D, true); |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10066 | if (DVar.CKind != OMPC_shared) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10067 | S.Diag(ELoc, diag::err_omp_required_access) |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10068 | << getOpenMPClauseName(OMPC_reduction) |
10069 | << getOpenMPClauseName(OMPC_shared); | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10070 | ReportOriginalDSA(S, Stack, D, DVar); |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10071 | continue; |
Alexey Bataev | f29276e | 2014-06-18 04:14:57 +0000 | [diff] [blame] | 10072 | } |
10073 | } | ||||
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10074 | |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10075 | // Try to find 'declare reduction' corresponding construct before using |
10076 | // builtin/overloaded operators. | ||||
10077 | CXXCastPath BasePath; | ||||
10078 | ExprResult DeclareReductionRef = buildDeclareReductionRef( | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10079 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10080 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); |
10081 | if (DeclareReductionRef.isInvalid()) | ||||
10082 | continue; | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10083 | if (S.CurContext->isDependentContext() && |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10084 | (DeclareReductionRef.isUnset() || |
10085 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10086 | RD.push(RefExpr, DeclareReductionRef.get()); |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10087 | continue; |
10088 | } | ||||
10089 | if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { | ||||
10090 | // Not allowed reduction identifier is found. | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10091 | S.Diag(ReductionId.getLocStart(), |
10092 | diag::err_omp_unknown_reduction_identifier) | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10093 | << Type << ReductionIdRange; |
10094 | continue; | ||||
10095 | } | ||||
10096 | |||||
10097 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | ||||
10098 | // The type of a list item that appears in a reduction clause must be valid | ||||
10099 | // for the reduction-identifier. For a max or min reduction in C, the type | ||||
10100 | // of the list item must be an allowed arithmetic data type: char, int, | ||||
10101 | // float, double, or _Bool, possibly modified with long, short, signed, or | ||||
10102 | // unsigned. For a max or min reduction in C++, the type of the list item | ||||
10103 | // must be an allowed arithmetic data type: char, wchar_t, int, float, | ||||
10104 | // double, or bool, possibly modified with long, short, signed, or unsigned. | ||||
10105 | if (DeclareReductionRef.isUnset()) { | ||||
10106 | if ((BOK == BO_GT || BOK == BO_LT) && | ||||
10107 | !(Type->isScalarType() || | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10108 | (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { |
10109 | S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) | ||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10110 | << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10111 | if (!ASE && !OASE) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10112 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
10113 | VarDecl::DeclarationOnly; | ||||
10114 | S.Diag(D->getLocation(), | ||||
10115 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10116 | << D; |
10117 | } | ||||
10118 | continue; | ||||
10119 | } | ||||
10120 | if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10121 | !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10122 | S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) |
10123 | << getOpenMPClauseName(ClauseKind); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10124 | if (!ASE && !OASE) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10125 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
10126 | VarDecl::DeclarationOnly; | ||||
10127 | S.Diag(D->getLocation(), | ||||
10128 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10129 | << D; |
10130 | } | ||||
10131 | continue; | ||||
10132 | } | ||||
10133 | } | ||||
10134 | |||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 10135 | Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10136 | auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10137 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10138 | auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10139 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10140 | auto PrivateTy = Type; |
Jonas Hahnfeld | 4525c82 | 2017-10-23 19:01:35 +0000 | [diff] [blame] | 10141 | |
10142 | // Try if we can determine constant lengths for all array sections and avoid | ||||
10143 | // the VLA. | ||||
10144 | bool ConstantLengthOASE = false; | ||||
10145 | if (OASE) { | ||||
10146 | bool SingleElement; | ||||
10147 | llvm::SmallVector<llvm::APSInt, 4> ArraySizes; | ||||
10148 | ConstantLengthOASE = CheckOMPArraySectionConstantForReduction( | ||||
10149 | Context, OASE, SingleElement, ArraySizes); | ||||
10150 | |||||
10151 | // If we don't have a single element, we must emit a constant array type. | ||||
10152 | if (ConstantLengthOASE && !SingleElement) { | ||||
10153 | for (auto &Size : ArraySizes) { | ||||
10154 | PrivateTy = Context.getConstantArrayType( | ||||
10155 | PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); | ||||
10156 | } | ||||
10157 | } | ||||
10158 | } | ||||
10159 | |||||
10160 | if ((OASE && !ConstantLengthOASE) || | ||||
Jonas Hahnfeld | 96087f3 | 2017-11-02 13:30:42 +0000 | [diff] [blame] | 10161 | (!OASE && !ASE && |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10162 | D->getType().getNonReferenceType()->isVariablyModifiedType())) { |
Jonas Hahnfeld | 87d4426 | 2017-11-18 21:00:46 +0000 | [diff] [blame] | 10163 | if (!Context.getTargetInfo().isVLASupported() && |
10164 | S.shouldDiagnoseTargetSupportFromOpenMP()) { | ||||
10165 | S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; | ||||
10166 | S.Diag(ELoc, diag::note_vla_unsupported); | ||||
10167 | continue; | ||||
10168 | } | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 10169 | // For arrays/array sections only: |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10170 | // Create pseudo array type for private copy. The size for this array will |
10171 | // be generated during codegen. | ||||
10172 | // For array subscripts or single variables Private Ty is the same as Type | ||||
10173 | // (type of the variable or single array element). | ||||
10174 | PrivateTy = Context.getVariableArrayType( | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10175 | Type, |
Alexey Bataev | d070a58 | 2017-10-25 15:54:04 +0000 | [diff] [blame] | 10176 | new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), |
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10177 | ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10178 | } else if (!ASE && !OASE && |
10179 | Context.getAsArrayType(D->getType().getNonReferenceType())) | ||||
10180 | PrivateTy = D->getType().getNonReferenceType(); | ||||
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10181 | // Private copy. |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10182 | auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(), |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10183 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 10184 | // Add initializer for private variable. |
10185 | Expr *Init = nullptr; | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10186 | auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); |
10187 | auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10188 | if (DeclareReductionRef.isUsable()) { |
10189 | auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); | ||||
10190 | auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); | ||||
10191 | if (DRD->getInitializer()) { | ||||
10192 | Init = DRDRef; | ||||
10193 | RHSVD->setInit(DRDRef); | ||||
10194 | RHSVD->setInitStyle(VarDecl::CallInit); | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 10195 | } |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10196 | } else { |
10197 | switch (BOK) { | ||||
10198 | case BO_Add: | ||||
10199 | case BO_Xor: | ||||
10200 | case BO_Or: | ||||
10201 | case BO_LOr: | ||||
10202 | // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. | ||||
10203 | if (Type->isScalarType() || Type->isAnyComplexType()) | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10204 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10205 | break; |
10206 | case BO_Mul: | ||||
10207 | case BO_LAnd: | ||||
10208 | if (Type->isScalarType() || Type->isAnyComplexType()) { | ||||
10209 | // '*' and '&&' reduction ops - initializer is '1'. | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10210 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10211 | } |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10212 | break; |
10213 | case BO_And: { | ||||
10214 | // '&' reduction op - initializer is '~0'. | ||||
10215 | QualType OrigType = Type; | ||||
10216 | if (auto *ComplexTy = OrigType->getAs<ComplexType>()) | ||||
10217 | Type = ComplexTy->getElementType(); | ||||
10218 | if (Type->isRealFloatingType()) { | ||||
10219 | llvm::APFloat InitValue = | ||||
10220 | llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), | ||||
10221 | /*isIEEE=*/true); | ||||
10222 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | ||||
10223 | Type, ELoc); | ||||
10224 | } else if (Type->isScalarType()) { | ||||
10225 | auto Size = Context.getTypeSize(Type); | ||||
10226 | QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); | ||||
10227 | llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); | ||||
10228 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); | ||||
10229 | } | ||||
10230 | if (Init && OrigType->isAnyComplexType()) { | ||||
10231 | // Init = 0xFFFF + 0xFFFFi; | ||||
10232 | auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10233 | Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10234 | } |
10235 | Type = OrigType; | ||||
10236 | break; | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 10237 | } |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10238 | case BO_LT: |
10239 | case BO_GT: { | ||||
10240 | // 'min' reduction op - initializer is 'Largest representable number in | ||||
10241 | // the reduction list item type'. | ||||
10242 | // 'max' reduction op - initializer is 'Least representable number in | ||||
10243 | // the reduction list item type'. | ||||
10244 | if (Type->isIntegerType() || Type->isPointerType()) { | ||||
10245 | bool IsSigned = Type->hasSignedIntegerRepresentation(); | ||||
10246 | auto Size = Context.getTypeSize(Type); | ||||
10247 | QualType IntTy = | ||||
10248 | Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); | ||||
10249 | llvm::APInt InitValue = | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10250 | (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) |
10251 | : llvm::APInt::getMinValue(Size) | ||||
10252 | : IsSigned ? llvm::APInt::getSignedMaxValue(Size) | ||||
10253 | : llvm::APInt::getMaxValue(Size); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10254 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); |
10255 | if (Type->isPointerType()) { | ||||
10256 | // Cast to pointer type. | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10257 | auto CastExpr = S.BuildCStyleCastExpr( |
Alexey Bataev | d070a58 | 2017-10-25 15:54:04 +0000 | [diff] [blame] | 10258 | ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10259 | if (CastExpr.isInvalid()) |
10260 | continue; | ||||
10261 | Init = CastExpr.get(); | ||||
10262 | } | ||||
10263 | } else if (Type->isRealFloatingType()) { | ||||
10264 | llvm::APFloat InitValue = llvm::APFloat::getLargest( | ||||
10265 | Context.getFloatTypeSemantics(Type), BOK != BO_LT); | ||||
10266 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | ||||
10267 | Type, ELoc); | ||||
10268 | } | ||||
10269 | break; | ||||
10270 | } | ||||
10271 | case BO_PtrMemD: | ||||
10272 | case BO_PtrMemI: | ||||
10273 | case BO_MulAssign: | ||||
10274 | case BO_Div: | ||||
10275 | case BO_Rem: | ||||
10276 | case BO_Sub: | ||||
10277 | case BO_Shl: | ||||
10278 | case BO_Shr: | ||||
10279 | case BO_LE: | ||||
10280 | case BO_GE: | ||||
10281 | case BO_EQ: | ||||
10282 | case BO_NE: | ||||
10283 | case BO_AndAssign: | ||||
10284 | case BO_XorAssign: | ||||
10285 | case BO_OrAssign: | ||||
10286 | case BO_Assign: | ||||
10287 | case BO_AddAssign: | ||||
10288 | case BO_SubAssign: | ||||
10289 | case BO_DivAssign: | ||||
10290 | case BO_RemAssign: | ||||
10291 | case BO_ShlAssign: | ||||
10292 | case BO_ShrAssign: | ||||
10293 | case BO_Comma: | ||||
10294 | llvm_unreachable("Unexpected reduction operation"); | ||||
10295 | } | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 10296 | } |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10297 | if (Init && DeclareReductionRef.isUnset()) |
10298 | S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); | ||||
10299 | else if (!Init) | ||||
10300 | S.ActOnUninitializedDecl(RHSVD); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10301 | if (RHSVD->isInvalidDecl()) |
10302 | continue; | ||||
10303 | if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10304 | S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) |
10305 | << Type << ReductionIdRange; | ||||
10306 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == | ||||
10307 | VarDecl::DeclarationOnly; | ||||
10308 | S.Diag(D->getLocation(), | ||||
10309 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10310 | << D; |
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 10311 | continue; |
10312 | } | ||||
Alexey Bataev | f24e7b1 | 2015-10-08 09:10:53 +0000 | [diff] [blame] | 10313 | // Store initializer for single element in private copy. Will be used during |
10314 | // codegen. | ||||
10315 | PrivateVD->setInit(RHSVD->getInit()); | ||||
10316 | PrivateVD->setInitStyle(RHSVD->getInitStyle()); | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10317 | auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10318 | ExprResult ReductionOp; |
10319 | if (DeclareReductionRef.isUsable()) { | ||||
10320 | QualType RedTy = DeclareReductionRef.get()->getType(); | ||||
10321 | QualType PtrRedTy = Context.getPointerType(RedTy); | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10322 | ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); |
10323 | ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10324 | if (!BasePath.empty()) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10325 | LHS = S.DefaultLvalueConversion(LHS.get()); |
10326 | RHS = S.DefaultLvalueConversion(RHS.get()); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10327 | LHS = ImplicitCastExpr::Create(Context, PtrRedTy, |
10328 | CK_UncheckedDerivedToBase, LHS.get(), | ||||
10329 | &BasePath, LHS.get()->getValueKind()); | ||||
10330 | RHS = ImplicitCastExpr::Create(Context, PtrRedTy, | ||||
10331 | CK_UncheckedDerivedToBase, RHS.get(), | ||||
10332 | &BasePath, RHS.get()->getValueKind()); | ||||
Alexey Bataev | 794ba0d | 2015-04-10 10:43:45 +0000 | [diff] [blame] | 10333 | } |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10334 | FunctionProtoType::ExtProtoInfo EPI; |
10335 | QualType Params[] = {PtrRedTy, PtrRedTy}; | ||||
10336 | QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); | ||||
10337 | auto *OVE = new (Context) OpaqueValueExpr( | ||||
10338 | ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10339 | S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10340 | Expr *Args[] = {LHS.get(), RHS.get()}; |
10341 | ReductionOp = new (Context) | ||||
10342 | CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); | ||||
10343 | } else { | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10344 | ReductionOp = S.BuildBinOp( |
10345 | Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10346 | if (ReductionOp.isUsable()) { |
10347 | if (BOK != BO_LT && BOK != BO_GT) { | ||||
10348 | ReductionOp = | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10349 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), |
10350 | BO_Assign, LHSDRE, ReductionOp.get()); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10351 | } else { |
Alexey Bataev | d070a58 | 2017-10-25 15:54:04 +0000 | [diff] [blame] | 10352 | auto *ConditionalOp = new (Context) |
10353 | ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, | ||||
10354 | Type, VK_LValue, OK_Ordinary); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10355 | ReductionOp = |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10356 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), |
10357 | BO_Assign, LHSDRE, ConditionalOp); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10358 | } |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 10359 | if (ReductionOp.isUsable()) |
10360 | ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10361 | } |
Alexey Bataev | 4d4624c | 2017-07-20 16:47:47 +0000 | [diff] [blame] | 10362 | if (!ReductionOp.isUsable()) |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 10363 | continue; |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10364 | } |
10365 | |||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 10366 | // OpenMP [2.15.4.6, Restrictions, p.2] |
10367 | // A list item that appears in an in_reduction clause of a task construct | ||||
10368 | // must appear in a task_reduction clause of a construct associated with a | ||||
10369 | // taskgroup region that includes the participating task in its taskgroup | ||||
10370 | // set. The construct associated with the innermost region that meets this | ||||
10371 | // condition must specify the same reduction-identifier as the in_reduction | ||||
10372 | // clause. | ||||
10373 | if (ClauseKind == OMPC_in_reduction) { | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 10374 | SourceRange ParentSR; |
10375 | BinaryOperatorKind ParentBOK; | ||||
10376 | const Expr *ParentReductionOp; | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 10377 | Expr *ParentBOKTD, *ParentReductionOpTD; |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 10378 | DSAStackTy::DSAVarData ParentBOKDSA = |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 10379 | Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, |
10380 | ParentBOKTD); | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 10381 | DSAStackTy::DSAVarData ParentReductionOpDSA = |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 10382 | Stack->getTopMostTaskgroupReductionData( |
10383 | D, ParentSR, ParentReductionOp, ParentReductionOpTD); | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 10384 | bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; |
10385 | bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; | ||||
10386 | if (!IsParentBOK && !IsParentReductionOp) { | ||||
10387 | S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); | ||||
10388 | continue; | ||||
10389 | } | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 10390 | if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || |
10391 | (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || | ||||
10392 | IsParentReductionOp) { | ||||
10393 | bool EmitError = true; | ||||
10394 | if (IsParentReductionOp && DeclareReductionRef.isUsable()) { | ||||
10395 | llvm::FoldingSetNodeID RedId, ParentRedId; | ||||
10396 | ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); | ||||
10397 | DeclareReductionRef.get()->Profile(RedId, Context, | ||||
10398 | /*Canonical=*/true); | ||||
10399 | EmitError = RedId != ParentRedId; | ||||
10400 | } | ||||
10401 | if (EmitError) { | ||||
10402 | S.Diag(ReductionId.getLocStart(), | ||||
10403 | diag::err_omp_reduction_identifier_mismatch) | ||||
10404 | << ReductionIdRange << RefExpr->getSourceRange(); | ||||
10405 | S.Diag(ParentSR.getBegin(), | ||||
10406 | diag::note_omp_previous_reduction_identifier) | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 10407 | << ParentSR |
10408 | << (IsParentBOK ? ParentBOKDSA.RefExpr | ||||
10409 | : ParentReductionOpDSA.RefExpr) | ||||
10410 | ->getSourceRange(); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 10411 | continue; |
10412 | } | ||||
10413 | } | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 10414 | TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; |
10415 | assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); | ||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 10416 | } |
10417 | |||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10418 | DeclRefExpr *Ref = nullptr; |
10419 | Expr *VarsExpr = RefExpr->IgnoreParens(); | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10420 | if (!VD && !S.CurContext->isDependentContext()) { |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10421 | if (ASE || OASE) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10422 | TransformExprToCaptures RebuildToCapture(S, D); |
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10423 | VarsExpr = |
10424 | RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); | ||||
10425 | Ref = RebuildToCapture.getCapturedExpr(); | ||||
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 10426 | } else { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10427 | VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 10428 | } |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10429 | if (!S.IsOpenMPCapturedDecl(D)) { |
10430 | RD.ExprCaptures.emplace_back(Ref->getDecl()); | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 10431 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10432 | ExprResult RefRes = S.DefaultLvalueConversion(Ref); |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 10433 | if (!RefRes.isUsable()) |
10434 | continue; | ||||
10435 | ExprResult PostUpdateRes = | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10436 | S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, |
10437 | RefRes.get()); | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 10438 | if (!PostUpdateRes.isUsable()) |
10439 | continue; | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10440 | if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || |
10441 | Stack->getCurrentDirective() == OMPD_taskgroup) { | ||||
10442 | S.Diag(RefExpr->getExprLoc(), | ||||
10443 | diag::err_omp_reduction_non_addressable_expression) | ||||
Alexey Bataev | bcd0ae0 | 2017-07-11 19:16:44 +0000 | [diff] [blame] | 10444 | << RefExpr->getSourceRange(); |
10445 | continue; | ||||
10446 | } | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10447 | RD.ExprPostUpdates.emplace_back( |
10448 | S.IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 10449 | } |
10450 | } | ||||
Alexey Bataev | 60da77e | 2016-02-29 05:54:20 +0000 | [diff] [blame] | 10451 | } |
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10452 | // All reduction items are still marked as reduction (to do not increase |
10453 | // code base size). | ||||
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10454 | Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 10455 | if (CurrDir == OMPD_taskgroup) { |
10456 | if (DeclareReductionRef.isUsable()) | ||||
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 10457 | Stack->addTaskgroupReductionData(D, ReductionIdRange, |
10458 | DeclareReductionRef.get()); | ||||
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 10459 | else |
Alexey Bataev | 3b1b895 | 2017-07-25 15:53:26 +0000 | [diff] [blame] | 10460 | Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); |
Alexey Bataev | f189cb7 | 2017-07-24 14:52:13 +0000 | [diff] [blame] | 10461 | } |
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 10462 | RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), |
10463 | TaskgroupDescriptor); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10464 | } |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10465 | return RD.Vars.empty(); |
10466 | } | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10467 | |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10468 | OMPClause *Sema::ActOnOpenMPReductionClause( |
10469 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||
10470 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||
10471 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||
10472 | ArrayRef<Expr *> UnresolvedReductions) { | ||||
10473 | ReductionData RD(VarList.size()); | ||||
10474 | |||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10475 | if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, |
10476 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||
10477 | ReductionIdScopeSpec, ReductionId, | ||||
10478 | UnresolvedReductions, RD)) | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10479 | return nullptr; |
Alexey Bataev | 6120507 | 2016-03-02 04:57:40 +0000 | [diff] [blame] | 10480 | |
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10481 | return OMPReductionClause::Create( |
Alexey Bataev | fad872fc | 2017-07-18 15:32:58 +0000 | [diff] [blame] | 10482 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, |
10483 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||
10484 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, | ||||
10485 | buildPreInits(Context, RD.ExprCaptures), | ||||
10486 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||
Alexey Bataev | c5e0258 | 2014-06-16 07:08:35 +0000 | [diff] [blame] | 10487 | } |
10488 | |||||
Alexey Bataev | 169d96a | 2017-07-18 20:17:46 +0000 | [diff] [blame] | 10489 | OMPClause *Sema::ActOnOpenMPTaskReductionClause( |
10490 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||
10491 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||
10492 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||
10493 | ArrayRef<Expr *> UnresolvedReductions) { | ||||
10494 | ReductionData RD(VarList.size()); | ||||
10495 | |||||
10496 | if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, | ||||
10497 | VarList, StartLoc, LParenLoc, ColonLoc, | ||||
10498 | EndLoc, ReductionIdScopeSpec, ReductionId, | ||||
10499 | UnresolvedReductions, RD)) | ||||
10500 | return nullptr; | ||||
10501 | |||||
10502 | return OMPTaskReductionClause::Create( | ||||
10503 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, | ||||
10504 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||
10505 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, | ||||
10506 | buildPreInits(Context, RD.ExprCaptures), | ||||
10507 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||
10508 | } | ||||
10509 | |||||
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 10510 | OMPClause *Sema::ActOnOpenMPInReductionClause( |
10511 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | ||||
10512 | SourceLocation ColonLoc, SourceLocation EndLoc, | ||||
10513 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, | ||||
10514 | ArrayRef<Expr *> UnresolvedReductions) { | ||||
10515 | ReductionData RD(VarList.size()); | ||||
10516 | |||||
10517 | if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, | ||||
10518 | StartLoc, LParenLoc, ColonLoc, EndLoc, | ||||
10519 | ReductionIdScopeSpec, ReductionId, | ||||
10520 | UnresolvedReductions, RD)) | ||||
10521 | return nullptr; | ||||
10522 | |||||
10523 | return OMPInReductionClause::Create( | ||||
10524 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, | ||||
10525 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, | ||||
Alexey Bataev | 88202be | 2017-07-27 13:20:36 +0000 | [diff] [blame] | 10526 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, |
Alexey Bataev | fa312f3 | 2017-07-21 18:48:21 +0000 | [diff] [blame] | 10527 | buildPreInits(Context, RD.ExprCaptures), |
10528 | buildPostUpdate(*this, RD.ExprPostUpdates)); | ||||
10529 | } | ||||
10530 | |||||
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 10531 | bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, |
10532 | SourceLocation LinLoc) { | ||||
10533 | if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || | ||||
10534 | LinKind == OMPC_LINEAR_unknown) { | ||||
10535 | Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; | ||||
10536 | return true; | ||||
10537 | } | ||||
10538 | return false; | ||||
10539 | } | ||||
10540 | |||||
10541 | bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, | ||||
10542 | OpenMPLinearClauseKind LinKind, | ||||
10543 | QualType Type) { | ||||
10544 | auto *VD = dyn_cast_or_null<VarDecl>(D); | ||||
10545 | // A variable must not have an incomplete type or a reference type. | ||||
10546 | if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) | ||||
10547 | return true; | ||||
10548 | if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && | ||||
10549 | !Type->isReferenceType()) { | ||||
10550 | Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) | ||||
10551 | << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); | ||||
10552 | return true; | ||||
10553 | } | ||||
10554 | Type = Type.getNonReferenceType(); | ||||
10555 | |||||
10556 | // A list item must not be const-qualified. | ||||
10557 | if (Type.isConstant(Context)) { | ||||
10558 | Diag(ELoc, diag::err_omp_const_variable) | ||||
10559 | << getOpenMPClauseName(OMPC_linear); | ||||
10560 | if (D) { | ||||
10561 | bool IsDecl = | ||||
10562 | !VD || | ||||
10563 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
10564 | Diag(D->getLocation(), | ||||
10565 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
10566 | << D; | ||||
10567 | } | ||||
10568 | return true; | ||||
10569 | } | ||||
10570 | |||||
10571 | // A list item must be of integral or pointer type. | ||||
10572 | Type = Type.getUnqualifiedType().getCanonicalType(); | ||||
10573 | const auto *Ty = Type.getTypePtrOrNull(); | ||||
10574 | if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && | ||||
10575 | !Ty->isPointerType())) { | ||||
10576 | Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; | ||||
10577 | if (D) { | ||||
10578 | bool IsDecl = | ||||
10579 | !VD || | ||||
10580 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | ||||
10581 | Diag(D->getLocation(), | ||||
10582 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | ||||
10583 | << D; | ||||
10584 | } | ||||
10585 | return true; | ||||
10586 | } | ||||
10587 | return false; | ||||
10588 | } | ||||
10589 | |||||
Alexey Bataev | 182227b | 2015-08-20 10:54:39 +0000 | [diff] [blame] | 10590 | OMPClause *Sema::ActOnOpenMPLinearClause( |
10591 | ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, | ||||
10592 | SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, | ||||
10593 | SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10594 | SmallVector<Expr *, 8> Vars; |
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 10595 | SmallVector<Expr *, 8> Privates; |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10596 | SmallVector<Expr *, 8> Inits; |
Alexey Bataev | 78849fb | 2016-03-09 09:49:00 +0000 | [diff] [blame] | 10597 | SmallVector<Decl *, 4> ExprCaptures; |
10598 | SmallVector<Expr *, 4> ExprPostUpdates; | ||||
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 10599 | if (CheckOpenMPLinearModifier(LinKind, LinLoc)) |
Alexey Bataev | 182227b | 2015-08-20 10:54:39 +0000 | [diff] [blame] | 10600 | LinKind = OMPC_LINEAR_val; |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10601 | for (auto &RefExpr : VarList) { |
10602 | assert(RefExpr && "NULL expr in OpenMP linear clause."); | ||||
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10603 | SourceLocation ELoc; |
10604 | SourceRange ERange; | ||||
10605 | Expr *SimpleRefExpr = RefExpr; | ||||
10606 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||
10607 | /*AllowArraySection=*/false); | ||||
10608 | if (Res.second) { | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10609 | // It will be analyzed later. |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10610 | Vars.push_back(RefExpr); |
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 10611 | Privates.push_back(nullptr); |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10612 | Inits.push_back(nullptr); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10613 | } |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10614 | ValueDecl *D = Res.first; |
10615 | if (!D) | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10616 | continue; |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10617 | |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10618 | QualType Type = D->getType(); |
10619 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10620 | |
10621 | // OpenMP [2.14.3.7, linear clause] | ||||
10622 | // A list-item cannot appear in more than one linear clause. | ||||
10623 | // A list-item that appears in a linear clause cannot appear in any | ||||
10624 | // other data-sharing attribute clause. | ||||
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10625 | DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10626 | if (DVar.RefExpr) { |
10627 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | ||||
10628 | << getOpenMPClauseName(OMPC_linear); | ||||
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10629 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10630 | continue; |
10631 | } | ||||
10632 | |||||
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 10633 | if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10634 | continue; |
Alexey Bataev | ecba70f | 2016-04-12 11:02:11 +0000 | [diff] [blame] | 10635 | Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10636 | |
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 10637 | // Build private copy of original var. |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10638 | auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), |
10639 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||
10640 | auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10641 | // Build var to save initial value. |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10642 | VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); |
Alexey Bataev | 84cfb1d | 2015-08-21 06:41:23 +0000 | [diff] [blame] | 10643 | Expr *InitExpr; |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10644 | DeclRefExpr *Ref = nullptr; |
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 10645 | if (!VD && !CurContext->isDependentContext()) { |
Alexey Bataev | 78849fb | 2016-03-09 09:49:00 +0000 | [diff] [blame] | 10646 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); |
10647 | if (!IsOpenMPCapturedDecl(D)) { | ||||
10648 | ExprCaptures.push_back(Ref->getDecl()); | ||||
10649 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { | ||||
10650 | ExprResult RefRes = DefaultLvalueConversion(Ref); | ||||
10651 | if (!RefRes.isUsable()) | ||||
10652 | continue; | ||||
10653 | ExprResult PostUpdateRes = | ||||
10654 | BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, | ||||
10655 | SimpleRefExpr, RefRes.get()); | ||||
10656 | if (!PostUpdateRes.isUsable()) | ||||
10657 | continue; | ||||
10658 | ExprPostUpdates.push_back( | ||||
10659 | IgnoredValueConversions(PostUpdateRes.get()).get()); | ||||
10660 | } | ||||
10661 | } | ||||
10662 | } | ||||
Alexey Bataev | 84cfb1d | 2015-08-21 06:41:23 +0000 | [diff] [blame] | 10663 | if (LinKind == OMPC_LINEAR_uval) |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10664 | InitExpr = VD ? VD->getInit() : SimpleRefExpr; |
Alexey Bataev | 84cfb1d | 2015-08-21 06:41:23 +0000 | [diff] [blame] | 10665 | else |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10666 | InitExpr = VD ? SimpleRefExpr : Ref; |
Alexey Bataev | 84cfb1d | 2015-08-21 06:41:23 +0000 | [diff] [blame] | 10667 | AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), |
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 10668 | /*DirectInit=*/false); |
Alexey Bataev | 2bbf721 | 2016-03-03 03:52:24 +0000 | [diff] [blame] | 10669 | auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); |
10670 | |||||
10671 | DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); | ||||
Alexey Bataev | be8b8b5 | 2016-07-07 11:04:06 +0000 | [diff] [blame] | 10672 | Vars.push_back((VD || CurContext->isDependentContext()) |
10673 | ? RefExpr->IgnoreParens() | ||||
10674 | : Ref); | ||||
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 10675 | Privates.push_back(PrivateRef); |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10676 | Inits.push_back(InitRef); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10677 | } |
10678 | |||||
10679 | if (Vars.empty()) | ||||
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 10680 | return nullptr; |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10681 | |
10682 | Expr *StepExpr = Step; | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10683 | Expr *CalcStepExpr = nullptr; |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10684 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && |
10685 | !Step->isInstantiationDependent() && | ||||
10686 | !Step->containsUnexpandedParameterPack()) { | ||||
10687 | SourceLocation StepLoc = Step->getLocStart(); | ||||
Alexander Musman | a8e9d2e | 2014-06-03 10:16:47 +0000 | [diff] [blame] | 10688 | ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10689 | if (Val.isInvalid()) |
Alexander Musman | cb7f9c4 | 2014-05-15 13:04:49 +0000 | [diff] [blame] | 10690 | return nullptr; |
Nikola Smiljanic | 01a7598 | 2014-05-29 10:55:11 +0000 | [diff] [blame] | 10691 | StepExpr = Val.get(); |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10692 | |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10693 | // Build var to save the step value. |
10694 | VarDecl *SaveVar = | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 10695 | buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10696 | ExprResult SaveRef = |
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 10697 | buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10698 | ExprResult CalcStep = |
10699 | BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 10700 | CalcStep = ActOnFinishFullExpr(CalcStep.get()); |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10701 | |
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10702 | // Warn about zero linear step (it would be probably better specified as |
10703 | // making corresponding variables 'const'). | ||||
10704 | llvm::APSInt Result; | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10705 | bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); |
10706 | if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10707 | Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] |
10708 | << (Vars.size() > 1); | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10709 | if (!IsConstant && CalcStep.isUsable()) { |
10710 | // Calculate the step beforehand instead of doing this on each iteration. | ||||
10711 | // (This is not used if the number of iterations may be kfold-ed). | ||||
10712 | CalcStepExpr = CalcStep.get(); | ||||
10713 | } | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10714 | } |
10715 | |||||
Alexey Bataev | 182227b | 2015-08-20 10:54:39 +0000 | [diff] [blame] | 10716 | return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, |
10717 | ColonLoc, EndLoc, Vars, Privates, Inits, | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 10718 | StepExpr, CalcStepExpr, |
10719 | buildPreInits(Context, ExprCaptures), | ||||
10720 | buildPostUpdate(*this, ExprPostUpdates)); | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10721 | } |
10722 | |||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 10723 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, |
10724 | Expr *NumIterations, Sema &SemaRef, | ||||
10725 | Scope *S, DSAStackTy *Stack) { | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10726 | // Walk the vars and build update/final expressions for the CodeGen. |
10727 | SmallVector<Expr *, 8> Updates; | ||||
10728 | SmallVector<Expr *, 8> Finals; | ||||
10729 | Expr *Step = Clause.getStep(); | ||||
10730 | Expr *CalcStep = Clause.getCalcStep(); | ||||
10731 | // OpenMP [2.14.3.7, linear clause] | ||||
10732 | // If linear-step is not specified it is assumed to be 1. | ||||
10733 | if (Step == nullptr) | ||||
10734 | Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); | ||||
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 10735 | else if (CalcStep) { |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10736 | Step = cast<BinaryOperator>(CalcStep)->getLHS(); |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 10737 | } |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10738 | bool HasErrors = false; |
10739 | auto CurInit = Clause.inits().begin(); | ||||
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 10740 | auto CurPrivate = Clause.privates().begin(); |
Alexey Bataev | 84cfb1d | 2015-08-21 06:41:23 +0000 | [diff] [blame] | 10741 | auto LinKind = Clause.getModifier(); |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10742 | for (auto &RefExpr : Clause.varlists()) { |
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 10743 | SourceLocation ELoc; |
10744 | SourceRange ERange; | ||||
10745 | Expr *SimpleRefExpr = RefExpr; | ||||
10746 | auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, | ||||
10747 | /*AllowArraySection=*/false); | ||||
10748 | ValueDecl *D = Res.first; | ||||
10749 | if (Res.second || !D) { | ||||
10750 | Updates.push_back(nullptr); | ||||
10751 | Finals.push_back(nullptr); | ||||
10752 | HasErrors = true; | ||||
10753 | continue; | ||||
10754 | } | ||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 10755 | auto &&Info = Stack->isLoopControlVariable(D); |
Alexey Bataev | 2b86f21 | 2017-11-29 21:31:48 +0000 | [diff] [blame] | 10756 | // OpenMP [2.15.11, distribute simd Construct] |
10757 | // A list item may not appear in a linear clause, unless it is the loop | ||||
10758 | // iteration variable. | ||||
10759 | if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && | ||||
10760 | isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { | ||||
10761 | SemaRef.Diag(ELoc, | ||||
10762 | diag::err_omp_linear_distribute_var_non_loop_iteration); | ||||
10763 | Updates.push_back(nullptr); | ||||
10764 | Finals.push_back(nullptr); | ||||
10765 | HasErrors = true; | ||||
10766 | continue; | ||||
10767 | } | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10768 | Expr *InitExpr = *CurInit; |
10769 | |||||
10770 | // Build privatized reference to the current linear var. | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 10771 | auto *DE = cast<DeclRefExpr>(SimpleRefExpr); |
Alexey Bataev | 84cfb1d | 2015-08-21 06:41:23 +0000 | [diff] [blame] | 10772 | Expr *CapturedRef; |
10773 | if (LinKind == OMPC_LINEAR_uval) | ||||
10774 | CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); | ||||
10775 | else | ||||
10776 | CapturedRef = | ||||
10777 | buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), | ||||
10778 | DE->getType().getUnqualifiedType(), DE->getExprLoc(), | ||||
10779 | /*RefersToCapture=*/true); | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10780 | |
10781 | // Build update: Var = InitExpr + IV * Step | ||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 10782 | ExprResult Update; |
10783 | if (!Info.first) { | ||||
10784 | Update = | ||||
10785 | BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, | ||||
10786 | InitExpr, IV, Step, /* Subtract */ false); | ||||
10787 | } else | ||||
10788 | Update = *CurPrivate; | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 10789 | Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), |
10790 | /*DiscardedValue=*/true); | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10791 | |
10792 | // Build final: Var = InitExpr + NumIterations * Step | ||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 10793 | ExprResult Final; |
10794 | if (!Info.first) { | ||||
10795 | Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, | ||||
10796 | InitExpr, NumIterations, Step, | ||||
10797 | /* Subtract */ false); | ||||
10798 | } else | ||||
10799 | Final = *CurPrivate; | ||||
Alexey Bataev | 6b8046a | 2015-09-03 07:23:48 +0000 | [diff] [blame] | 10800 | Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), |
10801 | /*DiscardedValue=*/true); | ||||
Alexey Bataev | 5dff95c | 2016-04-22 03:56:56 +0000 | [diff] [blame] | 10802 | |
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10803 | if (!Update.isUsable() || !Final.isUsable()) { |
10804 | Updates.push_back(nullptr); | ||||
10805 | Finals.push_back(nullptr); | ||||
10806 | HasErrors = true; | ||||
10807 | } else { | ||||
10808 | Updates.push_back(Update.get()); | ||||
10809 | Finals.push_back(Final.get()); | ||||
10810 | } | ||||
Richard Trieu | cc3949d | 2016-02-18 22:34:54 +0000 | [diff] [blame] | 10811 | ++CurInit; |
10812 | ++CurPrivate; | ||||
Alexander Musman | 3276a27 | 2015-03-21 10:12:56 +0000 | [diff] [blame] | 10813 | } |
10814 | Clause.setUpdates(Updates); | ||||
10815 | Clause.setFinals(Finals); | ||||
10816 | return HasErrors; | ||||
Alexander Musman | 8dba664 | 2014-04-22 13:09:42 +0000 | [diff] [blame] | 10817 | } |
10818 | |||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10819 | OMPClause *Sema::ActOnOpenMPAlignedClause( |
10820 | ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, | ||||
10821 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { | ||||
10822 | |||||
10823 | SmallVector<Expr *, 8> Vars; | ||||
10824 | for (auto &RefExpr : VarList) { | ||||
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10825 | assert(RefExpr && "NULL expr in OpenMP linear clause."); |
10826 | SourceLocation ELoc; | ||||
10827 | SourceRange ERange; | ||||
10828 | Expr *SimpleRefExpr = RefExpr; | ||||
10829 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||
10830 | /*AllowArraySection=*/false); | ||||
10831 | if (Res.second) { | ||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10832 | // It will be analyzed later. |
10833 | Vars.push_back(RefExpr); | ||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10834 | } |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10835 | ValueDecl *D = Res.first; |
10836 | if (!D) | ||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10837 | continue; |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10838 | |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10839 | QualType QType = D->getType(); |
10840 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10841 | |
10842 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||
10843 | // The type of list items appearing in the aligned clause must be | ||||
10844 | // array, pointer, reference to array, or reference to pointer. | ||||
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 10845 | QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10846 | const Type *Ty = QType.getTypePtrOrNull(); |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10847 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10848 | Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10849 | << QType << getLangOpts().CPlusPlus << ERange; |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10850 | bool IsDecl = |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10851 | !VD || |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10852 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10853 | Diag(D->getLocation(), |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10854 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10855 | << D; |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10856 | continue; |
10857 | } | ||||
10858 | |||||
10859 | // OpenMP [2.8.1, simd construct, Restrictions] | ||||
10860 | // A list-item cannot appear in more than one aligned clause. | ||||
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10861 | if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { |
Alexey Bataev | d93d376 | 2016-04-12 09:35:56 +0000 | [diff] [blame] | 10862 | Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; |
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10863 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) |
10864 | << getOpenMPClauseName(OMPC_aligned); | ||||
10865 | continue; | ||||
10866 | } | ||||
10867 | |||||
Alexey Bataev | 1efd166 | 2016-03-29 10:59:56 +0000 | [diff] [blame] | 10868 | DeclRefExpr *Ref = nullptr; |
10869 | if (!VD && IsOpenMPCapturedDecl(D)) | ||||
10870 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||
10871 | Vars.push_back(DefaultFunctionArrayConversion( | ||||
10872 | (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) | ||||
10873 | .get()); | ||||
Alexander Musman | f0d76e7 | 2014-05-29 14:36:25 +0000 | [diff] [blame] | 10874 | } |
10875 | |||||
10876 | // OpenMP [2.8.1, simd construct, Description] | ||||
10877 | // The parameter of the aligned clause, alignment, must be a constant | ||||
10878 | // positive integer expression. | ||||
10879 | // If no optional parameter is specified, implementation-defined default | ||||
10880 | // alignments for SIMD instructions on the target platforms are assumed. | ||||
10881 | if (Alignment != nullptr) { | ||||
10882 | ExprResult AlignResult = | ||||
10883 | VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); | ||||
10884 | if (AlignResult.isInvalid()) | ||||
10885 | return nullptr; | ||||
10886 | Alignment = AlignResult.get(); | ||||
10887 | } | ||||
10888 | if (Vars.empty()) | ||||
10889 | return nullptr; | ||||
10890 | |||||
10891 | return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, | ||||
10892 | EndLoc, Vars, Alignment); | ||||
10893 | } | ||||
10894 | |||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10895 | OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, |
10896 | SourceLocation StartLoc, | ||||
10897 | SourceLocation LParenLoc, | ||||
10898 | SourceLocation EndLoc) { | ||||
10899 | SmallVector<Expr *, 8> Vars; | ||||
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 10900 | SmallVector<Expr *, 8> SrcExprs; |
10901 | SmallVector<Expr *, 8> DstExprs; | ||||
10902 | SmallVector<Expr *, 8> AssignmentOps; | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10903 | for (auto &RefExpr : VarList) { |
10904 | assert(RefExpr && "NULL expr in OpenMP copyin clause."); | ||||
10905 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10906 | // It will be analyzed later. |
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10907 | Vars.push_back(RefExpr); |
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 10908 | SrcExprs.push_back(nullptr); |
10909 | DstExprs.push_back(nullptr); | ||||
10910 | AssignmentOps.push_back(nullptr); | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10911 | continue; |
10912 | } | ||||
10913 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10914 | SourceLocation ELoc = RefExpr->getExprLoc(); |
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10915 | // OpenMP [2.1, C/C++] |
10916 | // A list item is a variable name. | ||||
10917 | // OpenMP [2.14.4.1, Restrictions, p.1] | ||||
10918 | // A list item that appears in a copyin clause must be threadprivate. | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10919 | DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); |
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10920 | if (!DE || !isa<VarDecl>(DE->getDecl())) { |
Alexey Bataev | 48c0bfb | 2016-01-20 09:07:54 +0000 | [diff] [blame] | 10921 | Diag(ELoc, diag::err_omp_expected_var_name_member_expr) |
10922 | << 0 << RefExpr->getSourceRange(); | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10923 | continue; |
10924 | } | ||||
10925 | |||||
10926 | Decl *D = DE->getDecl(); | ||||
10927 | VarDecl *VD = cast<VarDecl>(D); | ||||
10928 | |||||
10929 | QualType Type = VD->getType(); | ||||
10930 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | ||||
10931 | // It will be analyzed later. | ||||
10932 | Vars.push_back(DE); | ||||
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 10933 | SrcExprs.push_back(nullptr); |
10934 | DstExprs.push_back(nullptr); | ||||
10935 | AssignmentOps.push_back(nullptr); | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10936 | continue; |
10937 | } | ||||
10938 | |||||
10939 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] | ||||
10940 | // A list item that appears in a copyin clause must be threadprivate. | ||||
10941 | if (!DSAStack->isThreadPrivate(VD)) { | ||||
10942 | Diag(ELoc, diag::err_omp_required_access) | ||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10943 | << getOpenMPClauseName(OMPC_copyin) |
10944 | << getOpenMPDirectiveName(OMPD_threadprivate); | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10945 | continue; |
10946 | } | ||||
10947 | |||||
10948 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] | ||||
10949 | // A variable of class type (or array thereof) that appears in a | ||||
Alexey Bataev | 23b6942 | 2014-06-18 07:08:49 +0000 | [diff] [blame] | 10950 | // copyin clause requires an accessible, unambiguous copy assignment |
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10951 | // operator for the class type. |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 10952 | auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); |
Alexey Bataev | 1d7f0fa | 2015-09-10 09:48:30 +0000 | [diff] [blame] | 10953 | auto *SrcVD = |
10954 | buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), | ||||
10955 | ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); | ||||
Alexey Bataev | 39f915b8 | 2015-05-08 10:41:21 +0000 | [diff] [blame] | 10956 | auto *PseudoSrcExpr = buildDeclRefExpr( |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 10957 | *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); |
10958 | auto *DstVD = | ||||
Alexey Bataev | 1d7f0fa | 2015-09-10 09:48:30 +0000 | [diff] [blame] | 10959 | buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", |
10960 | VD->hasAttrs() ? &VD->getAttrs() : nullptr); | ||||
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 10961 | auto *PseudoDstExpr = |
Alexey Bataev | f120c0d | 2015-05-19 07:46:42 +0000 | [diff] [blame] | 10962 | buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); |
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 10963 | // For arrays generate assignment operation for single element and replace |
10964 | // it by the original array element in CodeGen. | ||||
10965 | auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, | ||||
10966 | PseudoDstExpr, PseudoSrcExpr); | ||||
10967 | if (AssignmentOp.isInvalid()) | ||||
10968 | continue; | ||||
10969 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), | ||||
10970 | /*DiscardedValue=*/true); | ||||
10971 | if (AssignmentOp.isInvalid()) | ||||
10972 | continue; | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10973 | |
10974 | DSAStack->addDSA(VD, DE, OMPC_copyin); | ||||
10975 | Vars.push_back(DE); | ||||
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 10976 | SrcExprs.push_back(PseudoSrcExpr); |
10977 | DstExprs.push_back(PseudoDstExpr); | ||||
10978 | AssignmentOps.push_back(AssignmentOp.get()); | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10979 | } |
10980 | |||||
Alexey Bataev | ed09d24 | 2014-05-28 05:53:51 +0000 | [diff] [blame] | 10981 | if (Vars.empty()) |
10982 | return nullptr; | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10983 | |
Alexey Bataev | f56f98c | 2015-04-16 05:39:01 +0000 | [diff] [blame] | 10984 | return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, |
10985 | SrcExprs, DstExprs, AssignmentOps); | ||||
Alexey Bataev | d48bcd8 | 2014-03-31 03:36:38 +0000 | [diff] [blame] | 10986 | } |
10987 | |||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 10988 | OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, |
10989 | SourceLocation StartLoc, | ||||
10990 | SourceLocation LParenLoc, | ||||
10991 | SourceLocation EndLoc) { | ||||
10992 | SmallVector<Expr *, 8> Vars; | ||||
Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 10993 | SmallVector<Expr *, 8> SrcExprs; |
10994 | SmallVector<Expr *, 8> DstExprs; | ||||
10995 | SmallVector<Expr *, 8> AssignmentOps; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 10996 | for (auto &RefExpr : VarList) { |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 10997 | assert(RefExpr && "NULL expr in OpenMP linear clause."); |
10998 | SourceLocation ELoc; | ||||
10999 | SourceRange ERange; | ||||
11000 | Expr *SimpleRefExpr = RefExpr; | ||||
11001 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, | ||||
11002 | /*AllowArraySection=*/false); | ||||
11003 | if (Res.second) { | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11004 | // It will be analyzed later. |
11005 | Vars.push_back(RefExpr); | ||||
Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 11006 | SrcExprs.push_back(nullptr); |
11007 | DstExprs.push_back(nullptr); | ||||
11008 | AssignmentOps.push_back(nullptr); | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11009 | } |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11010 | ValueDecl *D = Res.first; |
11011 | if (!D) | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11012 | continue; |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11013 | |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11014 | QualType Type = D->getType(); |
11015 | auto *VD = dyn_cast<VarDecl>(D); | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11016 | |
11017 | // OpenMP [2.14.4.2, Restrictions, p.2] | ||||
11018 | // A list item that appears in a copyprivate clause may not appear in a | ||||
11019 | // private or firstprivate clause on the single construct. | ||||
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11020 | if (!VD || !DSAStack->isThreadPrivate(VD)) { |
11021 | auto DVar = DSAStack->getTopDSA(D, false); | ||||
Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 11022 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && |
11023 | DVar.RefExpr) { | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11024 | Diag(ELoc, diag::err_omp_wrong_dsa) |
11025 | << getOpenMPClauseName(DVar.CKind) | ||||
11026 | << getOpenMPClauseName(OMPC_copyprivate); | ||||
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11027 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11028 | continue; |
11029 | } | ||||
11030 | |||||
11031 | // OpenMP [2.11.4.2, Restrictions, p.1] | ||||
11032 | // All list items that appear in a copyprivate clause must be either | ||||
11033 | // threadprivate or private in the enclosing context. | ||||
11034 | if (DVar.CKind == OMPC_unknown) { | ||||
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11035 | DVar = DSAStack->getImplicitDSA(D, false); |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11036 | if (DVar.CKind == OMPC_shared) { |
11037 | Diag(ELoc, diag::err_omp_required_access) | ||||
11038 | << getOpenMPClauseName(OMPC_copyprivate) | ||||
11039 | << "threadprivate or private in the enclosing context"; | ||||
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11040 | ReportOriginalDSA(*this, DSAStack, D, DVar); |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11041 | continue; |
11042 | } | ||||
11043 | } | ||||
11044 | } | ||||
11045 | |||||
Alexey Bataev | 7a3e585 | 2015-05-19 08:19:24 +0000 | [diff] [blame] | 11046 | // Variably modified types are not supported. |
Alexey Bataev | 5129d3a | 2015-05-21 09:47:46 +0000 | [diff] [blame] | 11047 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { |
Alexey Bataev | 7a3e585 | 2015-05-19 08:19:24 +0000 | [diff] [blame] | 11048 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) |
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 11049 | << getOpenMPClauseName(OMPC_copyprivate) << Type |
11050 | << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); | ||||
Alexey Bataev | 7a3e585 | 2015-05-19 08:19:24 +0000 | [diff] [blame] | 11051 | bool IsDecl = |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11052 | !VD || |
Alexey Bataev | 7a3e585 | 2015-05-19 08:19:24 +0000 | [diff] [blame] | 11053 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11054 | Diag(D->getLocation(), |
Alexey Bataev | 7a3e585 | 2015-05-19 08:19:24 +0000 | [diff] [blame] | 11055 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11056 | << D; |
Alexey Bataev | 7a3e585 | 2015-05-19 08:19:24 +0000 | [diff] [blame] | 11057 | continue; |
11058 | } | ||||
Alexey Bataev | ccb59ec | 2015-05-19 08:44:56 +0000 | [diff] [blame] | 11059 | |
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11060 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] |
11061 | // A variable of class type (or array thereof) that appears in a | ||||
11062 | // copyin clause requires an accessible, unambiguous copy assignment | ||||
11063 | // operator for the class type. | ||||
Alexey Bataev | bd9fec1 | 2015-08-18 06:47:21 +0000 | [diff] [blame] | 11064 | Type = Context.getBaseElementType(Type.getNonReferenceType()) |
11065 | .getUnqualifiedType(); | ||||
Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 11066 | auto *SrcVD = |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11067 | buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", |
11068 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||
11069 | auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); | ||||
Alexey Bataev | 420d45b | 2015-04-14 05:11:24 +0000 | [diff] [blame] | 11070 | auto *DstVD = |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11071 | buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", |
11072 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 11073 | auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); |
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11074 | auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, |
Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 11075 | PseudoDstExpr, PseudoSrcExpr); |
11076 | if (AssignmentOp.isInvalid()) | ||||
11077 | continue; | ||||
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11078 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, |
Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 11079 | /*DiscardedValue=*/true); |
11080 | if (AssignmentOp.isInvalid()) | ||||
11081 | continue; | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11082 | |
11083 | // No need to mark vars as copyprivate, they are already threadprivate or | ||||
11084 | // implicitly private. | ||||
Alexey Bataev | e122da1 | 2016-03-17 10:50:17 +0000 | [diff] [blame] | 11085 | assert(VD || IsOpenMPCapturedDecl(D)); |
11086 | Vars.push_back( | ||||
11087 | VD ? RefExpr->IgnoreParens() | ||||
11088 | : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); | ||||
Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 11089 | SrcExprs.push_back(PseudoSrcExpr); |
11090 | DstExprs.push_back(PseudoDstExpr); | ||||
11091 | AssignmentOps.push_back(AssignmentOp.get()); | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11092 | } |
11093 | |||||
11094 | if (Vars.empty()) | ||||
11095 | return nullptr; | ||||
11096 | |||||
Alexey Bataev | a63048e | 2015-03-23 06:18:07 +0000 | [diff] [blame] | 11097 | return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
11098 | Vars, SrcExprs, DstExprs, AssignmentOps); | ||||
Alexey Bataev | bae9a79 | 2014-06-27 10:37:06 +0000 | [diff] [blame] | 11099 | } |
11100 | |||||
Alexey Bataev | 6125da9 | 2014-07-21 11:26:11 +0000 | [diff] [blame] | 11101 | OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, |
11102 | SourceLocation StartLoc, | ||||
11103 | SourceLocation LParenLoc, | ||||
11104 | SourceLocation EndLoc) { | ||||
11105 | if (VarList.empty()) | ||||
11106 | return nullptr; | ||||
11107 | |||||
11108 | return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); | ||||
11109 | } | ||||
Alexey Bataev | dea4761 | 2014-07-23 07:46:59 +0000 | [diff] [blame] | 11110 | |
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 11111 | OMPClause * |
11112 | Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, | ||||
11113 | SourceLocation DepLoc, SourceLocation ColonLoc, | ||||
11114 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, | ||||
11115 | SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 11116 | if (DSAStack->getCurrentDirective() == OMPD_ordered && |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11117 | DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { |
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 11118 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 11119 | << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); |
Alexey Bataev | eb48235 | 2015-12-18 05:05:56 +0000 | [diff] [blame] | 11120 | return nullptr; |
11121 | } | ||||
11122 | if (DSAStack->getCurrentDirective() != OMPD_ordered && | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11123 | (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || |
11124 | DepKind == OMPC_DEPEND_sink)) { | ||||
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 11125 | unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; |
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 11126 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) |
Alexey Bataev | 6402bca | 2015-12-28 07:25:51 +0000 | [diff] [blame] | 11127 | << getListOfPossibleValues(OMPC_depend, /*First=*/0, |
11128 | /*Last=*/OMPC_DEPEND_unknown, Except) | ||||
11129 | << getOpenMPClauseName(OMPC_depend); | ||||
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 11130 | return nullptr; |
11131 | } | ||||
11132 | SmallVector<Expr *, 8> Vars; | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 11133 | DSAStackTy::OperatorOffsetTy OpsOffs; |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11134 | llvm::APSInt DepCounter(/*BitWidth=*/32); |
11135 | llvm::APSInt TotalDepCount(/*BitWidth=*/32); | ||||
11136 | if (DepKind == OMPC_DEPEND_sink) { | ||||
11137 | if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { | ||||
11138 | TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); | ||||
11139 | TotalDepCount.setIsUnsigned(/*Val=*/true); | ||||
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 11140 | } |
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 11141 | } |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11142 | if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || |
11143 | DSAStack->getParentOrderedRegionParam()) { | ||||
11144 | for (auto &RefExpr : VarList) { | ||||
11145 | assert(RefExpr && "NULL expr in OpenMP shared clause."); | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 11146 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11147 | // It will be analyzed later. |
11148 | Vars.push_back(RefExpr); | ||||
11149 | continue; | ||||
11150 | } | ||||
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 11151 | |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11152 | SourceLocation ELoc = RefExpr->getExprLoc(); |
11153 | auto *SimpleExpr = RefExpr->IgnoreParenCasts(); | ||||
11154 | if (DepKind == OMPC_DEPEND_sink) { | ||||
11155 | if (DepCounter >= TotalDepCount) { | ||||
11156 | Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); | ||||
11157 | continue; | ||||
11158 | } | ||||
11159 | ++DepCounter; | ||||
11160 | // OpenMP [2.13.9, Summary] | ||||
11161 | // depend(dependence-type : vec), where dependence-type is: | ||||
11162 | // 'sink' and where vec is the iteration vector, which has the form: | ||||
11163 | // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] | ||||
11164 | // where n is the value specified by the ordered clause in the loop | ||||
11165 | // directive, xi denotes the loop iteration variable of the i-th nested | ||||
11166 | // loop associated with the loop directive, and di is a constant | ||||
11167 | // non-negative integer. | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 11168 | if (CurContext->isDependentContext()) { |
11169 | // It will be analyzed later. | ||||
11170 | Vars.push_back(RefExpr); | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11171 | continue; |
11172 | } | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 11173 | SimpleExpr = SimpleExpr->IgnoreImplicit(); |
11174 | OverloadedOperatorKind OOK = OO_None; | ||||
11175 | SourceLocation OOLoc; | ||||
11176 | Expr *LHS = SimpleExpr; | ||||
11177 | Expr *RHS = nullptr; | ||||
11178 | if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { | ||||
11179 | OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); | ||||
11180 | OOLoc = BO->getOperatorLoc(); | ||||
11181 | LHS = BO->getLHS()->IgnoreParenImpCasts(); | ||||
11182 | RHS = BO->getRHS()->IgnoreParenImpCasts(); | ||||
11183 | } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { | ||||
11184 | OOK = OCE->getOperator(); | ||||
11185 | OOLoc = OCE->getOperatorLoc(); | ||||
11186 | LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); | ||||
11187 | RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); | ||||
11188 | } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { | ||||
11189 | OOK = MCE->getMethodDecl() | ||||
11190 | ->getNameInfo() | ||||
11191 | .getName() | ||||
11192 | .getCXXOverloadedOperator(); | ||||
11193 | OOLoc = MCE->getCallee()->getExprLoc(); | ||||
11194 | LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); | ||||
11195 | RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); | ||||
11196 | } | ||||
11197 | SourceLocation ELoc; | ||||
11198 | SourceRange ERange; | ||||
11199 | auto Res = getPrivateItem(*this, LHS, ELoc, ERange, | ||||
11200 | /*AllowArraySection=*/false); | ||||
11201 | if (Res.second) { | ||||
11202 | // It will be analyzed later. | ||||
11203 | Vars.push_back(RefExpr); | ||||
11204 | } | ||||
11205 | ValueDecl *D = Res.first; | ||||
11206 | if (!D) | ||||
11207 | continue; | ||||
11208 | |||||
11209 | if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { | ||||
11210 | Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); | ||||
11211 | continue; | ||||
11212 | } | ||||
11213 | if (RHS) { | ||||
11214 | ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( | ||||
11215 | RHS, OMPC_depend, /*StrictlyPositive=*/false); | ||||
11216 | if (RHSRes.isInvalid()) | ||||
11217 | continue; | ||||
11218 | } | ||||
11219 | if (!CurContext->isDependentContext() && | ||||
11220 | DSAStack->getParentOrderedRegionParam() && | ||||
11221 | DepCounter != DSAStack->isParentLoopControlVariable(D).first) { | ||||
Rachel Craik | 1cf49e4 | 2017-09-19 21:04:23 +0000 | [diff] [blame] | 11222 | ValueDecl* VD = DSAStack->getParentLoopControlVariable( |
11223 | DepCounter.getZExtValue()); | ||||
11224 | if (VD) { | ||||
11225 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) | ||||
11226 | << 1 << VD; | ||||
11227 | } else { | ||||
11228 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; | ||||
11229 | } | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 11230 | continue; |
11231 | } | ||||
11232 | OpsOffs.push_back({RHS, OOK}); | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11233 | } else { |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11234 | auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); |
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11235 | if (!RefExpr->IgnoreParenImpCasts()->isLValue() || |
Alexey Bataev | 31300ed | 2016-02-04 11:27:03 +0000 | [diff] [blame] | 11236 | (ASE && |
11237 | !ASE->getBase() | ||||
11238 | ->getType() | ||||
11239 | .getNonReferenceType() | ||||
11240 | ->isPointerType() && | ||||
11241 | !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { | ||||
Alexey Bataev | 463a9fe | 2017-07-27 19:15:30 +0000 | [diff] [blame] | 11242 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) |
11243 | << RefExpr->getSourceRange(); | ||||
11244 | continue; | ||||
11245 | } | ||||
11246 | bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); | ||||
11247 | getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); | ||||
Alexey Bataev | d070a58 | 2017-10-25 15:54:04 +0000 | [diff] [blame] | 11248 | ExprResult Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, |
Alexey Bataev | 463a9fe | 2017-07-27 19:15:30 +0000 | [diff] [blame] | 11249 | RefExpr->IgnoreParenImpCasts()); |
11250 | getDiagnostics().setSuppressAllDiagnostics(Suppress); | ||||
11251 | if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { | ||||
11252 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) | ||||
11253 | << RefExpr->getSourceRange(); | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11254 | continue; |
11255 | } | ||||
11256 | } | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11257 | Vars.push_back(RefExpr->IgnoreParenImpCasts()); |
11258 | } | ||||
11259 | |||||
11260 | if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && | ||||
11261 | TotalDepCount > VarList.size() && | ||||
Rachel Craik | 1cf49e4 | 2017-09-19 21:04:23 +0000 | [diff] [blame] | 11262 | DSAStack->getParentOrderedRegionParam() && |
11263 | DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { | ||||
11264 | Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1 | ||||
Alexey Bataev | a636c7f | 2015-12-23 10:27:45 +0000 | [diff] [blame] | 11265 | << DSAStack->getParentLoopControlVariable(VarList.size() + 1); |
11266 | } | ||||
11267 | if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && | ||||
11268 | Vars.empty()) | ||||
11269 | return nullptr; | ||||
11270 | } | ||||
Alexey Bataev | 8b42706 | 2016-05-25 12:36:08 +0000 | [diff] [blame] | 11271 | auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
11272 | DepKind, DepLoc, ColonLoc, Vars); | ||||
11273 | if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) | ||||
11274 | DSAStack->addDoacrossDependClause(C, OpsOffs); | ||||
11275 | return C; | ||||
Alexey Bataev | 1c2cfbc | 2015-06-23 14:25:19 +0000 | [diff] [blame] | 11276 | } |
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 11277 | |
11278 | OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, | ||||
11279 | SourceLocation LParenLoc, | ||||
11280 | SourceLocation EndLoc) { | ||||
11281 | Expr *ValExpr = Device; | ||||
Alexey Bataev | 931e19b | 2017-10-02 16:32:39 +0000 | [diff] [blame] | 11282 | Stmt *HelperValStmt = nullptr; |
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 11283 | |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 11284 | // OpenMP [2.9.1, Restrictions] |
11285 | // The device expression must evaluate to a non-negative integer value. | ||||
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 11286 | if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, |
11287 | /*StrictlyPositive=*/false)) | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 11288 | return nullptr; |
11289 | |||||
Alexey Bataev | 931e19b | 2017-10-02 16:32:39 +0000 | [diff] [blame] | 11290 | OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 11291 | OpenMPDirectiveKind CaptureRegion = |
11292 | getOpenMPCaptureRegionForClause(DKind, OMPC_device); | ||||
11293 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||
Alexey Bataev | 931e19b | 2017-10-02 16:32:39 +0000 | [diff] [blame] | 11294 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
11295 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||
11296 | HelperValStmt = buildPreInits(Context, Captures); | ||||
11297 | } | ||||
11298 | |||||
11299 | return new (Context) | ||||
11300 | OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc); | ||||
Michael Wong | e710d54 | 2015-08-07 16:16:36 +0000 | [diff] [blame] | 11301 | } |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11302 | |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11303 | static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, |
11304 | DSAStackTy *Stack, QualType QTy) { | ||||
11305 | NamedDecl *ND; | ||||
11306 | if (QTy->isIncompleteType(&ND)) { | ||||
11307 | SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; | ||||
11308 | return false; | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11309 | } |
11310 | return true; | ||||
11311 | } | ||||
11312 | |||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11313 | /// \brief Return true if it can be proven that the provided array expression |
11314 | /// (array section or array subscript) does NOT specify the whole size of the | ||||
11315 | /// array whose base type is \a BaseQTy. | ||||
11316 | static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, | ||||
11317 | const Expr *E, | ||||
11318 | QualType BaseQTy) { | ||||
11319 | auto *OASE = dyn_cast<OMPArraySectionExpr>(E); | ||||
11320 | |||||
11321 | // If this is an array subscript, it refers to the whole size if the size of | ||||
11322 | // the dimension is constant and equals 1. Also, an array section assumes the | ||||
11323 | // format of an array subscript if no colon is used. | ||||
11324 | if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { | ||||
11325 | if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) | ||||
11326 | return ATy->getSize().getSExtValue() != 1; | ||||
11327 | // Size can't be evaluated statically. | ||||
11328 | return false; | ||||
11329 | } | ||||
11330 | |||||
11331 | assert(OASE && "Expecting array section if not an array subscript."); | ||||
11332 | auto *LowerBound = OASE->getLowerBound(); | ||||
11333 | auto *Length = OASE->getLength(); | ||||
11334 | |||||
11335 | // If there is a lower bound that does not evaluates to zero, we are not | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 11336 | // covering the whole dimension. |
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11337 | if (LowerBound) { |
11338 | llvm::APSInt ConstLowerBound; | ||||
11339 | if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) | ||||
11340 | return false; // Can't get the integer value as a constant. | ||||
11341 | if (ConstLowerBound.getSExtValue()) | ||||
11342 | return true; | ||||
11343 | } | ||||
11344 | |||||
11345 | // If we don't have a length we covering the whole dimension. | ||||
11346 | if (!Length) | ||||
11347 | return false; | ||||
11348 | |||||
11349 | // If the base is a pointer, we don't have a way to get the size of the | ||||
11350 | // pointee. | ||||
11351 | if (BaseQTy->isPointerType()) | ||||
11352 | return false; | ||||
11353 | |||||
11354 | // We can only check if the length is the same as the size of the dimension | ||||
11355 | // if we have a constant array. | ||||
11356 | auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); | ||||
11357 | if (!CATy) | ||||
11358 | return false; | ||||
11359 | |||||
11360 | llvm::APSInt ConstLength; | ||||
11361 | if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) | ||||
11362 | return false; // Can't get the integer value as a constant. | ||||
11363 | |||||
11364 | return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); | ||||
11365 | } | ||||
11366 | |||||
11367 | // Return true if it can be proven that the provided array expression (array | ||||
11368 | // section or array subscript) does NOT specify a single element of the array | ||||
11369 | // whose base type is \a BaseQTy. | ||||
11370 | static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 11371 | const Expr *E, |
11372 | QualType BaseQTy) { | ||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11373 | auto *OASE = dyn_cast<OMPArraySectionExpr>(E); |
11374 | |||||
11375 | // An array subscript always refer to a single element. Also, an array section | ||||
11376 | // assumes the format of an array subscript if no colon is used. | ||||
11377 | if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) | ||||
11378 | return false; | ||||
11379 | |||||
11380 | assert(OASE && "Expecting array section if not an array subscript."); | ||||
11381 | auto *Length = OASE->getLength(); | ||||
11382 | |||||
11383 | // If we don't have a length we have to check if the array has unitary size | ||||
11384 | // for this dimension. Also, we should always expect a length if the base type | ||||
11385 | // is pointer. | ||||
11386 | if (!Length) { | ||||
11387 | if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) | ||||
11388 | return ATy->getSize().getSExtValue() != 1; | ||||
11389 | // We cannot assume anything. | ||||
11390 | return false; | ||||
11391 | } | ||||
11392 | |||||
11393 | // Check if the length evaluates to 1. | ||||
11394 | llvm::APSInt ConstLength; | ||||
11395 | if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) | ||||
11396 | return false; // Can't get the integer value as a constant. | ||||
11397 | |||||
11398 | return ConstLength.getSExtValue() != 1; | ||||
11399 | } | ||||
11400 | |||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11401 | // Return the expression of the base of the mappable expression or null if it |
11402 | // cannot be determined and do all the necessary checks to see if the expression | ||||
11403 | // is valid as a standalone mappable expression. In the process, record all the | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11404 | // components of the expression. |
11405 | static Expr *CheckMapClauseExpressionBase( | ||||
11406 | Sema &SemaRef, Expr *E, | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11407 | OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, |
11408 | OpenMPClauseKind CKind) { | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11409 | SourceLocation ELoc = E->getExprLoc(); |
11410 | SourceRange ERange = E->getSourceRange(); | ||||
11411 | |||||
11412 | // The base of elements of list in a map clause have to be either: | ||||
11413 | // - a reference to variable or field. | ||||
11414 | // - a member expression. | ||||
11415 | // - an array expression. | ||||
11416 | // | ||||
11417 | // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the | ||||
11418 | // reference to 'r'. | ||||
11419 | // | ||||
11420 | // If we have: | ||||
11421 | // | ||||
11422 | // struct SS { | ||||
11423 | // Bla S; | ||||
11424 | // foo() { | ||||
11425 | // #pragma omp target map (S.Arr[:12]); | ||||
11426 | // } | ||||
11427 | // } | ||||
11428 | // | ||||
11429 | // We want to retrieve the member expression 'this->S'; | ||||
11430 | |||||
11431 | Expr *RelevantExpr = nullptr; | ||||
11432 | |||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11433 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] |
11434 | // If a list item is an array section, it must specify contiguous storage. | ||||
11435 | // | ||||
11436 | // For this restriction it is sufficient that we make sure only references | ||||
11437 | // to variables or fields and array expressions, and that no array sections | ||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11438 | // exist except in the rightmost expression (unless they cover the whole |
11439 | // dimension of the array). E.g. these would be invalid: | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11440 | // |
11441 | // r.ArrS[3:5].Arr[6:7] | ||||
11442 | // | ||||
11443 | // r.ArrS[3:5].x | ||||
11444 | // | ||||
11445 | // but these would be valid: | ||||
11446 | // r.ArrS[3].Arr[6:7] | ||||
11447 | // | ||||
11448 | // r.ArrS[3].x | ||||
11449 | |||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11450 | bool AllowUnitySizeArraySection = true; |
11451 | bool AllowWholeSizeArraySection = true; | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11452 | |
Dmitry Polukhin | 644a925 | 2016-03-11 07:58:34 +0000 | [diff] [blame] | 11453 | while (!RelevantExpr) { |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11454 | E = E->IgnoreParenImpCasts(); |
11455 | |||||
11456 | if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { | ||||
11457 | if (!isa<VarDecl>(CurE->getDecl())) | ||||
11458 | break; | ||||
11459 | |||||
11460 | RelevantExpr = CurE; | ||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11461 | |
11462 | // If we got a reference to a declaration, we should not expect any array | ||||
11463 | // section before that. | ||||
11464 | AllowUnitySizeArraySection = false; | ||||
11465 | AllowWholeSizeArraySection = false; | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11466 | |
11467 | // Record the component. | ||||
11468 | CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( | ||||
11469 | CurE, CurE->getDecl())); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11470 | continue; |
11471 | } | ||||
11472 | |||||
11473 | if (auto *CurE = dyn_cast<MemberExpr>(E)) { | ||||
11474 | auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); | ||||
11475 | |||||
11476 | if (isa<CXXThisExpr>(BaseE)) | ||||
11477 | // We found a base expression: this->Val. | ||||
11478 | RelevantExpr = CurE; | ||||
11479 | else | ||||
11480 | E = BaseE; | ||||
11481 | |||||
11482 | if (!isa<FieldDecl>(CurE->getMemberDecl())) { | ||||
11483 | SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) | ||||
11484 | << CurE->getSourceRange(); | ||||
11485 | break; | ||||
11486 | } | ||||
11487 | |||||
11488 | auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); | ||||
11489 | |||||
11490 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] | ||||
11491 | // A bit-field cannot appear in a map clause. | ||||
11492 | // | ||||
11493 | if (FD->isBitField()) { | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11494 | SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) |
11495 | << CurE->getSourceRange() << getOpenMPClauseName(CKind); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11496 | break; |
11497 | } | ||||
11498 | |||||
11499 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||
11500 | // If the type of a list item is a reference to a type T then the type | ||||
11501 | // will be considered to be T for all purposes of this clause. | ||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11502 | QualType CurType = BaseE->getType().getNonReferenceType(); |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11503 | |
11504 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] | ||||
11505 | // A list item cannot be a variable that is a member of a structure with | ||||
11506 | // a union type. | ||||
11507 | // | ||||
11508 | if (auto *RT = CurType->getAs<RecordType>()) | ||||
11509 | if (RT->isUnionType()) { | ||||
11510 | SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) | ||||
11511 | << CurE->getSourceRange(); | ||||
11512 | break; | ||||
11513 | } | ||||
11514 | |||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11515 | // If we got a member expression, we should not expect any array section |
11516 | // before that: | ||||
11517 | // | ||||
11518 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] | ||||
11519 | // If a list item is an element of a structure, only the rightmost symbol | ||||
11520 | // of the variable reference can be an array section. | ||||
11521 | // | ||||
11522 | AllowUnitySizeArraySection = false; | ||||
11523 | AllowWholeSizeArraySection = false; | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11524 | |
11525 | // Record the component. | ||||
11526 | CurComponents.push_back( | ||||
11527 | OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11528 | continue; |
11529 | } | ||||
11530 | |||||
11531 | if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { | ||||
11532 | E = CurE->getBase()->IgnoreParenImpCasts(); | ||||
11533 | |||||
11534 | if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { | ||||
11535 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) | ||||
11536 | << 0 << CurE->getSourceRange(); | ||||
11537 | break; | ||||
11538 | } | ||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11539 | |
11540 | // If we got an array subscript that express the whole dimension we | ||||
11541 | // can have any array expressions before. If it only expressing part of | ||||
11542 | // the dimension, we can only have unitary-size array expressions. | ||||
11543 | if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, | ||||
11544 | E->getType())) | ||||
11545 | AllowWholeSizeArraySection = false; | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11546 | |
11547 | // Record the component - we don't have any declaration associated. | ||||
11548 | CurComponents.push_back( | ||||
11549 | OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11550 | continue; |
11551 | } | ||||
11552 | |||||
11553 | if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11554 | E = CurE->getBase()->IgnoreParenImpCasts(); |
11555 | |||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11556 | auto CurType = |
11557 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); | ||||
11558 | |||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11559 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] |
11560 | // If the type of a list item is a reference to a type T then the type | ||||
11561 | // will be considered to be T for all purposes of this clause. | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11562 | if (CurType->isReferenceType()) |
11563 | CurType = CurType->getPointeeType(); | ||||
11564 | |||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11565 | bool IsPointer = CurType->isAnyPointerType(); |
11566 | |||||
11567 | if (!IsPointer && !CurType->isArrayType()) { | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11568 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) |
11569 | << 0 << CurE->getSourceRange(); | ||||
11570 | break; | ||||
11571 | } | ||||
11572 | |||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11573 | bool NotWhole = |
11574 | CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); | ||||
11575 | bool NotUnity = | ||||
11576 | CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); | ||||
11577 | |||||
Samuel Antao | dab51bb | 2016-07-18 23:22:11 +0000 | [diff] [blame] | 11578 | if (AllowWholeSizeArraySection) { |
11579 | // Any array section is currently allowed. Allowing a whole size array | ||||
11580 | // section implies allowing a unity array section as well. | ||||
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11581 | // |
11582 | // If this array section refers to the whole dimension we can still | ||||
11583 | // accept other array sections before this one, except if the base is a | ||||
11584 | // pointer. Otherwise, only unitary sections are accepted. | ||||
11585 | if (NotWhole || IsPointer) | ||||
11586 | AllowWholeSizeArraySection = false; | ||||
Samuel Antao | dab51bb | 2016-07-18 23:22:11 +0000 | [diff] [blame] | 11587 | } else if (AllowUnitySizeArraySection && NotUnity) { |
Samuel Antao | a9f35cb | 2016-03-09 15:46:05 +0000 | [diff] [blame] | 11588 | // A unity or whole array section is not allowed and that is not |
11589 | // compatible with the properties of the current array section. | ||||
11590 | SemaRef.Diag( | ||||
11591 | ELoc, diag::err_array_section_does_not_specify_contiguous_storage) | ||||
11592 | << CurE->getSourceRange(); | ||||
11593 | break; | ||||
11594 | } | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11595 | |
11596 | // Record the component - we don't have any declaration associated. | ||||
11597 | CurComponents.push_back( | ||||
11598 | OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11599 | continue; |
11600 | } | ||||
11601 | |||||
11602 | // If nothing else worked, this is not a valid map clause expression. | ||||
11603 | SemaRef.Diag(ELoc, | ||||
11604 | diag::err_omp_expected_named_var_member_or_array_expression) | ||||
11605 | << ERange; | ||||
11606 | break; | ||||
11607 | } | ||||
11608 | |||||
11609 | return RelevantExpr; | ||||
11610 | } | ||||
11611 | |||||
11612 | // Return true if expression E associated with value VD has conflicts with other | ||||
11613 | // map information. | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11614 | static bool CheckMapConflicts( |
11615 | Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, | ||||
11616 | bool CurrentRegionOnly, | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11617 | OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, |
11618 | OpenMPClauseKind CKind) { | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11619 | assert(VD && E); |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11620 | SourceLocation ELoc = E->getExprLoc(); |
11621 | SourceRange ERange = E->getSourceRange(); | ||||
11622 | |||||
11623 | // In order to easily check the conflicts we need to match each component of | ||||
11624 | // the expression under test with the components of the expressions that are | ||||
11625 | // already in the stack. | ||||
11626 | |||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11627 | assert(!CurComponents.empty() && "Map clause expression with no components!"); |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11628 | assert(CurComponents.back().getAssociatedDeclaration() == VD && |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11629 | "Map clause expression with unexpected base!"); |
11630 | |||||
11631 | // Variables to help detecting enclosing problems in data environment nests. | ||||
11632 | bool IsEnclosedByDataEnvironmentExpr = false; | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11633 | const Expr *EnclosingExpr = nullptr; |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11634 | |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11635 | bool FoundError = DSAS->checkMappableExprComponentListsForDecl( |
11636 | VD, CurrentRegionOnly, | ||||
11637 | [&](OMPClauseMappableExprCommon::MappableExprComponentListRef | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 11638 | StackComponents, |
11639 | OpenMPClauseKind) -> bool { | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11640 | |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11641 | assert(!StackComponents.empty() && |
11642 | "Map clause expression with no components!"); | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11643 | assert(StackComponents.back().getAssociatedDeclaration() == VD && |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11644 | "Map clause expression with unexpected base!"); |
11645 | |||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11646 | // The whole expression in the stack. |
11647 | auto *RE = StackComponents.front().getAssociatedExpression(); | ||||
11648 | |||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11649 | // Expressions must start from the same base. Here we detect at which |
11650 | // point both expressions diverge from each other and see if we can | ||||
11651 | // detect if the memory referred to both expressions is contiguous and | ||||
11652 | // do not overlap. | ||||
11653 | auto CI = CurComponents.rbegin(); | ||||
11654 | auto CE = CurComponents.rend(); | ||||
11655 | auto SI = StackComponents.rbegin(); | ||||
11656 | auto SE = StackComponents.rend(); | ||||
11657 | for (; CI != CE && SI != SE; ++CI, ++SI) { | ||||
11658 | |||||
11659 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] | ||||
11660 | // At most one list item can be an array item derived from a given | ||||
11661 | // variable in map clauses of the same construct. | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11662 | if (CurrentRegionOnly && |
11663 | (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || | ||||
11664 | isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && | ||||
11665 | (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || | ||||
11666 | isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { | ||||
11667 | SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11668 | diag::err_omp_multiple_array_items_in_map_clause) |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11669 | << CI->getAssociatedExpression()->getSourceRange(); |
11670 | SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), | ||||
11671 | diag::note_used_here) | ||||
11672 | << SI->getAssociatedExpression()->getSourceRange(); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11673 | return true; |
11674 | } | ||||
11675 | |||||
11676 | // Do both expressions have the same kind? | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11677 | if (CI->getAssociatedExpression()->getStmtClass() != |
11678 | SI->getAssociatedExpression()->getStmtClass()) | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11679 | break; |
11680 | |||||
11681 | // Are we dealing with different variables/fields? | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11682 | if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11683 | break; |
11684 | } | ||||
Kelvin Li | 9f645ae | 2016-07-18 22:49:16 +0000 | [diff] [blame] | 11685 | // Check if the extra components of the expressions in the enclosing |
11686 | // data environment are redundant for the current base declaration. | ||||
11687 | // If they are, the maps completely overlap, which is legal. | ||||
11688 | for (; SI != SE; ++SI) { | ||||
11689 | QualType Type; | ||||
11690 | if (auto *ASE = | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 11691 | dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { |
Kelvin Li | 9f645ae | 2016-07-18 22:49:16 +0000 | [diff] [blame] | 11692 | Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); |
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 11693 | } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>( |
11694 | SI->getAssociatedExpression())) { | ||||
Kelvin Li | 9f645ae | 2016-07-18 22:49:16 +0000 | [diff] [blame] | 11695 | auto *E = OASE->getBase()->IgnoreParenImpCasts(); |
11696 | Type = | ||||
11697 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); | ||||
11698 | } | ||||
11699 | if (Type.isNull() || Type->isAnyPointerType() || | ||||
11700 | CheckArrayExpressionDoesNotReferToWholeSize( | ||||
11701 | SemaRef, SI->getAssociatedExpression(), Type)) | ||||
11702 | break; | ||||
11703 | } | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11704 | |
11705 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] | ||||
11706 | // List items of map clauses in the same construct must not share | ||||
11707 | // original storage. | ||||
11708 | // | ||||
11709 | // If the expressions are exactly the same or one is a subset of the | ||||
11710 | // other, it means they are sharing storage. | ||||
11711 | if (CI == CE && SI == SE) { | ||||
11712 | if (CurrentRegionOnly) { | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11713 | if (CKind == OMPC_map) |
11714 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; | ||||
11715 | else { | ||||
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 11716 | assert(CKind == OMPC_to || CKind == OMPC_from); |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11717 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) |
11718 | << ERange; | ||||
11719 | } | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11720 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) |
11721 | << RE->getSourceRange(); | ||||
11722 | return true; | ||||
11723 | } else { | ||||
11724 | // If we find the same expression in the enclosing data environment, | ||||
11725 | // that is legal. | ||||
11726 | IsEnclosedByDataEnvironmentExpr = true; | ||||
11727 | return false; | ||||
11728 | } | ||||
11729 | } | ||||
11730 | |||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11731 | QualType DerivedType = |
11732 | std::prev(CI)->getAssociatedDeclaration()->getType(); | ||||
11733 | SourceLocation DerivedLoc = | ||||
11734 | std::prev(CI)->getAssociatedExpression()->getExprLoc(); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11735 | |
11736 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] | ||||
11737 | // If the type of a list item is a reference to a type T then the type | ||||
11738 | // will be considered to be T for all purposes of this clause. | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11739 | DerivedType = DerivedType.getNonReferenceType(); |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11740 | |
11741 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] | ||||
11742 | // A variable for which the type is pointer and an array section | ||||
11743 | // derived from that variable must not appear as list items of map | ||||
11744 | // clauses of the same construct. | ||||
11745 | // | ||||
11746 | // Also, cover one of the cases in: | ||||
11747 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] | ||||
11748 | // If any part of the original storage of a list item has corresponding | ||||
11749 | // storage in the device data environment, all of the original storage | ||||
11750 | // must have corresponding storage in the device data environment. | ||||
11751 | // | ||||
11752 | if (DerivedType->isAnyPointerType()) { | ||||
11753 | if (CI == CE || SI == SE) { | ||||
11754 | SemaRef.Diag( | ||||
11755 | DerivedLoc, | ||||
11756 | diag::err_omp_pointer_mapped_along_with_derived_section) | ||||
11757 | << DerivedLoc; | ||||
11758 | } else { | ||||
11759 | assert(CI != CE && SI != SE); | ||||
11760 | SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) | ||||
11761 | << DerivedLoc; | ||||
11762 | } | ||||
11763 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) | ||||
11764 | << RE->getSourceRange(); | ||||
11765 | return true; | ||||
11766 | } | ||||
11767 | |||||
11768 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] | ||||
11769 | // List items of map clauses in the same construct must not share | ||||
11770 | // original storage. | ||||
11771 | // | ||||
11772 | // An expression is a subset of the other. | ||||
11773 | if (CurrentRegionOnly && (CI == CE || SI == SE)) { | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11774 | if (CKind == OMPC_map) |
11775 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; | ||||
11776 | else { | ||||
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 11777 | assert(CKind == OMPC_to || CKind == OMPC_from); |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11778 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) |
11779 | << ERange; | ||||
11780 | } | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11781 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) |
11782 | << RE->getSourceRange(); | ||||
11783 | return true; | ||||
11784 | } | ||||
11785 | |||||
11786 | // The current expression uses the same base as other expression in the | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11787 | // data environment but does not contain it completely. |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11788 | if (!CurrentRegionOnly && SI != SE) |
11789 | EnclosingExpr = RE; | ||||
11790 | |||||
11791 | // The current expression is a subset of the expression in the data | ||||
11792 | // environment. | ||||
11793 | IsEnclosedByDataEnvironmentExpr |= | ||||
11794 | (!CurrentRegionOnly && CI != CE && SI == SE); | ||||
11795 | |||||
11796 | return false; | ||||
11797 | }); | ||||
11798 | |||||
11799 | if (CurrentRegionOnly) | ||||
11800 | return FoundError; | ||||
11801 | |||||
11802 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] | ||||
11803 | // If any part of the original storage of a list item has corresponding | ||||
11804 | // storage in the device data environment, all of the original storage must | ||||
11805 | // have corresponding storage in the device data environment. | ||||
11806 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] | ||||
11807 | // If a list item is an element of a structure, and a different element of | ||||
11808 | // the structure has a corresponding list item in the device data environment | ||||
11809 | // prior to a task encountering the construct associated with the map clause, | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11810 | // then the list item must also have a corresponding list item in the device |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11811 | // data environment prior to the task encountering the construct. |
11812 | // | ||||
11813 | if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { | ||||
11814 | SemaRef.Diag(ELoc, | ||||
11815 | diag::err_omp_original_storage_is_shared_and_does_not_contain) | ||||
11816 | << ERange; | ||||
11817 | SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) | ||||
11818 | << EnclosingExpr->getSourceRange(); | ||||
11819 | return true; | ||||
11820 | } | ||||
11821 | |||||
11822 | return FoundError; | ||||
11823 | } | ||||
11824 | |||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11825 | namespace { |
11826 | // Utility struct that gathers all the related lists associated with a mappable | ||||
11827 | // expression. | ||||
11828 | struct MappableVarListInfo final { | ||||
11829 | // The list of expressions. | ||||
11830 | ArrayRef<Expr *> VarList; | ||||
11831 | // The list of processed expressions. | ||||
11832 | SmallVector<Expr *, 16> ProcessedVarList; | ||||
11833 | // The mappble components for each expression. | ||||
11834 | OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; | ||||
11835 | // The base declaration of the variable. | ||||
11836 | SmallVector<ValueDecl *, 16> VarBaseDeclarations; | ||||
11837 | |||||
11838 | MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { | ||||
11839 | // We have a list of components and base declarations for each entry in the | ||||
11840 | // variable list. | ||||
11841 | VarComponents.reserve(VarList.size()); | ||||
11842 | VarBaseDeclarations.reserve(VarList.size()); | ||||
11843 | } | ||||
11844 | }; | ||||
11845 | } | ||||
11846 | |||||
11847 | // Check the validity of the provided variable list for the provided clause kind | ||||
11848 | // \a CKind. In the check process the valid expressions, and mappable expression | ||||
11849 | // components and variables are extracted and used to fill \a Vars, | ||||
11850 | // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and | ||||
11851 | // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. | ||||
11852 | static void | ||||
11853 | checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, | ||||
11854 | OpenMPClauseKind CKind, MappableVarListInfo &MVLI, | ||||
11855 | SourceLocation StartLoc, | ||||
11856 | OpenMPMapClauseKind MapType = OMPC_MAP_unknown, | ||||
11857 | bool IsMapTypeImplicit = false) { | ||||
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 11858 | // We only expect mappable expressions in 'to', 'from', and 'map' clauses. |
11859 | assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11860 | "Unexpected clause kind with mappable expressions!"); |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11861 | |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11862 | // Keep track of the mappable components and base declarations in this clause. |
11863 | // Each entry in the list is going to have a list of components associated. We | ||||
11864 | // record each set of the components so that we can build the clause later on. | ||||
11865 | // In the end we should have the same amount of declarations and component | ||||
11866 | // lists. | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11867 | |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11868 | for (auto &RE : MVLI.VarList) { |
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 11869 | assert(RE && "Null expr in omp to/from/map clause"); |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11870 | SourceLocation ELoc = RE->getExprLoc(); |
11871 | |||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11872 | auto *VE = RE->IgnoreParenLValueCasts(); |
11873 | |||||
11874 | if (VE->isValueDependent() || VE->isTypeDependent() || | ||||
11875 | VE->isInstantiationDependent() || | ||||
11876 | VE->containsUnexpandedParameterPack()) { | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11877 | // We can only analyze this information once the missing information is |
11878 | // resolved. | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11879 | MVLI.ProcessedVarList.push_back(RE); |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11880 | continue; |
11881 | } | ||||
11882 | |||||
11883 | auto *SimpleExpr = RE->IgnoreParenCasts(); | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11884 | |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11885 | if (!RE->IgnoreParenImpCasts()->isLValue()) { |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11886 | SemaRef.Diag(ELoc, |
11887 | diag::err_omp_expected_named_var_member_or_array_expression) | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11888 | << RE->getSourceRange(); |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11889 | continue; |
11890 | } | ||||
11891 | |||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11892 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; |
11893 | ValueDecl *CurDeclaration = nullptr; | ||||
11894 | |||||
11895 | // Obtain the array or member expression bases if required. Also, fill the | ||||
11896 | // components array with all the components identified in the process. | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11897 | auto *BE = |
11898 | CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11899 | if (!BE) |
11900 | continue; | ||||
11901 | |||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11902 | assert(!CurComponents.empty() && |
11903 | "Invalid mappable expression information."); | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11904 | |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11905 | // For the following checks, we rely on the base declaration which is |
11906 | // expected to be associated with the last component. The declaration is | ||||
11907 | // expected to be a variable or a field (if 'this' is being mapped). | ||||
11908 | CurDeclaration = CurComponents.back().getAssociatedDeclaration(); | ||||
11909 | assert(CurDeclaration && "Null decl on map clause."); | ||||
11910 | assert( | ||||
11911 | CurDeclaration->isCanonicalDecl() && | ||||
11912 | "Expecting components to have associated only canonical declarations."); | ||||
11913 | |||||
11914 | auto *VD = dyn_cast<VarDecl>(CurDeclaration); | ||||
11915 | auto *FD = dyn_cast<FieldDecl>(CurDeclaration); | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11916 | |
11917 | assert((VD || FD) && "Only variables or fields are expected here!"); | ||||
NAKAMURA Takumi | 6dcb814 | 2016-01-23 01:38:20 +0000 | [diff] [blame] | 11918 | (void)FD; |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11919 | |
11920 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11921 | // threadprivate variables cannot appear in a map clause. |
11922 | // OpenMP 4.5 [2.10.5, target update Construct] | ||||
11923 | // threadprivate variables cannot appear in a from clause. | ||||
11924 | if (VD && DSAS->isThreadPrivate(VD)) { | ||||
11925 | auto DVar = DSAS->getTopDSA(VD, false); | ||||
11926 | SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) | ||||
11927 | << getOpenMPClauseName(CKind); | ||||
11928 | ReportOriginalDSA(SemaRef, DSAS, VD, DVar); | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11929 | continue; |
11930 | } | ||||
11931 | |||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11932 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] |
11933 | // A list item cannot appear in both a map clause and a data-sharing | ||||
11934 | // attribute clause on the same construct. | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11935 | |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11936 | // Check conflicts with other map clause expressions. We check the conflicts |
11937 | // with the current construct separately from the enclosing data | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11938 | // environment, because the restrictions are different. We only have to |
11939 | // check conflicts across regions for the map clauses. | ||||
11940 | if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, | ||||
11941 | /*CurrentRegionOnly=*/true, CurComponents, CKind)) | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11942 | break; |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11943 | if (CKind == OMPC_map && |
11944 | CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, | ||||
11945 | /*CurrentRegionOnly=*/false, CurComponents, CKind)) | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11946 | break; |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11947 | |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11948 | // OpenMP 4.5 [2.10.5, target update Construct] |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11949 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] |
11950 | // If the type of a list item is a reference to a type T then the type will | ||||
11951 | // be considered to be T for all purposes of this clause. | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 11952 | QualType Type = CurDeclaration->getType().getNonReferenceType(); |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11953 | |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11954 | // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] |
11955 | // A list item in a to or from clause must have a mappable type. | ||||
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 11956 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] |
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11957 | // A list item must have a mappable type. |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11958 | if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, |
11959 | DSAS, Type)) | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 11960 | continue; |
11961 | |||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11962 | if (CKind == OMPC_map) { |
11963 | // target enter data | ||||
11964 | // OpenMP [2.10.2, Restrictions, p. 99] | ||||
11965 | // A map-type must be specified in all map clauses and must be either | ||||
11966 | // to or alloc. | ||||
11967 | OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); | ||||
11968 | if (DKind == OMPD_target_enter_data && | ||||
11969 | !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { | ||||
11970 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||
11971 | << (IsMapTypeImplicit ? 1 : 0) | ||||
11972 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||
11973 | << getOpenMPDirectiveName(DKind); | ||||
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 11974 | continue; |
11975 | } | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11976 | |
11977 | // target exit_data | ||||
11978 | // OpenMP [2.10.3, Restrictions, p. 102] | ||||
11979 | // A map-type must be specified in all map clauses and must be either | ||||
11980 | // from, release, or delete. | ||||
11981 | if (DKind == OMPD_target_exit_data && | ||||
11982 | !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || | ||||
11983 | MapType == OMPC_MAP_delete)) { | ||||
11984 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) | ||||
11985 | << (IsMapTypeImplicit ? 1 : 0) | ||||
11986 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) | ||||
11987 | << getOpenMPDirectiveName(DKind); | ||||
11988 | continue; | ||||
11989 | } | ||||
11990 | |||||
11991 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] | ||||
11992 | // A list item cannot appear in both a map clause and a data-sharing | ||||
11993 | // attribute clause on the same construct | ||||
Kelvin Li | 83c451e | 2016-12-25 04:52:54 +0000 | [diff] [blame] | 11994 | if ((DKind == OMPD_target || DKind == OMPD_target_teams || |
Kelvin Li | 80e8f56 | 2016-12-29 22:16:30 +0000 | [diff] [blame] | 11995 | DKind == OMPD_target_teams_distribute || |
Kelvin Li | 1851df5 | 2017-01-03 05:23:48 +0000 | [diff] [blame] | 11996 | DKind == OMPD_target_teams_distribute_parallel_for || |
Kelvin Li | da68118 | 2017-01-10 18:08:18 +0000 | [diff] [blame] | 11997 | DKind == OMPD_target_teams_distribute_parallel_for_simd || |
11998 | DKind == OMPD_target_teams_distribute_simd) && VD) { | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 11999 | auto DVar = DSAS->getTopDSA(VD, false); |
12000 | if (isOpenMPPrivate(DVar.CKind)) { | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12001 | SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 12002 | << getOpenMPClauseName(DVar.CKind) |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12003 | << getOpenMPClauseName(OMPC_map) |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 12004 | << getOpenMPDirectiveName(DSAS->getCurrentDirective()); |
12005 | ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); | ||||
12006 | continue; | ||||
12007 | } | ||||
12008 | } | ||||
Carlo Bertolli | b74bfc8 | 2016-03-18 21:43:32 +0000 | [diff] [blame] | 12009 | } |
12010 | |||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 12011 | // Save the current expression. |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 12012 | MVLI.ProcessedVarList.push_back(RE); |
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 12013 | |
12014 | // Store the components in the stack so that they can be used to check | ||||
12015 | // against other clauses later on. | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12016 | DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, |
12017 | /*WhereFoundClauseKind=*/OMPC_map); | ||||
Samuel Antao | 9092700 | 2016-04-26 14:54:23 +0000 | [diff] [blame] | 12018 | |
12019 | // Save the components and declaration to create the clause. For purposes of | ||||
12020 | // the clause creation, any component list that has has base 'this' uses | ||||
Samuel Antao | 686c70c | 2016-05-26 17:30:50 +0000 | [diff] [blame] | 12021 | // null as base declaration. |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 12022 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); |
12023 | MVLI.VarComponents.back().append(CurComponents.begin(), | ||||
12024 | CurComponents.end()); | ||||
12025 | MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr | ||||
12026 | : CurDeclaration); | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 12027 | } |
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 12028 | } |
12029 | |||||
12030 | OMPClause * | ||||
12031 | Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, | ||||
12032 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, | ||||
12033 | SourceLocation MapLoc, SourceLocation ColonLoc, | ||||
12034 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, | ||||
12035 | SourceLocation LParenLoc, SourceLocation EndLoc) { | ||||
12036 | MappableVarListInfo MVLI(VarList); | ||||
12037 | checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, | ||||
12038 | MapType, IsMapTypeImplicit); | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 12039 | |
Samuel Antao | 5de996e | 2016-01-22 20:21:36 +0000 | [diff] [blame] | 12040 | // We need to produce a map clause even if we don't have variables so that |
12041 | // other diagnostics related with non-existing map clauses are accurate. | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 12042 | return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
12043 | MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, | ||||
12044 | MVLI.VarComponents, MapTypeModifier, MapType, | ||||
12045 | IsMapTypeImplicit, MapLoc); | ||||
Kelvin Li | 0bff7af | 2015-11-23 05:32:03 +0000 | [diff] [blame] | 12046 | } |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 12047 | |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12048 | QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, |
12049 | TypeResult ParsedType) { | ||||
12050 | assert(ParsedType.isUsable()); | ||||
12051 | |||||
12052 | QualType ReductionType = GetTypeFromParser(ParsedType.get()); | ||||
12053 | if (ReductionType.isNull()) | ||||
12054 | return QualType(); | ||||
12055 | |||||
12056 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ | ||||
12057 | // A type name in a declare reduction directive cannot be a function type, an | ||||
12058 | // array type, a reference type, or a type qualified with const, volatile or | ||||
12059 | // restrict. | ||||
12060 | if (ReductionType.hasQualifiers()) { | ||||
12061 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; | ||||
12062 | return QualType(); | ||||
12063 | } | ||||
12064 | |||||
12065 | if (ReductionType->isFunctionType()) { | ||||
12066 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; | ||||
12067 | return QualType(); | ||||
12068 | } | ||||
12069 | if (ReductionType->isReferenceType()) { | ||||
12070 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; | ||||
12071 | return QualType(); | ||||
12072 | } | ||||
12073 | if (ReductionType->isArrayType()) { | ||||
12074 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; | ||||
12075 | return QualType(); | ||||
12076 | } | ||||
12077 | return ReductionType; | ||||
12078 | } | ||||
12079 | |||||
12080 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( | ||||
12081 | Scope *S, DeclContext *DC, DeclarationName Name, | ||||
12082 | ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, | ||||
12083 | AccessSpecifier AS, Decl *PrevDeclInScope) { | ||||
12084 | SmallVector<Decl *, 8> Decls; | ||||
12085 | Decls.reserve(ReductionTypes.size()); | ||||
12086 | |||||
12087 | LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, | ||||
Richard Smith | becb92d | 2017-10-10 22:33:17 +0000 | [diff] [blame] | 12088 | forRedeclarationInCurContext()); |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12089 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions |
12090 | // A reduction-identifier may not be re-declared in the current scope for the | ||||
12091 | // same type or for a type that is compatible according to the base language | ||||
12092 | // rules. | ||||
12093 | llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; | ||||
12094 | OMPDeclareReductionDecl *PrevDRD = nullptr; | ||||
12095 | bool InCompoundScope = true; | ||||
12096 | if (S != nullptr) { | ||||
12097 | // Find previous declaration with the same name not referenced in other | ||||
12098 | // declarations. | ||||
12099 | FunctionScopeInfo *ParentFn = getEnclosingFunction(); | ||||
12100 | InCompoundScope = | ||||
12101 | (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); | ||||
12102 | LookupName(Lookup, S); | ||||
12103 | FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, | ||||
12104 | /*AllowInlineNamespace=*/false); | ||||
12105 | llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; | ||||
12106 | auto Filter = Lookup.makeFilter(); | ||||
12107 | while (Filter.hasNext()) { | ||||
12108 | auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); | ||||
12109 | if (InCompoundScope) { | ||||
12110 | auto I = UsedAsPrevious.find(PrevDecl); | ||||
12111 | if (I == UsedAsPrevious.end()) | ||||
12112 | UsedAsPrevious[PrevDecl] = false; | ||||
12113 | if (auto *D = PrevDecl->getPrevDeclInScope()) | ||||
12114 | UsedAsPrevious[D] = true; | ||||
12115 | } | ||||
12116 | PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = | ||||
12117 | PrevDecl->getLocation(); | ||||
12118 | } | ||||
12119 | Filter.done(); | ||||
12120 | if (InCompoundScope) { | ||||
12121 | for (auto &PrevData : UsedAsPrevious) { | ||||
12122 | if (!PrevData.second) { | ||||
12123 | PrevDRD = PrevData.first; | ||||
12124 | break; | ||||
12125 | } | ||||
12126 | } | ||||
12127 | } | ||||
12128 | } else if (PrevDeclInScope != nullptr) { | ||||
12129 | auto *PrevDRDInScope = PrevDRD = | ||||
12130 | cast<OMPDeclareReductionDecl>(PrevDeclInScope); | ||||
12131 | do { | ||||
12132 | PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = | ||||
12133 | PrevDRDInScope->getLocation(); | ||||
12134 | PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); | ||||
12135 | } while (PrevDRDInScope != nullptr); | ||||
12136 | } | ||||
12137 | for (auto &TyData : ReductionTypes) { | ||||
12138 | auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); | ||||
12139 | bool Invalid = false; | ||||
12140 | if (I != PreviousRedeclTypes.end()) { | ||||
12141 | Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) | ||||
12142 | << TyData.first; | ||||
12143 | Diag(I->second, diag::note_previous_definition); | ||||
12144 | Invalid = true; | ||||
12145 | } | ||||
12146 | PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; | ||||
12147 | auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, | ||||
12148 | Name, TyData.first, PrevDRD); | ||||
12149 | DC->addDecl(DRD); | ||||
12150 | DRD->setAccess(AS); | ||||
12151 | Decls.push_back(DRD); | ||||
12152 | if (Invalid) | ||||
12153 | DRD->setInvalidDecl(); | ||||
12154 | else | ||||
12155 | PrevDRD = DRD; | ||||
12156 | } | ||||
12157 | |||||
12158 | return DeclGroupPtrTy::make( | ||||
12159 | DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); | ||||
12160 | } | ||||
12161 | |||||
12162 | void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { | ||||
12163 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||
12164 | |||||
12165 | // Enter new function scope. | ||||
12166 | PushFunctionScope(); | ||||
12167 | getCurFunction()->setHasBranchProtectedScope(); | ||||
12168 | getCurFunction()->setHasOMPDeclareReductionCombiner(); | ||||
12169 | |||||
12170 | if (S != nullptr) | ||||
12171 | PushDeclContext(S, DRD); | ||||
12172 | else | ||||
12173 | CurContext = DRD; | ||||
12174 | |||||
Faisal Vali | d143a0c | 2017-04-01 21:30:49 +0000 | [diff] [blame] | 12175 | PushExpressionEvaluationContext( |
12176 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12177 | |
12178 | QualType ReductionType = DRD->getType(); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 12179 | // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will |
12180 | // be replaced by '*omp_parm' during codegen. This required because 'omp_in' | ||||
12181 | // uses semantics of argument handles by value, but it should be passed by | ||||
12182 | // reference. C lang does not support references, so pass all parameters as | ||||
12183 | // pointers. | ||||
12184 | // Create 'T omp_in;' variable. | ||||
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12185 | auto *OmpInParm = |
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 12186 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12187 | // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will |
12188 | // be replaced by '*omp_parm' during codegen. This required because 'omp_out' | ||||
12189 | // uses semantics of argument handles by value, but it should be passed by | ||||
12190 | // reference. C lang does not support references, so pass all parameters as | ||||
12191 | // pointers. | ||||
12192 | // Create 'T omp_out;' variable. | ||||
12193 | auto *OmpOutParm = | ||||
12194 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); | ||||
12195 | if (S != nullptr) { | ||||
12196 | PushOnScopeChains(OmpInParm, S); | ||||
12197 | PushOnScopeChains(OmpOutParm, S); | ||||
12198 | } else { | ||||
12199 | DRD->addDecl(OmpInParm); | ||||
12200 | DRD->addDecl(OmpOutParm); | ||||
12201 | } | ||||
12202 | } | ||||
12203 | |||||
12204 | void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { | ||||
12205 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||
12206 | DiscardCleanupsInEvaluationContext(); | ||||
12207 | PopExpressionEvaluationContext(); | ||||
12208 | |||||
12209 | PopDeclContext(); | ||||
12210 | PopFunctionScopeInfo(); | ||||
12211 | |||||
12212 | if (Combiner != nullptr) | ||||
12213 | DRD->setCombiner(Combiner); | ||||
12214 | else | ||||
12215 | DRD->setInvalidDecl(); | ||||
12216 | } | ||||
12217 | |||||
Alexey Bataev | 070f43a | 2017-09-06 14:49:58 +0000 | [diff] [blame] | 12218 | VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12219 | auto *DRD = cast<OMPDeclareReductionDecl>(D); |
12220 | |||||
12221 | // Enter new function scope. | ||||
12222 | PushFunctionScope(); | ||||
12223 | getCurFunction()->setHasBranchProtectedScope(); | ||||
12224 | |||||
12225 | if (S != nullptr) | ||||
12226 | PushDeclContext(S, DRD); | ||||
12227 | else | ||||
12228 | CurContext = DRD; | ||||
12229 | |||||
Faisal Vali | d143a0c | 2017-04-01 21:30:49 +0000 | [diff] [blame] | 12230 | PushExpressionEvaluationContext( |
12231 | ExpressionEvaluationContext::PotentiallyEvaluated); | ||||
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12232 | |
12233 | QualType ReductionType = DRD->getType(); | ||||
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12234 | // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will |
12235 | // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' | ||||
12236 | // uses semantics of argument handles by value, but it should be passed by | ||||
12237 | // reference. C lang does not support references, so pass all parameters as | ||||
12238 | // pointers. | ||||
12239 | // Create 'T omp_priv;' variable. | ||||
12240 | auto *OmpPrivParm = | ||||
12241 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); | ||||
Alexey Bataev | a839ddd | 2016-03-17 10:19:46 +0000 | [diff] [blame] | 12242 | // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will |
12243 | // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' | ||||
12244 | // uses semantics of argument handles by value, but it should be passed by | ||||
12245 | // reference. C lang does not support references, so pass all parameters as | ||||
12246 | // pointers. | ||||
12247 | // Create 'T omp_orig;' variable. | ||||
12248 | auto *OmpOrigParm = | ||||
12249 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); | ||||
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12250 | if (S != nullptr) { |
12251 | PushOnScopeChains(OmpPrivParm, S); | ||||
12252 | PushOnScopeChains(OmpOrigParm, S); | ||||
12253 | } else { | ||||
12254 | DRD->addDecl(OmpPrivParm); | ||||
12255 | DRD->addDecl(OmpOrigParm); | ||||
12256 | } | ||||
Alexey Bataev | 070f43a | 2017-09-06 14:49:58 +0000 | [diff] [blame] | 12257 | return OmpPrivParm; |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12258 | } |
12259 | |||||
Alexey Bataev | 070f43a | 2017-09-06 14:49:58 +0000 | [diff] [blame] | 12260 | void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, |
12261 | VarDecl *OmpPrivParm) { | ||||
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12262 | auto *DRD = cast<OMPDeclareReductionDecl>(D); |
12263 | DiscardCleanupsInEvaluationContext(); | ||||
12264 | PopExpressionEvaluationContext(); | ||||
12265 | |||||
12266 | PopDeclContext(); | ||||
12267 | PopFunctionScopeInfo(); | ||||
12268 | |||||
Alexey Bataev | 070f43a | 2017-09-06 14:49:58 +0000 | [diff] [blame] | 12269 | if (Initializer != nullptr) { |
12270 | DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); | ||||
12271 | } else if (OmpPrivParm->hasInit()) { | ||||
12272 | DRD->setInitializer(OmpPrivParm->getInit(), | ||||
12273 | OmpPrivParm->isDirectInit() | ||||
12274 | ? OMPDeclareReductionDecl::DirectInit | ||||
12275 | : OMPDeclareReductionDecl::CopyInit); | ||||
12276 | } else { | ||||
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12277 | DRD->setInvalidDecl(); |
Alexey Bataev | 070f43a | 2017-09-06 14:49:58 +0000 | [diff] [blame] | 12278 | } |
Alexey Bataev | 94a4f0c | 2016-03-03 05:21:39 +0000 | [diff] [blame] | 12279 | } |
12280 | |||||
12281 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( | ||||
12282 | Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { | ||||
12283 | for (auto *D : DeclReductions.get()) { | ||||
12284 | if (IsValid) { | ||||
12285 | auto *DRD = cast<OMPDeclareReductionDecl>(D); | ||||
12286 | if (S != nullptr) | ||||
12287 | PushOnScopeChains(DRD, S, /*AddToContext=*/false); | ||||
12288 | } else | ||||
12289 | D->setInvalidDecl(); | ||||
12290 | } | ||||
12291 | return DeclReductions; | ||||
12292 | } | ||||
12293 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 12294 | OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 12295 | SourceLocation StartLoc, |
12296 | SourceLocation LParenLoc, | ||||
12297 | SourceLocation EndLoc) { | ||||
12298 | Expr *ValExpr = NumTeams; | ||||
Arpith Chacko Jacob | bc12634 | 2017-01-25 11:28:18 +0000 | [diff] [blame] | 12299 | Stmt *HelperValStmt = nullptr; |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 12300 | |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 12301 | // OpenMP [teams Constrcut, Restrictions] |
12302 | // The num_teams expression must evaluate to a positive integer value. | ||||
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 12303 | if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, |
12304 | /*StrictlyPositive=*/true)) | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 12305 | return nullptr; |
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 12306 | |
Arpith Chacko Jacob | bc12634 | 2017-01-25 11:28:18 +0000 | [diff] [blame] | 12307 | OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 12308 | OpenMPDirectiveKind CaptureRegion = |
12309 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); | ||||
12310 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||
Arpith Chacko Jacob | bc12634 | 2017-01-25 11:28:18 +0000 | [diff] [blame] | 12311 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
12312 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||
12313 | HelperValStmt = buildPreInits(Context, Captures); | ||||
12314 | } | ||||
12315 | |||||
12316 | return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, | ||||
12317 | StartLoc, LParenLoc, EndLoc); | ||||
Kelvin Li | 099bb8c | 2015-11-24 20:50:12 +0000 | [diff] [blame] | 12318 | } |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 12319 | |
12320 | OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, | ||||
12321 | SourceLocation StartLoc, | ||||
12322 | SourceLocation LParenLoc, | ||||
12323 | SourceLocation EndLoc) { | ||||
12324 | Expr *ValExpr = ThreadLimit; | ||||
Arpith Chacko Jacob | 7ecc0b7 | 2017-01-25 11:44:35 +0000 | [diff] [blame] | 12325 | Stmt *HelperValStmt = nullptr; |
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 12326 | |
12327 | // OpenMP [teams Constrcut, Restrictions] | ||||
12328 | // The thread_limit expression must evaluate to a positive integer value. | ||||
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 12329 | if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, |
12330 | /*StrictlyPositive=*/true)) | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 12331 | return nullptr; |
12332 | |||||
Arpith Chacko Jacob | 7ecc0b7 | 2017-01-25 11:44:35 +0000 | [diff] [blame] | 12333 | OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); |
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 12334 | OpenMPDirectiveKind CaptureRegion = |
12335 | getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); | ||||
12336 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { | ||||
Arpith Chacko Jacob | 7ecc0b7 | 2017-01-25 11:44:35 +0000 | [diff] [blame] | 12337 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
12338 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||
12339 | HelperValStmt = buildPreInits(Context, Captures); | ||||
12340 | } | ||||
12341 | |||||
12342 | return new (Context) OMPThreadLimitClause( | ||||
12343 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); | ||||
Kelvin Li | a15fb1a | 2015-11-27 18:47:36 +0000 | [diff] [blame] | 12344 | } |
Alexey Bataev | a056935 | 2015-12-01 10:17:31 +0000 | [diff] [blame] | 12345 | |
12346 | OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, | ||||
12347 | SourceLocation StartLoc, | ||||
12348 | SourceLocation LParenLoc, | ||||
12349 | SourceLocation EndLoc) { | ||||
12350 | Expr *ValExpr = Priority; | ||||
12351 | |||||
12352 | // OpenMP [2.9.1, task Constrcut] | ||||
12353 | // The priority-value is a non-negative numerical scalar expression. | ||||
12354 | if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, | ||||
12355 | /*StrictlyPositive=*/false)) | ||||
12356 | return nullptr; | ||||
12357 | |||||
12358 | return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); | ||||
12359 | } | ||||
Alexey Bataev | 1fd4aed | 2015-12-07 12:52:51 +0000 | [diff] [blame] | 12360 | |
12361 | OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, | ||||
12362 | SourceLocation StartLoc, | ||||
12363 | SourceLocation LParenLoc, | ||||
12364 | SourceLocation EndLoc) { | ||||
12365 | Expr *ValExpr = Grainsize; | ||||
12366 | |||||
12367 | // OpenMP [2.9.2, taskloop Constrcut] | ||||
12368 | // The parameter of the grainsize clause must be a positive integer | ||||
12369 | // expression. | ||||
12370 | if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, | ||||
12371 | /*StrictlyPositive=*/true)) | ||||
12372 | return nullptr; | ||||
12373 | |||||
12374 | return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); | ||||
12375 | } | ||||
Alexey Bataev | 382967a | 2015-12-08 12:06:20 +0000 | [diff] [blame] | 12376 | |
12377 | OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, | ||||
12378 | SourceLocation StartLoc, | ||||
12379 | SourceLocation LParenLoc, | ||||
12380 | SourceLocation EndLoc) { | ||||
12381 | Expr *ValExpr = NumTasks; | ||||
12382 | |||||
12383 | // OpenMP [2.9.2, taskloop Constrcut] | ||||
12384 | // The parameter of the num_tasks clause must be a positive integer | ||||
12385 | // expression. | ||||
12386 | if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, | ||||
12387 | /*StrictlyPositive=*/true)) | ||||
12388 | return nullptr; | ||||
12389 | |||||
12390 | return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); | ||||
12391 | } | ||||
12392 | |||||
Alexey Bataev | 28c7541 | 2015-12-15 08:19:24 +0000 | [diff] [blame] | 12393 | OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, |
12394 | SourceLocation LParenLoc, | ||||
12395 | SourceLocation EndLoc) { | ||||
12396 | // OpenMP [2.13.2, critical construct, Description] | ||||
12397 | // ... where hint-expression is an integer constant expression that evaluates | ||||
12398 | // to a valid lock hint. | ||||
12399 | ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); | ||||
12400 | if (HintExpr.isInvalid()) | ||||
12401 | return nullptr; | ||||
12402 | return new (Context) | ||||
12403 | OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); | ||||
12404 | } | ||||
12405 | |||||
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 12406 | OMPClause *Sema::ActOnOpenMPDistScheduleClause( |
12407 | OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, | ||||
12408 | SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, | ||||
12409 | SourceLocation EndLoc) { | ||||
12410 | if (Kind == OMPC_DIST_SCHEDULE_unknown) { | ||||
12411 | std::string Values; | ||||
12412 | Values += "'"; | ||||
12413 | Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); | ||||
12414 | Values += "'"; | ||||
12415 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | ||||
12416 | << Values << getOpenMPClauseName(OMPC_dist_schedule); | ||||
12417 | return nullptr; | ||||
12418 | } | ||||
12419 | Expr *ValExpr = ChunkSize; | ||||
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 12420 | Stmt *HelperValStmt = nullptr; |
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 12421 | if (ChunkSize) { |
12422 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && | ||||
12423 | !ChunkSize->isInstantiationDependent() && | ||||
12424 | !ChunkSize->containsUnexpandedParameterPack()) { | ||||
12425 | SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); | ||||
12426 | ExprResult Val = | ||||
12427 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); | ||||
12428 | if (Val.isInvalid()) | ||||
12429 | return nullptr; | ||||
12430 | |||||
12431 | ValExpr = Val.get(); | ||||
12432 | |||||
12433 | // OpenMP [2.7.1, Restrictions] | ||||
12434 | // chunk_size must be a loop invariant integer expression with a positive | ||||
12435 | // value. | ||||
12436 | llvm::APSInt Result; | ||||
12437 | if (ValExpr->isIntegerConstantExpr(Result, Context)) { | ||||
12438 | if (Result.isSigned() && !Result.isStrictlyPositive()) { | ||||
12439 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) | ||||
12440 | << "dist_schedule" << ChunkSize->getSourceRange(); | ||||
12441 | return nullptr; | ||||
12442 | } | ||||
Alexey Bataev | 2ba6704 | 2017-11-28 21:11:44 +0000 | [diff] [blame] | 12443 | } else if (getOpenMPCaptureRegionForClause( |
12444 | DSAStack->getCurrentDirective(), OMPC_dist_schedule) != | ||||
12445 | OMPD_unknown && | ||||
Alexey Bataev | b46cdea | 2016-06-15 11:20:48 +0000 | [diff] [blame] | 12446 | !CurContext->isDependentContext()) { |
Alexey Bataev | 5a3af13 | 2016-03-29 08:58:54 +0000 | [diff] [blame] | 12447 | llvm::MapVector<Expr *, DeclRefExpr *> Captures; |
12448 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); | ||||
12449 | HelperValStmt = buildPreInits(Context, Captures); | ||||
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 12450 | } |
12451 | } | ||||
12452 | } | ||||
12453 | |||||
12454 | return new (Context) | ||||
12455 | OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, | ||||
Alexey Bataev | 3392d76 | 2016-02-16 11:18:12 +0000 | [diff] [blame] | 12456 | Kind, ValExpr, HelperValStmt); |
Carlo Bertolli | b4adf55 | 2016-01-15 18:50:31 +0000 | [diff] [blame] | 12457 | } |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 12458 | |
12459 | OMPClause *Sema::ActOnOpenMPDefaultmapClause( | ||||
12460 | OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, | ||||
12461 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, | ||||
12462 | SourceLocation KindLoc, SourceLocation EndLoc) { | ||||
12463 | // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 12464 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 12465 | std::string Value; |
12466 | SourceLocation Loc; | ||||
12467 | Value += "'"; | ||||
12468 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { | ||||
12469 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 12470 | OMPC_DEFAULTMAP_MODIFIER_tofrom); |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 12471 | Loc = MLoc; |
12472 | } else { | ||||
12473 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 12474 | OMPC_DEFAULTMAP_scalar); |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 12475 | Loc = KindLoc; |
12476 | } | ||||
12477 | Value += "'"; | ||||
12478 | Diag(Loc, diag::err_omp_unexpected_clause_value) | ||||
12479 | << Value << getOpenMPClauseName(OMPC_defaultmap); | ||||
12480 | return nullptr; | ||||
12481 | } | ||||
Alexey Bataev | 2fd0cb2 | 2017-10-05 17:51:39 +0000 | [diff] [blame] | 12482 | DSAStack->setDefaultDMAToFromScalar(StartLoc); |
Arpith Chacko Jacob | 3cf8904 | 2016-01-26 16:37:23 +0000 | [diff] [blame] | 12483 | |
12484 | return new (Context) | ||||
12485 | OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); | ||||
12486 | } | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12487 | |
12488 | bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { | ||||
12489 | DeclContext *CurLexicalContext = getCurLexicalContext(); | ||||
12490 | if (!CurLexicalContext->isFileContext() && | ||||
12491 | !CurLexicalContext->isExternCContext() && | ||||
Alexey Bataev | 502ec49 | 2017-10-03 20:00:00 +0000 | [diff] [blame] | 12492 | !CurLexicalContext->isExternCXXContext() && |
12493 | !isa<CXXRecordDecl>(CurLexicalContext) && | ||||
12494 | !isa<ClassTemplateDecl>(CurLexicalContext) && | ||||
12495 | !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && | ||||
12496 | !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12497 | Diag(Loc, diag::err_omp_region_not_file_context); |
12498 | return false; | ||||
12499 | } | ||||
12500 | if (IsInOpenMPDeclareTargetContext) { | ||||
12501 | Diag(Loc, diag::err_omp_enclosed_declare_target); | ||||
12502 | return false; | ||||
12503 | } | ||||
12504 | |||||
12505 | IsInOpenMPDeclareTargetContext = true; | ||||
12506 | return true; | ||||
12507 | } | ||||
12508 | |||||
12509 | void Sema::ActOnFinishOpenMPDeclareTargetDirective() { | ||||
12510 | assert(IsInOpenMPDeclareTargetContext && | ||||
12511 | "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); | ||||
12512 | |||||
12513 | IsInOpenMPDeclareTargetContext = false; | ||||
12514 | } | ||||
12515 | |||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 12516 | void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, |
12517 | CXXScopeSpec &ScopeSpec, | ||||
12518 | const DeclarationNameInfo &Id, | ||||
12519 | OMPDeclareTargetDeclAttr::MapTypeTy MT, | ||||
12520 | NamedDeclSetType &SameDirectiveDecls) { | ||||
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12521 | LookupResult Lookup(*this, Id, LookupOrdinaryName); |
12522 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); | ||||
12523 | |||||
12524 | if (Lookup.isAmbiguous()) | ||||
12525 | return; | ||||
12526 | Lookup.suppressDiagnostics(); | ||||
12527 | |||||
12528 | if (!Lookup.isSingleResult()) { | ||||
12529 | if (TypoCorrection Corrected = | ||||
12530 | CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, | ||||
12531 | llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), | ||||
12532 | CTK_ErrorRecovery)) { | ||||
12533 | diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) | ||||
12534 | << Id.getName()); | ||||
12535 | checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); | ||||
12536 | return; | ||||
12537 | } | ||||
12538 | |||||
12539 | Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); | ||||
12540 | return; | ||||
12541 | } | ||||
12542 | |||||
12543 | NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); | ||||
12544 | if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { | ||||
12545 | if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) | ||||
12546 | Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); | ||||
12547 | |||||
12548 | if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { | ||||
12549 | Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); | ||||
12550 | ND->addAttr(A); | ||||
12551 | if (ASTMutationListener *ML = Context.getASTMutationListener()) | ||||
12552 | ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); | ||||
12553 | checkDeclIsAllowedInOpenMPTarget(nullptr, ND); | ||||
12554 | } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { | ||||
12555 | Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) | ||||
12556 | << Id.getName(); | ||||
12557 | } | ||||
12558 | } else | ||||
12559 | Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); | ||||
12560 | } | ||||
12561 | |||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12562 | static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, |
12563 | Sema &SemaRef, Decl *D) { | ||||
12564 | if (!D) | ||||
12565 | return; | ||||
12566 | Decl *LD = nullptr; | ||||
12567 | if (isa<TagDecl>(D)) { | ||||
12568 | LD = cast<TagDecl>(D)->getDefinition(); | ||||
12569 | } else if (isa<VarDecl>(D)) { | ||||
12570 | LD = cast<VarDecl>(D)->getDefinition(); | ||||
12571 | |||||
12572 | // If this is an implicit variable that is legal and we do not need to do | ||||
12573 | // anything. | ||||
12574 | if (cast<VarDecl>(D)->isImplicit()) { | ||||
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12575 | Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( |
12576 | SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); | ||||
12577 | D->addAttr(A); | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12578 | if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) |
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12579 | ML->DeclarationMarkedOpenMPDeclareTarget(D, A); |
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12580 | return; |
12581 | } | ||||
12582 | |||||
12583 | } else if (isa<FunctionDecl>(D)) { | ||||
12584 | const FunctionDecl *FD = nullptr; | ||||
12585 | if (cast<FunctionDecl>(D)->hasBody(FD)) | ||||
12586 | LD = const_cast<FunctionDecl *>(FD); | ||||
12587 | |||||
12588 | // If the definition is associated with the current declaration in the | ||||
12589 | // target region (it can be e.g. a lambda) that is legal and we do not need | ||||
12590 | // to do anything else. | ||||
12591 | if (LD == D) { | ||||
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12592 | Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( |
12593 | SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); | ||||
12594 | D->addAttr(A); | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12595 | if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) |
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12596 | ML->DeclarationMarkedOpenMPDeclareTarget(D, A); |
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12597 | return; |
12598 | } | ||||
12599 | } | ||||
12600 | if (!LD) | ||||
12601 | LD = D; | ||||
12602 | if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && | ||||
12603 | (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { | ||||
12604 | // Outlined declaration is not declared target. | ||||
12605 | if (LD->isOutOfLine()) { | ||||
12606 | SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); | ||||
12607 | SemaRef.Diag(SL, diag::note_used_here) << SR; | ||||
12608 | } else { | ||||
12609 | DeclContext *DC = LD->getDeclContext(); | ||||
12610 | while (DC) { | ||||
12611 | if (isa<FunctionDecl>(DC) && | ||||
12612 | cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) | ||||
12613 | break; | ||||
12614 | DC = DC->getParent(); | ||||
12615 | } | ||||
12616 | if (DC) | ||||
12617 | return; | ||||
12618 | |||||
12619 | // Is not declared in target context. | ||||
12620 | SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); | ||||
12621 | SemaRef.Diag(SL, diag::note_used_here) << SR; | ||||
12622 | } | ||||
12623 | // Mark decl as declared target to prevent further diagnostic. | ||||
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12624 | Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( |
12625 | SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); | ||||
12626 | D->addAttr(A); | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12627 | if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) |
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12628 | ML->DeclarationMarkedOpenMPDeclareTarget(D, A); |
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12629 | } |
12630 | } | ||||
12631 | |||||
12632 | static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, | ||||
12633 | Sema &SemaRef, DSAStackTy *Stack, | ||||
12634 | ValueDecl *VD) { | ||||
12635 | if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) | ||||
12636 | return true; | ||||
12637 | if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) | ||||
12638 | return false; | ||||
12639 | return true; | ||||
12640 | } | ||||
12641 | |||||
12642 | void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { | ||||
12643 | if (!D || D->isInvalidDecl()) | ||||
12644 | return; | ||||
12645 | SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); | ||||
12646 | SourceLocation SL = E ? E->getLocStart() : D->getLocation(); | ||||
12647 | // 2.10.6: threadprivate variable cannot appear in a declare target directive. | ||||
12648 | if (VarDecl *VD = dyn_cast<VarDecl>(D)) { | ||||
12649 | if (DSAStack->isThreadPrivate(VD)) { | ||||
12650 | Diag(SL, diag::err_omp_threadprivate_in_target); | ||||
12651 | ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); | ||||
12652 | return; | ||||
12653 | } | ||||
12654 | } | ||||
12655 | if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { | ||||
12656 | // Problem if any with var declared with incomplete type will be reported | ||||
12657 | // as normal, so no need to check it here. | ||||
12658 | if ((E || !VD->getType()->isIncompleteType()) && | ||||
12659 | !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { | ||||
12660 | // Mark decl as declared target to prevent further diagnostic. | ||||
12661 | if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { | ||||
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12662 | Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( |
12663 | Context, OMPDeclareTargetDeclAttr::MT_To); | ||||
12664 | VD->addAttr(A); | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12665 | if (ASTMutationListener *ML = Context.getASTMutationListener()) |
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12666 | ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); |
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12667 | } |
12668 | return; | ||||
12669 | } | ||||
12670 | } | ||||
12671 | if (!E) { | ||||
12672 | // Checking declaration inside declare target region. | ||||
12673 | if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && | ||||
12674 | (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { | ||||
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12675 | Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( |
12676 | Context, OMPDeclareTargetDeclAttr::MT_To); | ||||
12677 | D->addAttr(A); | ||||
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12678 | if (ASTMutationListener *ML = Context.getASTMutationListener()) |
Dmitry Polukhin | d69b505 | 2016-05-09 14:59:13 +0000 | [diff] [blame] | 12679 | ML->DeclarationMarkedOpenMPDeclareTarget(D, A); |
Dmitry Polukhin | 0b0da29 | 2016-04-06 11:38:59 +0000 | [diff] [blame] | 12680 | } |
12681 | return; | ||||
12682 | } | ||||
12683 | checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); | ||||
12684 | } | ||||
Samuel Antao | 661c090 | 2016-05-26 17:39:58 +0000 | [diff] [blame] | 12685 | |
12686 | OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, | ||||
12687 | SourceLocation StartLoc, | ||||
12688 | SourceLocation LParenLoc, | ||||
12689 | SourceLocation EndLoc) { | ||||
12690 | MappableVarListInfo MVLI(VarList); | ||||
12691 | checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); | ||||
12692 | if (MVLI.ProcessedVarList.empty()) | ||||
12693 | return nullptr; | ||||
12694 | |||||
12695 | return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||
12696 | MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, | ||||
12697 | MVLI.VarComponents); | ||||
12698 | } | ||||
Samuel Antao | ec172c6 | 2016-05-26 17:49:04 +0000 | [diff] [blame] | 12699 | |
12700 | OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, | ||||
12701 | SourceLocation StartLoc, | ||||
12702 | SourceLocation LParenLoc, | ||||
12703 | SourceLocation EndLoc) { | ||||
12704 | MappableVarListInfo MVLI(VarList); | ||||
12705 | checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); | ||||
12706 | if (MVLI.ProcessedVarList.empty()) | ||||
12707 | return nullptr; | ||||
12708 | |||||
12709 | return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, | ||||
12710 | MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, | ||||
12711 | MVLI.VarComponents); | ||||
12712 | } | ||||
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 12713 | |
12714 | OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, | ||||
12715 | SourceLocation StartLoc, | ||||
12716 | SourceLocation LParenLoc, | ||||
12717 | SourceLocation EndLoc) { | ||||
Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 12718 | MappableVarListInfo MVLI(VarList); |
12719 | SmallVector<Expr *, 8> PrivateCopies; | ||||
12720 | SmallVector<Expr *, 8> Inits; | ||||
12721 | |||||
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 12722 | for (auto &RefExpr : VarList) { |
12723 | assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); | ||||
12724 | SourceLocation ELoc; | ||||
12725 | SourceRange ERange; | ||||
12726 | Expr *SimpleRefExpr = RefExpr; | ||||
12727 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||
12728 | if (Res.second) { | ||||
12729 | // It will be analyzed later. | ||||
Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 12730 | MVLI.ProcessedVarList.push_back(RefExpr); |
12731 | PrivateCopies.push_back(nullptr); | ||||
12732 | Inits.push_back(nullptr); | ||||
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 12733 | } |
12734 | ValueDecl *D = Res.first; | ||||
12735 | if (!D) | ||||
12736 | continue; | ||||
12737 | |||||
12738 | QualType Type = D->getType(); | ||||
Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 12739 | Type = Type.getNonReferenceType().getUnqualifiedType(); |
12740 | |||||
12741 | auto *VD = dyn_cast<VarDecl>(D); | ||||
12742 | |||||
12743 | // Item should be a pointer or reference to pointer. | ||||
12744 | if (!Type->isPointerType()) { | ||||
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 12745 | Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) |
12746 | << 0 << RefExpr->getSourceRange(); | ||||
12747 | continue; | ||||
12748 | } | ||||
Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 12749 | |
12750 | // Build the private variable and the expression that refers to it. | ||||
12751 | auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), | ||||
12752 | D->hasAttrs() ? &D->getAttrs() : nullptr); | ||||
12753 | if (VDPrivate->isInvalidDecl()) | ||||
12754 | continue; | ||||
12755 | |||||
12756 | CurContext->addDecl(VDPrivate); | ||||
12757 | auto VDPrivateRefExpr = buildDeclRefExpr( | ||||
12758 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); | ||||
12759 | |||||
12760 | // Add temporary variable to initialize the private copy of the pointer. | ||||
12761 | auto *VDInit = | ||||
12762 | buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); | ||||
12763 | auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), | ||||
12764 | RefExpr->getExprLoc()); | ||||
12765 | AddInitializerToDecl(VDPrivate, | ||||
12766 | DefaultLvalueConversion(VDInitRefExpr).get(), | ||||
Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 12767 | /*DirectInit=*/false); |
Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 12768 | |
12769 | // If required, build a capture to implement the privatization initialized | ||||
12770 | // with the current list item value. | ||||
12771 | DeclRefExpr *Ref = nullptr; | ||||
12772 | if (!VD) | ||||
12773 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); | ||||
12774 | MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); | ||||
12775 | PrivateCopies.push_back(VDPrivateRefExpr); | ||||
12776 | Inits.push_back(VDInitRefExpr); | ||||
12777 | |||||
12778 | // We need to add a data sharing attribute for this variable to make sure it | ||||
12779 | // is correctly captured. A variable that shows up in a use_device_ptr has | ||||
12780 | // similar properties of a first private variable. | ||||
12781 | DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); | ||||
12782 | |||||
12783 | // Create a mappable component for the list item. List items in this clause | ||||
12784 | // only need a component. | ||||
12785 | MVLI.VarBaseDeclarations.push_back(D); | ||||
12786 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||
12787 | MVLI.VarComponents.back().push_back( | ||||
12788 | OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); | ||||
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 12789 | } |
12790 | |||||
Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 12791 | if (MVLI.ProcessedVarList.empty()) |
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 12792 | return nullptr; |
12793 | |||||
Samuel Antao | cc10b85 | 2016-07-28 14:23:26 +0000 | [diff] [blame] | 12794 | return OMPUseDevicePtrClause::Create( |
12795 | Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, | ||||
12796 | PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); | ||||
Carlo Bertolli | 2404b17 | 2016-07-13 15:37:16 +0000 | [diff] [blame] | 12797 | } |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 12798 | |
12799 | OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, | ||||
12800 | SourceLocation StartLoc, | ||||
12801 | SourceLocation LParenLoc, | ||||
12802 | SourceLocation EndLoc) { | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12803 | MappableVarListInfo MVLI(VarList); |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 12804 | for (auto &RefExpr : VarList) { |
Kelvin Li | 8437625 | 2016-12-14 15:39:58 +0000 | [diff] [blame] | 12805 | assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 12806 | SourceLocation ELoc; |
12807 | SourceRange ERange; | ||||
12808 | Expr *SimpleRefExpr = RefExpr; | ||||
12809 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); | ||||
12810 | if (Res.second) { | ||||
12811 | // It will be analyzed later. | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12812 | MVLI.ProcessedVarList.push_back(RefExpr); |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 12813 | } |
12814 | ValueDecl *D = Res.first; | ||||
12815 | if (!D) | ||||
12816 | continue; | ||||
12817 | |||||
12818 | QualType Type = D->getType(); | ||||
12819 | // item should be a pointer or array or reference to pointer or array | ||||
12820 | if (!Type.getNonReferenceType()->isPointerType() && | ||||
12821 | !Type.getNonReferenceType()->isArrayType()) { | ||||
12822 | Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) | ||||
12823 | << 0 << RefExpr->getSourceRange(); | ||||
12824 | continue; | ||||
12825 | } | ||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12826 | |
12827 | // Check if the declaration in the clause does not show up in any data | ||||
12828 | // sharing attribute. | ||||
12829 | auto DVar = DSAStack->getTopDSA(D, false); | ||||
12830 | if (isOpenMPPrivate(DVar.CKind)) { | ||||
12831 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) | ||||
12832 | << getOpenMPClauseName(DVar.CKind) | ||||
12833 | << getOpenMPClauseName(OMPC_is_device_ptr) | ||||
12834 | << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); | ||||
12835 | ReportOriginalDSA(*this, DSAStack, D, DVar); | ||||
12836 | continue; | ||||
12837 | } | ||||
12838 | |||||
12839 | Expr *ConflictExpr; | ||||
12840 | if (DSAStack->checkMappableExprComponentListsForDecl( | ||||
David Majnemer | 9d16822 | 2016-08-05 17:44:54 +0000 | [diff] [blame] | 12841 | D, /*CurrentRegionOnly=*/true, |
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12842 | [&ConflictExpr]( |
12843 | OMPClauseMappableExprCommon::MappableExprComponentListRef R, | ||||
12844 | OpenMPClauseKind) -> bool { | ||||
12845 | ConflictExpr = R.front().getAssociatedExpression(); | ||||
12846 | return true; | ||||
12847 | })) { | ||||
12848 | Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); | ||||
12849 | Diag(ConflictExpr->getExprLoc(), diag::note_used_here) | ||||
12850 | << ConflictExpr->getSourceRange(); | ||||
12851 | continue; | ||||
12852 | } | ||||
12853 | |||||
12854 | // Store the components in the stack so that they can be used to check | ||||
12855 | // against other clauses later on. | ||||
12856 | OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); | ||||
12857 | DSAStack->addMappableExpressionComponents( | ||||
12858 | D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); | ||||
12859 | |||||
12860 | // Record the expression we've just processed. | ||||
12861 | MVLI.ProcessedVarList.push_back(SimpleRefExpr); | ||||
12862 | |||||
12863 | // Create a mappable component for the list item. List items in this clause | ||||
12864 | // only need a component. We use a null declaration to signal fields in | ||||
12865 | // 'this'. | ||||
12866 | assert((isa<DeclRefExpr>(SimpleRefExpr) || | ||||
12867 | isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && | ||||
12868 | "Unexpected device pointer expression!"); | ||||
12869 | MVLI.VarBaseDeclarations.push_back( | ||||
12870 | isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); | ||||
12871 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); | ||||
12872 | MVLI.VarComponents.back().push_back(MC); | ||||
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 12873 | } |
12874 | |||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12875 | if (MVLI.ProcessedVarList.empty()) |
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 12876 | return nullptr; |
12877 | |||||
Samuel Antao | 6890b09 | 2016-07-28 14:25:09 +0000 | [diff] [blame] | 12878 | return OMPIsDevicePtrClause::Create( |
12879 | Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, | ||||
12880 | MVLI.VarBaseDeclarations, MVLI.VarComponents); | ||||
Carlo Bertolli | 70594e9 | 2016-07-13 17:16:49 +0000 | [diff] [blame] | 12881 | } |