1 //===--- SemaOpenACCClause.cpp - Semantic Analysis for OpenACC clause -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenACC clauses. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/DeclCXX.h" 14 #include "clang/AST/ExprCXX.h" 15 #include "clang/AST/OpenACCClause.h" 16 #include "clang/Basic/DiagnosticSema.h" 17 #include "clang/Basic/OpenACCKinds.h" 18 #include "clang/Sema/SemaOpenACC.h" 19 20 using namespace clang; 21 22 namespace { 23 bool checkValidAfterDeviceType( 24 SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause, 25 const SemaOpenACC::OpenACCParsedClause &NewClause) { 26 // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are 27 // default clauses. Clauses that follow a device_type clause up to the end of 28 // the directive or up to the next device_type clause are device-specific 29 // clauses for the device types specified in the device_type argument. 30 // 31 // The above implies that despite what the individual text says, these are 32 // valid. 33 if (NewClause.getClauseKind() == OpenACCClauseKind::DType || 34 NewClause.getClauseKind() == OpenACCClauseKind::DeviceType) 35 return false; 36 37 // Implement check from OpenACC3.3: section 2.5.4: 38 // Only the async, wait, num_gangs, num_workers, and vector_length clauses may 39 // follow a device_type clause. 40 if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) { 41 switch (NewClause.getClauseKind()) { 42 case OpenACCClauseKind::Async: 43 case OpenACCClauseKind::Wait: 44 case OpenACCClauseKind::NumGangs: 45 case OpenACCClauseKind::NumWorkers: 46 case OpenACCClauseKind::VectorLength: 47 return false; 48 default: 49 break; 50 } 51 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) { 52 // Implement check from OpenACC3.3: section 2.9: 53 // Only the collapse, gang, worker, vector, seq, independent, auto, and tile 54 // clauses may follow a device_type clause. 55 switch (NewClause.getClauseKind()) { 56 case OpenACCClauseKind::Collapse: 57 case OpenACCClauseKind::Gang: 58 case OpenACCClauseKind::Worker: 59 case OpenACCClauseKind::Vector: 60 case OpenACCClauseKind::Seq: 61 case OpenACCClauseKind::Independent: 62 case OpenACCClauseKind::Auto: 63 case OpenACCClauseKind::Tile: 64 return false; 65 default: 66 break; 67 } 68 } else if (isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind())) { 69 // This seems like it should be the union of 2.9 and 2.5.4 from above. 70 switch (NewClause.getClauseKind()) { 71 case OpenACCClauseKind::Async: 72 case OpenACCClauseKind::Wait: 73 case OpenACCClauseKind::NumGangs: 74 case OpenACCClauseKind::NumWorkers: 75 case OpenACCClauseKind::VectorLength: 76 case OpenACCClauseKind::Collapse: 77 case OpenACCClauseKind::Gang: 78 case OpenACCClauseKind::Worker: 79 case OpenACCClauseKind::Vector: 80 case OpenACCClauseKind::Seq: 81 case OpenACCClauseKind::Independent: 82 case OpenACCClauseKind::Auto: 83 case OpenACCClauseKind::Tile: 84 return false; 85 default: 86 break; 87 } 88 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) { 89 // OpenACC3.3 section 2.6.5: Only the async and wait clauses may follow a 90 // device_type clause. 91 switch (NewClause.getClauseKind()) { 92 case OpenACCClauseKind::Async: 93 case OpenACCClauseKind::Wait: 94 return false; 95 default: 96 break; 97 } 98 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set || 99 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init || 100 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) { 101 // There are no restrictions on 'set', 'init', or 'shutdown'. 102 return false; 103 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) { 104 // OpenACC3.3 section 2.14.4: Only the async and wait clauses may follow a 105 // device_type clause. 106 switch (NewClause.getClauseKind()) { 107 case OpenACCClauseKind::Async: 108 case OpenACCClauseKind::Wait: 109 return false; 110 default: 111 break; 112 } 113 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine) { 114 // OpenACC 3.3 section 2.15: Only the 'gang', 'worker', 'vector', 'seq', and 115 // 'bind' clauses may follow a device_type clause. 116 switch (NewClause.getClauseKind()) { 117 case OpenACCClauseKind::Gang: 118 case OpenACCClauseKind::Worker: 119 case OpenACCClauseKind::Vector: 120 case OpenACCClauseKind::Seq: 121 case OpenACCClauseKind::Bind: 122 return false; 123 default: 124 break; 125 } 126 } 127 S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type) 128 << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind() 129 << NewClause.getDirectiveKind(); 130 S.Diag(DeviceTypeClause.getBeginLoc(), 131 diag::note_acc_active_applies_clause_here) 132 << diag::ACCDeviceTypeApp::Active << DeviceTypeClause.getClauseKind(); 133 return true; 134 } 135 136 // GCC looks through linkage specs, but not the other transparent declaration 137 // contexts for 'declare' restrictions, so this helper function helps get us 138 // through that. 139 const DeclContext *removeLinkageSpecDC(const DeclContext *DC) { 140 while (isa<LinkageSpecDecl>(DC)) 141 DC = DC->getParent(); 142 143 return DC; 144 } 145 146 class SemaOpenACCClauseVisitor { 147 SemaOpenACC &SemaRef; 148 ASTContext &Ctx; 149 ArrayRef<const OpenACCClause *> ExistingClauses; 150 151 // OpenACC 3.3 2.9: 152 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause 153 // appears. 154 bool 155 DiagGangWorkerVectorSeqConflict(SemaOpenACC::OpenACCParsedClause &Clause) { 156 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop && 157 !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) 158 return false; 159 assert(Clause.getClauseKind() == OpenACCClauseKind::Gang || 160 Clause.getClauseKind() == OpenACCClauseKind::Worker || 161 Clause.getClauseKind() == OpenACCClauseKind::Vector); 162 const auto *Itr = 163 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>); 164 165 if (Itr != ExistingClauses.end()) { 166 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 167 << Clause.getClauseKind() << (*Itr)->getClauseKind() 168 << Clause.getDirectiveKind(); 169 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here) 170 << (*Itr)->getClauseKind(); 171 172 return true; 173 } 174 return false; 175 } 176 177 OpenACCModifierKind 178 CheckModifierList(SemaOpenACC::OpenACCParsedClause &Clause, 179 OpenACCModifierKind Mods) { 180 auto CheckSingle = [=](OpenACCModifierKind CurMods, 181 OpenACCModifierKind ValidKinds, 182 OpenACCModifierKind Bit) { 183 if (!isOpenACCModifierBitSet(CurMods, Bit) || 184 isOpenACCModifierBitSet(ValidKinds, Bit)) 185 return CurMods; 186 187 SemaRef.Diag(Clause.getLParenLoc(), diag::err_acc_invalid_modifier) 188 << Bit << Clause.getClauseKind(); 189 190 return CurMods ^ Bit; 191 }; 192 auto Check = [&](OpenACCModifierKind ValidKinds) { 193 if ((Mods | ValidKinds) == ValidKinds) 194 return Mods; 195 196 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Always); 197 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::AlwaysIn); 198 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::AlwaysOut); 199 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Readonly); 200 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Zero); 201 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Capture); 202 return Mods; 203 }; 204 205 // The 'capture' modifier is only valid on copyin, copyout, and create on 206 // structured data or compute constructs (which also includes combined). 207 bool IsStructuredDataOrCompute = 208 Clause.getDirectiveKind() == OpenACCDirectiveKind::Data || 209 isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) || 210 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()); 211 212 switch (Clause.getClauseKind()) { 213 default: 214 llvm_unreachable("Only for copy, copyin, copyout, create"); 215 case OpenACCClauseKind::Copy: 216 case OpenACCClauseKind::PCopy: 217 case OpenACCClauseKind::PresentOrCopy: 218 // COPY: Capture always 219 return Check(OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn | 220 OpenACCModifierKind::AlwaysOut | 221 OpenACCModifierKind::Capture); 222 case OpenACCClauseKind::CopyIn: 223 case OpenACCClauseKind::PCopyIn: 224 case OpenACCClauseKind::PresentOrCopyIn: 225 // COPYIN: Capture only struct.data & compute 226 return Check(OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn | 227 OpenACCModifierKind::Readonly | 228 (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture 229 : OpenACCModifierKind::Invalid)); 230 case OpenACCClauseKind::CopyOut: 231 case OpenACCClauseKind::PCopyOut: 232 case OpenACCClauseKind::PresentOrCopyOut: 233 // COPYOUT: Capture only struct.data & compute 234 return Check(OpenACCModifierKind::Always | 235 OpenACCModifierKind::AlwaysOut | OpenACCModifierKind::Zero | 236 (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture 237 : OpenACCModifierKind::Invalid)); 238 case OpenACCClauseKind::Create: 239 case OpenACCClauseKind::PCreate: 240 case OpenACCClauseKind::PresentOrCreate: 241 // CREATE: Capture only struct.data & compute 242 return Check(OpenACCModifierKind::Zero | 243 (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture 244 : OpenACCModifierKind::Invalid)); 245 } 246 llvm_unreachable("didn't return from switch above?"); 247 } 248 249 // Helper for the 'routine' checks during 'new' clause addition. Precondition 250 // is that we already know the new clause is one of the prohbiited ones. 251 template <typename Pred> 252 bool 253 CheckValidRoutineNewClauseHelper(Pred HasPredicate, 254 SemaOpenACC::OpenACCParsedClause &Clause) { 255 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Routine) 256 return false; 257 258 auto *FirstDeviceType = 259 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCDeviceTypeClause>); 260 261 if (FirstDeviceType == ExistingClauses.end()) { 262 // If there isn't a device type yet, ANY duplicate is wrong. 263 264 auto *ExistingProhibitedClause = 265 llvm::find_if(ExistingClauses, HasPredicate); 266 267 if (ExistingProhibitedClause == ExistingClauses.end()) 268 return false; 269 270 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 271 << Clause.getClauseKind() 272 << (*ExistingProhibitedClause)->getClauseKind() 273 << Clause.getDirectiveKind(); 274 SemaRef.Diag((*ExistingProhibitedClause)->getBeginLoc(), 275 diag::note_acc_previous_clause_here) 276 << (*ExistingProhibitedClause)->getClauseKind(); 277 return true; 278 } 279 280 // At this point we know that this is 'after' a device type. So this is an 281 // error if: 1- there is one BEFORE the 'device_type' 2- there is one 282 // between this and the previous 'device_type'. 283 284 auto *BeforeDeviceType = 285 std::find_if(ExistingClauses.begin(), FirstDeviceType, HasPredicate); 286 // If there is one before the device_type (and we know we are after a 287 // device_type), than this is ill-formed. 288 if (BeforeDeviceType != FirstDeviceType) { 289 SemaRef.Diag( 290 Clause.getBeginLoc(), 291 diag::err_acc_clause_routine_cannot_combine_before_device_type) 292 << Clause.getClauseKind() << (*BeforeDeviceType)->getClauseKind(); 293 SemaRef.Diag((*BeforeDeviceType)->getBeginLoc(), 294 diag::note_acc_previous_clause_here) 295 << (*BeforeDeviceType)->getClauseKind(); 296 SemaRef.Diag((*FirstDeviceType)->getBeginLoc(), 297 diag::note_acc_active_applies_clause_here) 298 << diag::ACCDeviceTypeApp::Active 299 << (*FirstDeviceType)->getClauseKind(); 300 return true; 301 } 302 303 auto LastDeviceTypeItr = 304 std::find_if(ExistingClauses.rbegin(), ExistingClauses.rend(), 305 llvm::IsaPred<OpenACCDeviceTypeClause>); 306 307 // We already know there is one in the list, so it is nonsensical to not 308 // have one. 309 assert(LastDeviceTypeItr != ExistingClauses.rend()); 310 311 // Get the device-type from-the-front (not reverse) iterator from the 312 // reverse iterator. 313 auto *LastDeviceType = LastDeviceTypeItr.base() - 1; 314 315 auto *ExistingProhibitedSinceLastDevice = 316 std::find_if(LastDeviceType, ExistingClauses.end(), HasPredicate); 317 318 // No prohibited ones since the last device-type. 319 if (ExistingProhibitedSinceLastDevice == ExistingClauses.end()) 320 return false; 321 322 SemaRef.Diag(Clause.getBeginLoc(), 323 diag::err_acc_clause_routine_cannot_combine_same_device_type) 324 << Clause.getClauseKind() 325 << (*ExistingProhibitedSinceLastDevice)->getClauseKind(); 326 SemaRef.Diag((*ExistingProhibitedSinceLastDevice)->getBeginLoc(), 327 diag::note_acc_previous_clause_here) 328 << (*ExistingProhibitedSinceLastDevice)->getClauseKind(); 329 SemaRef.Diag((*LastDeviceType)->getBeginLoc(), 330 diag::note_acc_active_applies_clause_here) 331 << diag::ACCDeviceTypeApp::Active << (*LastDeviceType)->getClauseKind(); 332 return true; 333 } 334 335 // Routine has a pretty complicated set of rules for how device_type and the 336 // gang, worker, vector, and seq clauses work. So diagnose some of it here. 337 bool CheckValidRoutineGangWorkerVectorSeqNewClause( 338 SemaOpenACC::OpenACCParsedClause &Clause) { 339 340 if (Clause.getClauseKind() != OpenACCClauseKind::Gang && 341 Clause.getClauseKind() != OpenACCClauseKind::Vector && 342 Clause.getClauseKind() != OpenACCClauseKind::Worker && 343 Clause.getClauseKind() != OpenACCClauseKind::Seq) 344 return false; 345 auto ProhibitedPred = llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause, 346 OpenACCVectorClause, OpenACCSeqClause>; 347 348 return CheckValidRoutineNewClauseHelper(ProhibitedPred, Clause); 349 } 350 351 // Bind should have similar rules on a routine as gang/worker/vector/seq, 352 // except there is no 'must have 1' rule, so we can get all the checking done 353 // here. 354 bool 355 CheckValidRoutineBindNewClause(SemaOpenACC::OpenACCParsedClause &Clause) { 356 357 if (Clause.getClauseKind() != OpenACCClauseKind::Bind) 358 return false; 359 360 auto HasBindPred = llvm::IsaPred<OpenACCBindClause>; 361 return CheckValidRoutineNewClauseHelper(HasBindPred, Clause); 362 } 363 364 // For 'tile' and 'collapse', only allow 1 per 'device_type'. 365 // Also applies to num_worker, num_gangs, vector_length, and async. 366 // This does introspection into the actual device-types to prevent duplicates 367 // across device types as well. 368 template <typename TheClauseTy> 369 bool DisallowSinceLastDeviceType(SemaOpenACC::OpenACCParsedClause &Clause) { 370 auto LastDeviceTypeItr = 371 std::find_if(ExistingClauses.rbegin(), ExistingClauses.rend(), 372 llvm::IsaPred<OpenACCDeviceTypeClause>); 373 374 auto LastSinceDevTy = 375 std::find_if(ExistingClauses.rbegin(), LastDeviceTypeItr, 376 llvm::IsaPred<TheClauseTy>); 377 378 // In this case there is a duplicate since the last device_type/lack of a 379 // device_type. Diagnose these as duplicates. 380 if (LastSinceDevTy != LastDeviceTypeItr) { 381 SemaRef.Diag(Clause.getBeginLoc(), 382 diag::err_acc_clause_since_last_device_type) 383 << Clause.getClauseKind() << Clause.getDirectiveKind() 384 << (LastDeviceTypeItr != ExistingClauses.rend()); 385 386 SemaRef.Diag((*LastSinceDevTy)->getBeginLoc(), 387 diag::note_acc_previous_clause_here) 388 << (*LastSinceDevTy)->getClauseKind(); 389 390 // Mention the last device_type as well. 391 if (LastDeviceTypeItr != ExistingClauses.rend()) 392 SemaRef.Diag((*LastDeviceTypeItr)->getBeginLoc(), 393 diag::note_acc_active_applies_clause_here) 394 << diag::ACCDeviceTypeApp::Active 395 << (*LastDeviceTypeItr)->getClauseKind(); 396 return true; 397 } 398 399 // If this isn't in a device_type, and we didn't diagnose that there are 400 // dupes above, just give up, no sense in searching for previous device_type 401 // regions as they don't exist. 402 if (LastDeviceTypeItr == ExistingClauses.rend()) 403 return false; 404 405 // The device-type that is active for us, so we can compare to the previous 406 // ones. 407 const auto &ActiveDeviceTypeClause = 408 cast<OpenACCDeviceTypeClause>(**LastDeviceTypeItr); 409 410 auto PrevDeviceTypeItr = LastDeviceTypeItr; 411 auto CurDevTypeItr = LastDeviceTypeItr; 412 413 while ((CurDevTypeItr = std::find_if( 414 std::next(PrevDeviceTypeItr), ExistingClauses.rend(), 415 llvm::IsaPred<OpenACCDeviceTypeClause>)) != 416 ExistingClauses.rend()) { 417 // At this point, we know that we have a region between two device_types, 418 // as specified by CurDevTypeItr and PrevDeviceTypeItr. 419 420 auto CurClauseKindItr = std::find_if(PrevDeviceTypeItr, CurDevTypeItr, 421 llvm::IsaPred<TheClauseTy>); 422 423 // There are no clauses of the current kind between these device_types, so 424 // continue. 425 if (CurClauseKindItr == CurDevTypeItr) { 426 PrevDeviceTypeItr = CurDevTypeItr; 427 continue; 428 } 429 430 // At this point, we know that this device_type region has a collapse. So 431 // diagnose if the two device_types have any overlap in their 432 // architectures. 433 const auto &CurDeviceTypeClause = 434 cast<OpenACCDeviceTypeClause>(**CurDevTypeItr); 435 436 for (const DeviceTypeArgument &arg : 437 ActiveDeviceTypeClause.getArchitectures()) { 438 for (const DeviceTypeArgument &prevArg : 439 CurDeviceTypeClause.getArchitectures()) { 440 441 // This should catch duplicates * regions, duplicate same-text (thanks 442 // to identifier equiv.) and case insensitive dupes. 443 if (arg.getIdentifierInfo() == prevArg.getIdentifierInfo() || 444 (arg.getIdentifierInfo() && prevArg.getIdentifierInfo() && 445 StringRef{arg.getIdentifierInfo()->getName()}.equals_insensitive( 446 prevArg.getIdentifierInfo()->getName()))) { 447 SemaRef.Diag(Clause.getBeginLoc(), 448 diag::err_acc_clause_conflicts_prev_dev_type) 449 << Clause.getClauseKind() 450 << (arg.getIdentifierInfo() ? arg.getIdentifierInfo()->getName() 451 : "*"); 452 // mention the active device type. 453 SemaRef.Diag(ActiveDeviceTypeClause.getBeginLoc(), 454 diag::note_acc_active_applies_clause_here) 455 << diag::ACCDeviceTypeApp::Active 456 << ActiveDeviceTypeClause.getClauseKind(); 457 // mention the previous clause. 458 SemaRef.Diag((*CurClauseKindItr)->getBeginLoc(), 459 diag::note_acc_previous_clause_here) 460 << (*CurClauseKindItr)->getClauseKind(); 461 // mention the previous device type. 462 SemaRef.Diag(CurDeviceTypeClause.getBeginLoc(), 463 diag::note_acc_active_applies_clause_here) 464 << diag::ACCDeviceTypeApp::Applies 465 << CurDeviceTypeClause.getClauseKind(); 466 return true; 467 } 468 } 469 } 470 471 PrevDeviceTypeItr = CurDevTypeItr; 472 } 473 return false; 474 } 475 476 public: 477 SemaOpenACCClauseVisitor(SemaOpenACC &S, 478 ArrayRef<const OpenACCClause *> ExistingClauses) 479 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {} 480 481 OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) { 482 483 if (SemaRef.DiagnoseAllowedOnceClauses( 484 Clause.getDirectiveKind(), Clause.getClauseKind(), 485 Clause.getBeginLoc(), ExistingClauses) || 486 SemaRef.DiagnoseExclusiveClauses(Clause.getDirectiveKind(), 487 Clause.getClauseKind(), 488 Clause.getBeginLoc(), ExistingClauses)) 489 return nullptr; 490 if (CheckValidRoutineGangWorkerVectorSeqNewClause(Clause) || 491 CheckValidRoutineBindNewClause(Clause)) 492 return nullptr; 493 494 switch (Clause.getClauseKind()) { 495 case OpenACCClauseKind::Shortloop: 496 llvm_unreachable("Shortloop shouldn't be generated in clang"); 497 case OpenACCClauseKind::Invalid: 498 return nullptr; 499 #define VISIT_CLAUSE(CLAUSE_NAME) \ 500 case OpenACCClauseKind::CLAUSE_NAME: \ 501 return Visit##CLAUSE_NAME##Clause(Clause); 502 #define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \ 503 case OpenACCClauseKind::ALIAS: \ 504 if (DEPRECATED) \ 505 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \ 506 << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \ 507 return Visit##CLAUSE_NAME##Clause(Clause); 508 #include "clang/Basic/OpenACCClauses.def" 509 } 510 llvm_unreachable("Invalid clause kind"); 511 } 512 513 #define VISIT_CLAUSE(CLAUSE_NAME) \ 514 OpenACCClause *Visit##CLAUSE_NAME##Clause( \ 515 SemaOpenACC::OpenACCParsedClause &Clause); 516 #include "clang/Basic/OpenACCClauses.def" 517 }; 518 519 OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause( 520 SemaOpenACC::OpenACCParsedClause &Clause) { 521 // Don't add an invalid clause to the AST. 522 if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid) 523 return nullptr; 524 525 return OpenACCDefaultClause::Create( 526 Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(), 527 Clause.getLParenLoc(), Clause.getEndLoc()); 528 } 529 530 OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause( 531 SemaOpenACC::OpenACCParsedClause &Clause) { 532 533 if (DisallowSinceLastDeviceType<OpenACCTileClause>(Clause)) 534 return nullptr; 535 536 llvm::SmallVector<Expr *> NewSizeExprs; 537 538 // Make sure these are all positive constant expressions or *. 539 for (Expr *E : Clause.getIntExprs()) { 540 ExprResult Res = SemaRef.CheckTileSizeExpr(E); 541 542 if (!Res.isUsable()) 543 return nullptr; 544 545 NewSizeExprs.push_back(Res.get()); 546 } 547 548 return OpenACCTileClause::Create(Ctx, Clause.getBeginLoc(), 549 Clause.getLParenLoc(), NewSizeExprs, 550 Clause.getEndLoc()); 551 } 552 553 OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause( 554 SemaOpenACC::OpenACCParsedClause &Clause) { 555 556 // The parser has ensured that we have a proper condition expr, so there 557 // isn't really much to do here. 558 559 // If the 'if' clause is true, it makes the 'self' clause have no effect, 560 // diagnose that here. This only applies on compute/combined constructs. 561 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) { 562 const auto *Itr = 563 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>); 564 if (Itr != ExistingClauses.end()) { 565 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); 566 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here) 567 << (*Itr)->getClauseKind(); 568 } 569 } 570 571 return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(), 572 Clause.getLParenLoc(), 573 Clause.getConditionExpr(), Clause.getEndLoc()); 574 } 575 576 OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause( 577 SemaOpenACC::OpenACCParsedClause &Clause) { 578 579 // If the 'if' clause is true, it makes the 'self' clause have no effect, 580 // diagnose that here. This only applies on compute/combined constructs. 581 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update) 582 return OpenACCSelfClause::Create(Ctx, Clause.getBeginLoc(), 583 Clause.getLParenLoc(), Clause.getVarList(), 584 Clause.getEndLoc()); 585 586 const auto *Itr = 587 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>); 588 if (Itr != ExistingClauses.end()) { 589 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); 590 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here) 591 << (*Itr)->getClauseKind(); 592 } 593 return OpenACCSelfClause::Create( 594 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 595 Clause.getConditionExpr(), Clause.getEndLoc()); 596 } 597 598 OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause( 599 SemaOpenACC::OpenACCParsedClause &Clause) { 600 601 if (DisallowSinceLastDeviceType<OpenACCNumGangsClause>(Clause)) 602 return nullptr; 603 604 // num_gangs requires at least 1 int expr in all forms. Diagnose here, but 605 // allow us to continue, an empty clause might be useful for future 606 // diagnostics. 607 if (Clause.getIntExprs().empty()) 608 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) 609 << /*NoArgs=*/0; 610 611 unsigned MaxArgs = 612 (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || 613 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) 614 ? 3 615 : 1; 616 // The max number of args differs between parallel and other constructs. 617 // Again, allow us to continue for the purposes of future diagnostics. 618 if (Clause.getIntExprs().size() > MaxArgs) 619 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) 620 << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs 621 << Clause.getIntExprs().size(); 622 623 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop 624 // directive that has a gang clause and is within a compute construct that has 625 // a num_gangs clause with more than one explicit argument. 626 if (Clause.getIntExprs().size() > 1 && 627 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 628 auto *GangClauseItr = 629 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 630 auto *ReductionClauseItr = 631 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 632 633 if (GangClauseItr != ExistingClauses.end() && 634 ReductionClauseItr != ExistingClauses.end()) { 635 SemaRef.Diag(Clause.getBeginLoc(), 636 diag::err_acc_gang_reduction_numgangs_conflict) 637 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang 638 << Clause.getDirectiveKind() << /*is on combined directive=*/1; 639 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(), 640 diag::note_acc_previous_clause_here) 641 << (*ReductionClauseItr)->getClauseKind(); 642 SemaRef.Diag((*GangClauseItr)->getBeginLoc(), 643 diag::note_acc_previous_clause_here) 644 << (*GangClauseItr)->getClauseKind(); 645 return nullptr; 646 } 647 } 648 649 // OpenACC 3.3 Section 2.5.4: 650 // A reduction clause may not appear on a parallel construct with a 651 // num_gangs clause that has more than one argument. 652 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || 653 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) && 654 Clause.getIntExprs().size() > 1) { 655 auto *Parallel = 656 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 657 658 if (Parallel != ExistingClauses.end()) { 659 SemaRef.Diag(Clause.getBeginLoc(), 660 diag::err_acc_reduction_num_gangs_conflict) 661 << /*>1 arg in first loc=*/1 << Clause.getClauseKind() 662 << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction; 663 SemaRef.Diag((*Parallel)->getBeginLoc(), 664 diag::note_acc_previous_clause_here) 665 << (*Parallel)->getClauseKind(); 666 return nullptr; 667 } 668 } 669 670 // OpenACC 3.3 Section 2.9.2: 671 // An argument with no keyword or with the 'num' keyword is allowed only when 672 // the 'num_gangs' does not appear on the 'kernel' construct. 673 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { 674 auto GangClauses = llvm::make_filter_range( 675 ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 676 677 for (auto *GC : GangClauses) { 678 if (cast<OpenACCGangClause>(GC)->hasExprOfKind(OpenACCGangKind::Num)) { 679 SemaRef.Diag(Clause.getBeginLoc(), 680 diag::err_acc_num_arg_conflict_reverse) 681 << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang 682 << /*Num argument*/ 1; 683 SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here) 684 << GC->getClauseKind(); 685 return nullptr; 686 } 687 } 688 } 689 690 return OpenACCNumGangsClause::Create( 691 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(), 692 Clause.getEndLoc()); 693 } 694 695 OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause( 696 SemaOpenACC::OpenACCParsedClause &Clause) { 697 698 if (DisallowSinceLastDeviceType<OpenACCNumWorkersClause>(Clause)) 699 return nullptr; 700 701 // OpenACC 3.3 Section 2.9.2: 702 // An argument is allowed only when the 'num_workers' does not appear on the 703 // kernels construct. 704 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { 705 auto WorkerClauses = llvm::make_filter_range( 706 ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>); 707 708 for (auto *WC : WorkerClauses) { 709 if (cast<OpenACCWorkerClause>(WC)->hasIntExpr()) { 710 SemaRef.Diag(Clause.getBeginLoc(), 711 diag::err_acc_num_arg_conflict_reverse) 712 << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker 713 << /*num argument*/ 0; 714 SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here) 715 << WC->getClauseKind(); 716 return nullptr; 717 } 718 } 719 } 720 721 assert(Clause.getIntExprs().size() == 1 && 722 "Invalid number of expressions for NumWorkers"); 723 return OpenACCNumWorkersClause::Create( 724 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 725 Clause.getEndLoc()); 726 } 727 728 OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause( 729 SemaOpenACC::OpenACCParsedClause &Clause) { 730 731 if (DisallowSinceLastDeviceType<OpenACCVectorLengthClause>(Clause)) 732 return nullptr; 733 734 // OpenACC 3.3 Section 2.9.4: 735 // An argument is allowed only when the 'vector_length' does not appear on the 736 // 'kernels' construct. 737 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { 738 auto VectorClauses = llvm::make_filter_range( 739 ExistingClauses, llvm::IsaPred<OpenACCVectorClause>); 740 741 for (auto *VC : VectorClauses) { 742 if (cast<OpenACCVectorClause>(VC)->hasIntExpr()) { 743 SemaRef.Diag(Clause.getBeginLoc(), 744 diag::err_acc_num_arg_conflict_reverse) 745 << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector 746 << /*num argument*/ 0; 747 SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here) 748 << VC->getClauseKind(); 749 return nullptr; 750 } 751 } 752 } 753 754 assert(Clause.getIntExprs().size() == 1 && 755 "Invalid number of expressions for NumWorkers"); 756 return OpenACCVectorLengthClause::Create( 757 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 758 Clause.getEndLoc()); 759 } 760 761 OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause( 762 SemaOpenACC::OpenACCParsedClause &Clause) { 763 if (DisallowSinceLastDeviceType<OpenACCAsyncClause>(Clause)) 764 return nullptr; 765 766 assert(Clause.getNumIntExprs() < 2 && 767 "Invalid number of expressions for Async"); 768 return OpenACCAsyncClause::Create( 769 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 770 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr, 771 Clause.getEndLoc()); 772 } 773 774 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause( 775 SemaOpenACC::OpenACCParsedClause &Clause) { 776 assert(Clause.getNumIntExprs() == 1 && 777 "Invalid number of expressions for device_num"); 778 return OpenACCDeviceNumClause::Create( 779 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 780 Clause.getEndLoc()); 781 } 782 783 OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause( 784 SemaOpenACC::OpenACCParsedClause &Clause) { 785 assert(Clause.getNumIntExprs() == 1 && 786 "Invalid number of expressions for default_async"); 787 return OpenACCDefaultAsyncClause::Create( 788 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 789 Clause.getEndLoc()); 790 } 791 792 OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause( 793 SemaOpenACC::OpenACCParsedClause &Clause) { 794 // ActOnVar ensured that everything is a valid variable reference, so there 795 // really isn't anything to do here. GCC does some duplicate-finding, though 796 // it isn't apparent in the standard where this is justified. 797 798 return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(), 799 Clause.getLParenLoc(), 800 Clause.getVarList(), Clause.getEndLoc()); 801 } 802 803 OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause( 804 SemaOpenACC::OpenACCParsedClause &Clause) { 805 // ActOnVar ensured that everything is a valid variable reference, so there 806 // really isn't anything to do here. GCC does some duplicate-finding, though 807 // it isn't apparent in the standard where this is justified. 808 809 return OpenACCFirstPrivateClause::Create( 810 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 811 Clause.getEndLoc()); 812 } 813 814 OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause( 815 SemaOpenACC::OpenACCParsedClause &Clause) { 816 // ActOnVar ensured that everything is a valid variable reference, so there 817 // really isn't anything to do here. GCC does some duplicate-finding, though 818 // it isn't apparent in the standard where this is justified. 819 820 return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(), 821 Clause.getLParenLoc(), 822 Clause.getVarList(), Clause.getEndLoc()); 823 } 824 825 OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause( 826 SemaOpenACC::OpenACCParsedClause &Clause) { 827 // ActOnVar ensured that everything is a valid variable reference, so there 828 // really isn't anything to do here. GCC does some duplicate-finding, though 829 // it isn't apparent in the standard where this is justified. 830 831 // 'declare' has some restrictions that need to be enforced separately, so 832 // check it here. 833 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid)) 834 return nullptr; 835 836 return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(), 837 Clause.getLParenLoc(), 838 Clause.getVarList(), Clause.getEndLoc()); 839 } 840 841 OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause( 842 SemaOpenACC::OpenACCParsedClause &Clause) { 843 // ActOnVar ensured that everything is a valid variable reference, so there 844 // really isn't anything to do here. GCC does some duplicate-finding, though 845 // it isn't apparent in the standard where this is justified. 846 847 return OpenACCHostClause::Create(Ctx, Clause.getBeginLoc(), 848 Clause.getLParenLoc(), Clause.getVarList(), 849 Clause.getEndLoc()); 850 } 851 852 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause( 853 SemaOpenACC::OpenACCParsedClause &Clause) { 854 // ActOnVar ensured that everything is a valid variable reference, so there 855 // really isn't anything to do here. GCC does some duplicate-finding, though 856 // it isn't apparent in the standard where this is justified. 857 858 return OpenACCDeviceClause::Create(Ctx, Clause.getBeginLoc(), 859 Clause.getLParenLoc(), Clause.getVarList(), 860 Clause.getEndLoc()); 861 } 862 863 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause( 864 SemaOpenACC::OpenACCParsedClause &Clause) { 865 // ActOnVar ensured that everything is a valid variable reference, so there 866 // really isn't anything to do here. GCC does some duplicate-finding, though 867 // it isn't apparent in the standard where this is justified. 868 869 OpenACCModifierKind NewMods = 870 CheckModifierList(Clause, Clause.getModifierList()); 871 872 // 'declare' has some restrictions that need to be enforced separately, so 873 // check it here. 874 if (SemaRef.CheckDeclareClause(Clause, NewMods)) 875 return nullptr; 876 877 return OpenACCCopyClause::Create( 878 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 879 Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc()); 880 } 881 882 OpenACCClause *SemaOpenACCClauseVisitor::VisitLinkClause( 883 SemaOpenACC::OpenACCParsedClause &Clause) { 884 // 'declare' has some restrictions that need to be enforced separately, so 885 // check it here. 886 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid)) 887 return nullptr; 888 889 Clause.setVarListDetails(SemaRef.CheckLinkClauseVarList(Clause.getVarList()), 890 OpenACCModifierKind::Invalid); 891 892 return OpenACCLinkClause::Create(Ctx, Clause.getBeginLoc(), 893 Clause.getLParenLoc(), Clause.getVarList(), 894 Clause.getEndLoc()); 895 } 896 897 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceResidentClause( 898 SemaOpenACC::OpenACCParsedClause &Clause) { 899 // 'declare' has some restrictions that need to be enforced separately, so 900 // check it here. 901 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid)) 902 return nullptr; 903 904 return OpenACCDeviceResidentClause::Create( 905 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 906 Clause.getEndLoc()); 907 } 908 909 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause( 910 SemaOpenACC::OpenACCParsedClause &Clause) { 911 // ActOnVar ensured that everything is a valid variable reference, so there 912 // really isn't anything to do here. GCC does some duplicate-finding, though 913 // it isn't apparent in the standard where this is justified. 914 915 OpenACCModifierKind NewMods = 916 CheckModifierList(Clause, Clause.getModifierList()); 917 918 // 'declare' has some restrictions that need to be enforced separately, so 919 // check it here. 920 if (SemaRef.CheckDeclareClause(Clause, NewMods)) 921 return nullptr; 922 923 return OpenACCCopyInClause::Create( 924 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 925 Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc()); 926 } 927 928 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause( 929 SemaOpenACC::OpenACCParsedClause &Clause) { 930 // ActOnVar ensured that everything is a valid variable reference, so there 931 // really isn't anything to do here. GCC does some duplicate-finding, though 932 // it isn't apparent in the standard where this is justified. 933 934 OpenACCModifierKind NewMods = 935 CheckModifierList(Clause, Clause.getModifierList()); 936 937 // 'declare' has some restrictions that need to be enforced separately, so 938 // check it here. 939 if (SemaRef.CheckDeclareClause(Clause, NewMods)) 940 return nullptr; 941 942 return OpenACCCopyOutClause::Create( 943 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 944 Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc()); 945 } 946 947 OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause( 948 SemaOpenACC::OpenACCParsedClause &Clause) { 949 // ActOnVar ensured that everything is a valid variable reference, so there 950 // really isn't anything to do here. GCC does some duplicate-finding, though 951 // it isn't apparent in the standard where this is justified. 952 953 OpenACCModifierKind NewMods = 954 CheckModifierList(Clause, Clause.getModifierList()); 955 956 // 'declare' has some restrictions that need to be enforced separately, so 957 // check it here. 958 if (SemaRef.CheckDeclareClause(Clause, NewMods)) 959 return nullptr; 960 961 return OpenACCCreateClause::Create( 962 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 963 Clause.getModifierList(), Clause.getVarList(), Clause.getEndLoc()); 964 } 965 966 OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause( 967 SemaOpenACC::OpenACCParsedClause &Clause) { 968 // ActOnVar ensured that everything is a valid variable reference, but we 969 // still have to make sure it is a pointer type. 970 llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 971 llvm::erase_if(VarList, [&](Expr *E) { 972 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E); 973 }); 974 Clause.setVarListDetails(VarList, OpenACCModifierKind::Invalid); 975 return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(), 976 Clause.getLParenLoc(), Clause.getVarList(), 977 Clause.getEndLoc()); 978 } 979 980 OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause( 981 SemaOpenACC::OpenACCParsedClause &Clause) { 982 // ActOnVar ensured that everything is a valid variable reference, but we 983 // still have to make sure it is a pointer type. 984 llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 985 llvm::erase_if(VarList, [&](Expr *E) { 986 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E); 987 }); 988 Clause.setVarListDetails(VarList, OpenACCModifierKind::Invalid); 989 return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(), 990 Clause.getLParenLoc(), Clause.getVarList(), 991 Clause.getEndLoc()); 992 } 993 994 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause( 995 SemaOpenACC::OpenACCParsedClause &Clause) { 996 // ActOnVar ensured that everything is a valid variable reference, so there 997 // really isn't anything to do here. GCC does some duplicate-finding, though 998 // it isn't apparent in the standard where this is justified. 999 return OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(), 1000 Clause.getLParenLoc(), Clause.getVarList(), 1001 Clause.getEndLoc()); 1002 } 1003 1004 OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause( 1005 SemaOpenACC::OpenACCParsedClause &Clause) { 1006 // ActOnVar ensured that everything is a valid variable or array, so nothing 1007 // left to do here. 1008 return OpenACCUseDeviceClause::Create( 1009 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 1010 Clause.getEndLoc()); 1011 } 1012 1013 OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause( 1014 SemaOpenACC::OpenACCParsedClause &Clause) { 1015 // ActOnVar ensured that everything is a valid variable reference, but we 1016 // still have to make sure it is a pointer type. 1017 llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 1018 llvm::erase_if(VarList, [&](Expr *E) { 1019 return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E); 1020 }); 1021 Clause.setVarListDetails(VarList, OpenACCModifierKind::Invalid); 1022 1023 // 'declare' has some restrictions that need to be enforced separately, so 1024 // check it here. 1025 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid)) 1026 return nullptr; 1027 1028 return OpenACCDevicePtrClause::Create( 1029 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 1030 Clause.getEndLoc()); 1031 } 1032 1033 OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause( 1034 SemaOpenACC::OpenACCParsedClause &Clause) { 1035 return OpenACCWaitClause::Create( 1036 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(), 1037 Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc()); 1038 } 1039 1040 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause( 1041 SemaOpenACC::OpenACCParsedClause &Clause) { 1042 1043 // Based on discussions, having more than 1 'architecture' on a 'set' is 1044 // nonsensical, so we're going to fix the standard to reflect this. Implement 1045 // the limitation, since the Dialect requires this. 1046 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set && 1047 Clause.getDeviceTypeArchitectures().size() > 1) { 1048 SemaRef.Diag(Clause.getDeviceTypeArchitectures()[1].getLoc(), 1049 diag::err_acc_device_type_multiple_archs); 1050 return nullptr; 1051 } 1052 1053 // The list of valid device_type values. Flang also has these hardcoded in 1054 // openacc_parsers.cpp, as there does not seem to be a reliable backend 1055 // source. The list below is sourced from Flang, though NVC++ supports only 1056 // 'nvidia', 'host', 'multicore', and 'default'. 1057 const std::array<llvm::StringLiteral, 6> ValidValues{ 1058 "default", "nvidia", "acc_device_nvidia", "radeon", "host", "multicore"}; 1059 // As an optimization, we have a manually maintained list of valid values 1060 // below, rather than trying to calculate from above. These should be kept in 1061 // sync if/when the above list ever changes. 1062 std::string ValidValuesString = 1063 "'default', 'nvidia', 'acc_device_nvidia', 'radeon', 'host', 'multicore'"; 1064 1065 llvm::SmallVector<DeviceTypeArgument> Architectures{ 1066 Clause.getDeviceTypeArchitectures()}; 1067 1068 // The parser has ensured that we either have a single entry of just '*' 1069 // (represented by a nullptr IdentifierInfo), or a list. 1070 1071 bool Diagnosed = false; 1072 auto FilterPred = [&](const DeviceTypeArgument &Arch) { 1073 // The '*' case. 1074 if (!Arch.getIdentifierInfo()) 1075 return false; 1076 return llvm::find_if(ValidValues, [&](StringRef RHS) { 1077 return Arch.getIdentifierInfo()->getName().equals_insensitive(RHS); 1078 }) == ValidValues.end(); 1079 }; 1080 1081 auto Diagnose = [&](const DeviceTypeArgument &Arch) { 1082 Diagnosed = SemaRef.Diag(Arch.getLoc(), diag::err_acc_invalid_default_type) 1083 << Arch.getIdentifierInfo() << Clause.getClauseKind() 1084 << ValidValuesString; 1085 }; 1086 1087 // There aren't stable enumertor versions of 'for-each-then-erase', so do it 1088 // here. We DO keep track of whether we diagnosed something to make sure we 1089 // don't do the 'erase_if' in the event that the first list didn't find 1090 // anything. 1091 llvm::for_each(llvm::make_filter_range(Architectures, FilterPred), Diagnose); 1092 if (Diagnosed) 1093 llvm::erase_if(Architectures, FilterPred); 1094 1095 return OpenACCDeviceTypeClause::Create( 1096 Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 1097 Architectures, Clause.getEndLoc()); 1098 } 1099 1100 OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause( 1101 SemaOpenACC::OpenACCParsedClause &Clause) { 1102 1103 return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(), 1104 Clause.getEndLoc()); 1105 } 1106 1107 OpenACCClause *SemaOpenACCClauseVisitor::VisitNoHostClause( 1108 SemaOpenACC::OpenACCParsedClause &Clause) { 1109 return OpenACCNoHostClause::Create(Ctx, Clause.getBeginLoc(), 1110 Clause.getEndLoc()); 1111 } 1112 1113 OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause( 1114 SemaOpenACC::OpenACCParsedClause &Clause) { 1115 1116 return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(), 1117 Clause.getEndLoc()); 1118 } 1119 1120 ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) { 1121 if (isa<OpenACCAsteriskSizeExpr>(E)) 1122 return E; 1123 return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, 1124 E->getBeginLoc(), E); 1125 } 1126 1127 bool IsOrphanLoop(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) { 1128 return DK == OpenACCDirectiveKind::Loop && 1129 AssocKind == OpenACCDirectiveKind::Invalid; 1130 } 1131 1132 bool HasAssocKind(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) { 1133 return DK == OpenACCDirectiveKind::Loop && 1134 AssocKind != OpenACCDirectiveKind::Invalid; 1135 } 1136 1137 ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK, 1138 OpenACCClauseKind CK, OpenACCDirectiveKind DK, 1139 OpenACCDirectiveKind AssocKind) { 1140 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) 1141 << GK << CK << IsOrphanLoop(DK, AssocKind) << DK 1142 << HasAssocKind(DK, AssocKind) << AssocKind; 1143 return ExprError(); 1144 } 1145 ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind, 1146 OpenACCClauseKind CK, OpenACCDirectiveKind DK, 1147 OpenACCDirectiveKind AssocKind) { 1148 S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) 1149 << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK 1150 << HasAssocKind(DK, AssocKind) << AssocKind; 1151 return ExprError(); 1152 } 1153 1154 ExprResult CheckGangDimExpr(SemaOpenACC &S, Expr *E) { 1155 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel 1156 // construct, or an orphaned loop construct, the gang clause behaves as 1157 // follows. ... The dim argument must be a constant positive integer value 1158 // 1, 2, or 3. 1159 // -also- 1160 // OpenACC 3.3 2.15: The 'dim' argument must be a constant positive integer 1161 // with value 1, 2, or 3. 1162 if (!E) 1163 return ExprError(); 1164 ExprResult Res = S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, 1165 OpenACCClauseKind::Gang, E->getBeginLoc(), E); 1166 1167 if (!Res.isUsable()) 1168 return Res; 1169 1170 if (Res.get()->isInstantiationDependent()) 1171 return Res; 1172 1173 std::optional<llvm::APSInt> ICE = 1174 Res.get()->getIntegerConstantExpr(S.getASTContext()); 1175 1176 if (!ICE || *ICE <= 0 || ICE > 3) { 1177 S.Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value) 1178 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); 1179 return ExprError(); 1180 } 1181 1182 return ExprResult{ 1183 ConstantExpr::Create(S.getASTContext(), Res.get(), APValue{*ICE})}; 1184 } 1185 1186 ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK, 1187 OpenACCDirectiveKind AssocKind, 1188 OpenACCGangKind GK, Expr *E) { 1189 switch (GK) { 1190 case OpenACCGangKind::Static: 1191 return CheckGangStaticExpr(S, E); 1192 case OpenACCGangKind::Num: 1193 // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel 1194 // construct, or an orphaned loop construct, the gang clause behaves as 1195 // follows. ... The num argument is not allowed. 1196 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); 1197 case OpenACCGangKind::Dim: 1198 return CheckGangDimExpr(S, E); 1199 } 1200 llvm_unreachable("Unknown gang kind in gang parallel check"); 1201 } 1202 1203 ExprResult CheckGangKernelsExpr(SemaOpenACC &S, 1204 ArrayRef<const OpenACCClause *> ExistingClauses, 1205 OpenACCDirectiveKind DK, 1206 OpenACCDirectiveKind AssocKind, 1207 OpenACCGangKind GK, Expr *E) { 1208 switch (GK) { 1209 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 1210 // construct, the gang clause behaves as follows. ... The dim argument is 1211 // not allowed. 1212 case OpenACCGangKind::Dim: 1213 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); 1214 case OpenACCGangKind::Num: { 1215 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 1216 // construct, the gang clause behaves as follows. ... An argument with no 1217 // keyword or with num keyword is only allowed when num_gangs does not 1218 // appear on the kernels construct. ... The region of a loop with the gang 1219 // clause may not contain another loop with a gang clause unless within a 1220 // nested compute region. 1221 1222 // If this is a 'combined' construct, search the list of existing clauses. 1223 // Else we need to search the containing 'kernel'. 1224 auto Collection = isOpenACCCombinedDirectiveKind(DK) 1225 ? ExistingClauses 1226 : S.getActiveComputeConstructInfo().Clauses; 1227 1228 const auto *Itr = 1229 llvm::find_if(Collection, llvm::IsaPred<OpenACCNumGangsClause>); 1230 1231 if (Itr != Collection.end()) { 1232 S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict) 1233 << "num" << OpenACCClauseKind::Gang << DK 1234 << HasAssocKind(DK, AssocKind) << AssocKind 1235 << OpenACCClauseKind::NumGangs; 1236 1237 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here) 1238 << (*Itr)->getClauseKind(); 1239 return ExprError(); 1240 } 1241 return ExprResult{E}; 1242 } 1243 case OpenACCGangKind::Static: 1244 return CheckGangStaticExpr(S, E); 1245 } 1246 llvm_unreachable("Unknown gang kind in gang kernels check"); 1247 } 1248 1249 ExprResult CheckGangSerialExpr(SemaOpenACC &S, OpenACCDirectiveKind DK, 1250 OpenACCDirectiveKind AssocKind, 1251 OpenACCGangKind GK, Expr *E) { 1252 switch (GK) { 1253 // 'dim' and 'num' don't really make sense on serial, and GCC rejects them 1254 // too, so we disallow them too. 1255 case OpenACCGangKind::Dim: 1256 case OpenACCGangKind::Num: 1257 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); 1258 case OpenACCGangKind::Static: 1259 return CheckGangStaticExpr(S, E); 1260 } 1261 llvm_unreachable("Unknown gang kind in gang serial check"); 1262 } 1263 1264 ExprResult CheckGangRoutineExpr(SemaOpenACC &S, OpenACCDirectiveKind DK, 1265 OpenACCDirectiveKind AssocKind, 1266 OpenACCGangKind GK, Expr *E) { 1267 switch (GK) { 1268 // Only 'dim' is allowed on a routine, so diallow num and static. 1269 case OpenACCGangKind::Num: 1270 case OpenACCGangKind::Static: 1271 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); 1272 case OpenACCGangKind::Dim: 1273 return CheckGangDimExpr(S, E); 1274 } 1275 llvm_unreachable("Unknown gang kind in gang serial check"); 1276 } 1277 1278 OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause( 1279 SemaOpenACC::OpenACCParsedClause &Clause) { 1280 if (DiagGangWorkerVectorSeqConflict(Clause)) 1281 return nullptr; 1282 1283 Expr *IntExpr = 1284 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr; 1285 if (IntExpr) { 1286 switch (Clause.getDirectiveKind()) { 1287 default: 1288 llvm_unreachable("Invalid directive kind for this clause"); 1289 case OpenACCDirectiveKind::Loop: 1290 switch (SemaRef.getActiveComputeConstructInfo().Kind) { 1291 case OpenACCDirectiveKind::Invalid: 1292 case OpenACCDirectiveKind::Parallel: 1293 case OpenACCDirectiveKind::ParallelLoop: 1294 // No restriction on when 'parallel' can contain an argument. 1295 break; 1296 case OpenACCDirectiveKind::Serial: 1297 case OpenACCDirectiveKind::SerialLoop: 1298 // GCC disallows this, and there is no real good reason for us to permit 1299 // it, so disallow until we come up with a use case that makes sense. 1300 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector, 1301 Clause.getDirectiveKind(), 1302 SemaRef.getActiveComputeConstructInfo().Kind); 1303 IntExpr = nullptr; 1304 break; 1305 case OpenACCDirectiveKind::Kernels: 1306 case OpenACCDirectiveKind::KernelsLoop: { 1307 const auto *Itr = 1308 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, 1309 llvm::IsaPred<OpenACCVectorLengthClause>); 1310 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { 1311 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1312 << "length" << OpenACCClauseKind::Vector 1313 << Clause.getDirectiveKind() 1314 << HasAssocKind(Clause.getDirectiveKind(), 1315 SemaRef.getActiveComputeConstructInfo().Kind) 1316 << SemaRef.getActiveComputeConstructInfo().Kind 1317 << OpenACCClauseKind::VectorLength; 1318 SemaRef.Diag((*Itr)->getBeginLoc(), 1319 diag::note_acc_previous_clause_here) 1320 << (*Itr)->getClauseKind(); 1321 1322 IntExpr = nullptr; 1323 } 1324 break; 1325 } 1326 default: 1327 llvm_unreachable("Non compute construct in active compute construct"); 1328 } 1329 break; 1330 case OpenACCDirectiveKind::KernelsLoop: { 1331 const auto *Itr = llvm::find_if(ExistingClauses, 1332 llvm::IsaPred<OpenACCVectorLengthClause>); 1333 if (Itr != ExistingClauses.end()) { 1334 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1335 << "length" << OpenACCClauseKind::Vector 1336 << Clause.getDirectiveKind() 1337 << HasAssocKind(Clause.getDirectiveKind(), 1338 SemaRef.getActiveComputeConstructInfo().Kind) 1339 << SemaRef.getActiveComputeConstructInfo().Kind 1340 << OpenACCClauseKind::VectorLength; 1341 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here) 1342 << (*Itr)->getClauseKind(); 1343 1344 IntExpr = nullptr; 1345 } 1346 break; 1347 } 1348 case OpenACCDirectiveKind::SerialLoop: 1349 case OpenACCDirectiveKind::Routine: 1350 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector, 1351 Clause.getDirectiveKind(), 1352 SemaRef.getActiveComputeConstructInfo().Kind); 1353 IntExpr = nullptr; 1354 break; 1355 case OpenACCDirectiveKind::ParallelLoop: 1356 break; 1357 case OpenACCDirectiveKind::Invalid: 1358 // This can happen when the directive was not recognized, but we continued 1359 // anyway. Since there is a lot of stuff that can happen (including 1360 // 'allow anything' in the parallel loop case), just skip all checking and 1361 // continue. 1362 break; 1363 } 1364 } 1365 1366 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop) { 1367 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not 1368 // contain a loop with a gang, worker, or vector clause unless within a 1369 // nested compute region. 1370 if (SemaRef.LoopVectorClauseLoc.isValid()) { 1371 // This handles the 'inner loop' diagnostic, but we cannot set that we're 1372 // on one of these until we get to the end of the construct. 1373 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1374 << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector 1375 << /*skip kernels construct info*/ 0; 1376 SemaRef.Diag(SemaRef.LoopVectorClauseLoc, 1377 diag::note_acc_previous_clause_here) 1378 << "vector"; 1379 return nullptr; 1380 } 1381 } 1382 1383 return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(), 1384 Clause.getLParenLoc(), IntExpr, 1385 Clause.getEndLoc()); 1386 } 1387 1388 OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause( 1389 SemaOpenACC::OpenACCParsedClause &Clause) { 1390 if (DiagGangWorkerVectorSeqConflict(Clause)) 1391 return nullptr; 1392 1393 Expr *IntExpr = 1394 Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr; 1395 1396 if (IntExpr) { 1397 switch (Clause.getDirectiveKind()) { 1398 default: 1399 llvm_unreachable("Invalid directive kind for this clause"); 1400 case OpenACCDirectiveKind::Invalid: 1401 // This can happen in cases where the directive was not recognized but we 1402 // continued anyway. Kernels allows kind of any integer argument, so we 1403 // can assume it is that (rather than marking the argument invalid like 1404 // with parallel/serial/routine), and just continue as if nothing 1405 // happened. We'll skip the 'kernels' checking vs num-workers, since this 1406 // MIGHT be something else. 1407 break; 1408 case OpenACCDirectiveKind::Loop: 1409 switch (SemaRef.getActiveComputeConstructInfo().Kind) { 1410 case OpenACCDirectiveKind::Invalid: 1411 case OpenACCDirectiveKind::ParallelLoop: 1412 case OpenACCDirectiveKind::SerialLoop: 1413 case OpenACCDirectiveKind::Parallel: 1414 case OpenACCDirectiveKind::Serial: 1415 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num, 1416 OpenACCClauseKind::Worker, Clause.getDirectiveKind(), 1417 SemaRef.getActiveComputeConstructInfo().Kind); 1418 IntExpr = nullptr; 1419 break; 1420 case OpenACCDirectiveKind::KernelsLoop: 1421 case OpenACCDirectiveKind::Kernels: { 1422 const auto *Itr = 1423 llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, 1424 llvm::IsaPred<OpenACCNumWorkersClause>); 1425 if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { 1426 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1427 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind() 1428 << HasAssocKind(Clause.getDirectiveKind(), 1429 SemaRef.getActiveComputeConstructInfo().Kind) 1430 << SemaRef.getActiveComputeConstructInfo().Kind 1431 << OpenACCClauseKind::NumWorkers; 1432 SemaRef.Diag((*Itr)->getBeginLoc(), 1433 diag::note_acc_previous_clause_here) 1434 << (*Itr)->getClauseKind(); 1435 1436 IntExpr = nullptr; 1437 } 1438 break; 1439 } 1440 default: 1441 llvm_unreachable("Non compute construct in active compute construct"); 1442 } 1443 break; 1444 case OpenACCDirectiveKind::ParallelLoop: 1445 case OpenACCDirectiveKind::SerialLoop: 1446 case OpenACCDirectiveKind::Routine: 1447 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num, 1448 OpenACCClauseKind::Worker, Clause.getDirectiveKind(), 1449 SemaRef.getActiveComputeConstructInfo().Kind); 1450 IntExpr = nullptr; 1451 break; 1452 case OpenACCDirectiveKind::KernelsLoop: { 1453 const auto *Itr = llvm::find_if(ExistingClauses, 1454 llvm::IsaPred<OpenACCNumWorkersClause>); 1455 if (Itr != ExistingClauses.end()) { 1456 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1457 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind() 1458 << HasAssocKind(Clause.getDirectiveKind(), 1459 SemaRef.getActiveComputeConstructInfo().Kind) 1460 << SemaRef.getActiveComputeConstructInfo().Kind 1461 << OpenACCClauseKind::NumWorkers; 1462 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here) 1463 << (*Itr)->getClauseKind(); 1464 1465 IntExpr = nullptr; 1466 } 1467 } 1468 } 1469 } 1470 1471 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop) { 1472 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not 1473 // contain a loop with a gang or worker clause unless within a nested 1474 // compute region. 1475 if (SemaRef.LoopWorkerClauseLoc.isValid()) { 1476 // This handles the 'inner loop' diagnostic, but we cannot set that we're 1477 // on one of these until we get to the end of the construct. 1478 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1479 << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker 1480 << /*skip kernels construct info*/ 0; 1481 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, 1482 diag::note_acc_previous_clause_here) 1483 << "worker"; 1484 return nullptr; 1485 } 1486 1487 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not 1488 // contain a loop with a gang, worker, or vector clause unless within a 1489 // nested compute region. 1490 if (SemaRef.LoopVectorClauseLoc.isValid()) { 1491 // This handles the 'inner loop' diagnostic, but we cannot set that we're 1492 // on one of these until we get to the end of the construct. 1493 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1494 << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector 1495 << /*skip kernels construct info*/ 0; 1496 SemaRef.Diag(SemaRef.LoopVectorClauseLoc, 1497 diag::note_acc_previous_clause_here) 1498 << "vector"; 1499 return nullptr; 1500 } 1501 } 1502 1503 return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(), 1504 Clause.getLParenLoc(), IntExpr, 1505 Clause.getEndLoc()); 1506 } 1507 1508 OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause( 1509 SemaOpenACC::OpenACCParsedClause &Clause) { 1510 1511 if (DiagGangWorkerVectorSeqConflict(Clause)) 1512 return nullptr; 1513 1514 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop 1515 // directive that has a gang clause and is within a compute construct that has 1516 // a num_gangs clause with more than one explicit argument. 1517 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && 1518 SemaRef.getActiveComputeConstructInfo().Kind != 1519 OpenACCDirectiveKind::Invalid) || 1520 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1521 // num_gangs clause on the active compute construct. 1522 auto ActiveComputeConstructContainer = 1523 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) 1524 ? ExistingClauses 1525 : SemaRef.getActiveComputeConstructInfo().Clauses; 1526 auto *NumGangsClauseItr = llvm::find_if( 1527 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>); 1528 1529 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() && 1530 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() > 1531 1) { 1532 auto *ReductionClauseItr = 1533 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 1534 1535 if (ReductionClauseItr != ExistingClauses.end()) { 1536 SemaRef.Diag(Clause.getBeginLoc(), 1537 diag::err_acc_gang_reduction_numgangs_conflict) 1538 << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction 1539 << Clause.getDirectiveKind() 1540 << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()); 1541 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(), 1542 diag::note_acc_previous_clause_here) 1543 << (*ReductionClauseItr)->getClauseKind(); 1544 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), 1545 diag::note_acc_previous_clause_here) 1546 << (*NumGangsClauseItr)->getClauseKind(); 1547 return nullptr; 1548 } 1549 } 1550 } 1551 1552 llvm::SmallVector<OpenACCGangKind> GangKinds; 1553 llvm::SmallVector<Expr *> IntExprs; 1554 1555 // Store the existing locations, so we can do duplicate checking. Index is 1556 // the int-value of the OpenACCGangKind enum. 1557 SourceLocation ExistingElemLoc[3]; 1558 1559 for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) { 1560 OpenACCGangKind GK = Clause.getGangKinds()[I]; 1561 ExprResult ER = 1562 SemaRef.CheckGangExpr(ExistingClauses, Clause.getDirectiveKind(), GK, 1563 Clause.getIntExprs()[I]); 1564 1565 if (!ER.isUsable()) 1566 continue; 1567 1568 // OpenACC 3.3 2.9: 'gang-arg-list' may have at most one num, one dim, and 1569 // one static argument. 1570 if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) { 1571 SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt) 1572 << static_cast<unsigned>(GK); 1573 SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)], 1574 diag::note_acc_previous_expr_here); 1575 continue; 1576 } 1577 1578 ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc(); 1579 GangKinds.push_back(GK); 1580 IntExprs.push_back(ER.get()); 1581 } 1582 1583 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop) { 1584 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 1585 // construct, the gang clause behaves as follows. ... The region of a loop 1586 // with a gang clause may not contain another loop with a gang clause unless 1587 // within a nested compute region. 1588 if (SemaRef.LoopGangClauseOnKernel.Loc.isValid()) { 1589 // This handles the 'inner loop' diagnostic, but we cannot set that we're 1590 // on one of these until we get to the end of the construct. 1591 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1592 << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang 1593 << /*kernels construct info*/ 1 1594 << SemaRef.LoopGangClauseOnKernel.DirKind; 1595 SemaRef.Diag(SemaRef.LoopGangClauseOnKernel.Loc, 1596 diag::note_acc_previous_clause_here) 1597 << "gang"; 1598 return nullptr; 1599 } 1600 1601 // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not 1602 // contain a loop with a gang or worker clause unless within a nested 1603 // compute region. 1604 if (SemaRef.LoopWorkerClauseLoc.isValid()) { 1605 // This handles the 'inner loop' diagnostic, but we cannot set that we're 1606 // on one of these until we get to the end of the construct. 1607 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1608 << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker 1609 << /*!kernels construct info*/ 0; 1610 SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, 1611 diag::note_acc_previous_clause_here) 1612 << "worker"; 1613 return nullptr; 1614 } 1615 1616 // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not 1617 // contain a loop with a gang, worker, or vector clause unless within a 1618 // nested compute region. 1619 if (SemaRef.LoopVectorClauseLoc.isValid()) { 1620 // This handles the 'inner loop' diagnostic, but we cannot set that we're 1621 // on one of these until we get to the end of the construct. 1622 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1623 << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector 1624 << /*!kernels construct info*/ 0; 1625 SemaRef.Diag(SemaRef.LoopVectorClauseLoc, 1626 diag::note_acc_previous_clause_here) 1627 << "vector"; 1628 return nullptr; 1629 } 1630 } 1631 1632 return SemaRef.CheckGangClause(Clause.getDirectiveKind(), ExistingClauses, 1633 Clause.getBeginLoc(), Clause.getLParenLoc(), 1634 GangKinds, IntExprs, Clause.getEndLoc()); 1635 } 1636 1637 OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause( 1638 SemaOpenACC::OpenACCParsedClause &Clause) { 1639 // There isn't anything to do here, this is only valid on one construct, and 1640 // has no associated rules. 1641 return OpenACCFinalizeClause::Create(Ctx, Clause.getBeginLoc(), 1642 Clause.getEndLoc()); 1643 } 1644 1645 OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause( 1646 SemaOpenACC::OpenACCParsedClause &Clause) { 1647 // There isn't anything to do here, this is only valid on one construct, and 1648 // has no associated rules. 1649 return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(), 1650 Clause.getEndLoc()); 1651 } 1652 1653 OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause( 1654 SemaOpenACC::OpenACCParsedClause &Clause) { 1655 // OpenACC 3.3 2.9: 1656 // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause 1657 // appears. 1658 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop || 1659 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1660 const auto *Itr = llvm::find_if( 1661 ExistingClauses, llvm::IsaPred<OpenACCGangClause, OpenACCVectorClause, 1662 OpenACCWorkerClause>); 1663 if (Itr != ExistingClauses.end()) { 1664 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 1665 << Clause.getClauseKind() << (*Itr)->getClauseKind() 1666 << Clause.getDirectiveKind(); 1667 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here) 1668 << (*Itr)->getClauseKind(); 1669 return nullptr; 1670 } 1671 } 1672 1673 return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(), 1674 Clause.getEndLoc()); 1675 } 1676 1677 OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( 1678 SemaOpenACC::OpenACCParsedClause &Clause) { 1679 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop 1680 // directive that has a gang clause and is within a compute construct that has 1681 // a num_gangs clause with more than one explicit argument. 1682 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && 1683 SemaRef.getActiveComputeConstructInfo().Kind != 1684 OpenACCDirectiveKind::Invalid) || 1685 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1686 // num_gangs clause on the active compute construct. 1687 auto ActiveComputeConstructContainer = 1688 isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) 1689 ? ExistingClauses 1690 : SemaRef.getActiveComputeConstructInfo().Clauses; 1691 auto *NumGangsClauseItr = llvm::find_if( 1692 ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>); 1693 1694 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() && 1695 cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() > 1696 1) { 1697 auto *GangClauseItr = 1698 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 1699 1700 if (GangClauseItr != ExistingClauses.end()) { 1701 SemaRef.Diag(Clause.getBeginLoc(), 1702 diag::err_acc_gang_reduction_numgangs_conflict) 1703 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang 1704 << Clause.getDirectiveKind() 1705 << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()); 1706 SemaRef.Diag((*GangClauseItr)->getBeginLoc(), 1707 diag::note_acc_previous_clause_here) 1708 << (*GangClauseItr)->getClauseKind(); 1709 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), 1710 diag::note_acc_previous_clause_here) 1711 << (*NumGangsClauseItr)->getClauseKind(); 1712 return nullptr; 1713 } 1714 } 1715 } 1716 1717 // OpenACC3.3 Section 2.9.11: If a variable is involved in a reduction that 1718 // spans multiple nested loops where two or more of those loops have 1719 // associated loop directives, a reduction clause containing that variable 1720 // must appear on each of those loop directives. 1721 // 1722 // This can't really be implemented in the CFE, as this requires a level of 1723 // rechability/useage analysis that we're not really wanting to get into. 1724 // Additionally, I'm alerted that this restriction is one that the middle-end 1725 // can just 'figure out' as an extension and isn't really necessary. 1726 // 1727 // OpenACC3.3 Section 2.9.11: Every 'var' in a reduction clause appearing on 1728 // an orphaned loop construct must be private. 1729 // 1730 // This again is something we cannot really diagnose, as it requires we see 1731 // all the uses/scopes of all variables referenced. The middle end/MLIR might 1732 // be able to diagnose this. 1733 1734 // OpenACC 3.3 Section 2.5.4: 1735 // A reduction clause may not appear on a parallel construct with a 1736 // num_gangs clause that has more than one argument. 1737 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || 1738 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) { 1739 auto NumGangsClauses = llvm::make_filter_range( 1740 ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>); 1741 1742 for (auto *NGC : NumGangsClauses) { 1743 unsigned NumExprs = 1744 cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size(); 1745 1746 if (NumExprs > 1) { 1747 SemaRef.Diag(Clause.getBeginLoc(), 1748 diag::err_acc_reduction_num_gangs_conflict) 1749 << /*>1 arg in first loc=*/0 << Clause.getClauseKind() 1750 << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs; 1751 SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here) 1752 << NGC->getClauseKind(); 1753 return nullptr; 1754 } 1755 } 1756 } 1757 1758 SmallVector<Expr *> ValidVars; 1759 1760 for (Expr *Var : Clause.getVarList()) { 1761 ExprResult Res = SemaRef.CheckReductionVar(Clause.getDirectiveKind(), 1762 Clause.getReductionOp(), Var); 1763 1764 if (Res.isUsable()) 1765 ValidVars.push_back(Res.get()); 1766 } 1767 1768 return SemaRef.CheckReductionClause( 1769 ExistingClauses, Clause.getDirectiveKind(), Clause.getBeginLoc(), 1770 Clause.getLParenLoc(), Clause.getReductionOp(), ValidVars, 1771 Clause.getEndLoc()); 1772 } 1773 1774 OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause( 1775 SemaOpenACC::OpenACCParsedClause &Clause) { 1776 1777 if (DisallowSinceLastDeviceType<OpenACCCollapseClause>(Clause)) 1778 return nullptr; 1779 1780 ExprResult LoopCount = SemaRef.CheckCollapseLoopCount(Clause.getLoopCount()); 1781 1782 if (!LoopCount.isUsable()) 1783 return nullptr; 1784 1785 return OpenACCCollapseClause::Create(Ctx, Clause.getBeginLoc(), 1786 Clause.getLParenLoc(), Clause.isForce(), 1787 LoopCount.get(), Clause.getEndLoc()); 1788 } 1789 1790 OpenACCClause *SemaOpenACCClauseVisitor::VisitBindClause( 1791 SemaOpenACC::OpenACCParsedClause &Clause) { 1792 1793 if (std::holds_alternative<StringLiteral *>(Clause.getBindDetails())) 1794 return OpenACCBindClause::Create( 1795 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 1796 std::get<StringLiteral *>(Clause.getBindDetails()), Clause.getEndLoc()); 1797 return OpenACCBindClause::Create( 1798 Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 1799 std::get<IdentifierInfo *>(Clause.getBindDetails()), Clause.getEndLoc()); 1800 } 1801 1802 // Return true if the two vars refer to the same variable, for the purposes of 1803 // equality checking. 1804 bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) { 1805 if (VarExpr1->isInstantiationDependent() || 1806 VarExpr2->isInstantiationDependent()) 1807 return false; 1808 1809 VarExpr1 = VarExpr1->IgnoreParenCasts(); 1810 VarExpr2 = VarExpr2->IgnoreParenCasts(); 1811 1812 // Legal expressions can be: Scalar variable reference, sub-array, array 1813 // element, or composite variable member. 1814 1815 // Sub-array. 1816 if (isa<ArraySectionExpr>(VarExpr1)) { 1817 auto *Expr2AS = dyn_cast<ArraySectionExpr>(VarExpr2); 1818 if (!Expr2AS) 1819 return false; 1820 1821 auto *Expr1AS = cast<ArraySectionExpr>(VarExpr1); 1822 1823 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase())) 1824 return false; 1825 // We could possibly check to see if the ranges aren't overlapping, but it 1826 // isn't clear that the rules allow this. 1827 return true; 1828 } 1829 1830 // Array-element. 1831 if (isa<ArraySubscriptExpr>(VarExpr1)) { 1832 auto *Expr2AS = dyn_cast<ArraySubscriptExpr>(VarExpr2); 1833 if (!Expr2AS) 1834 return false; 1835 1836 auto *Expr1AS = cast<ArraySubscriptExpr>(VarExpr1); 1837 1838 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase())) 1839 return false; 1840 1841 // We could possibly check to see if the elements referenced aren't the 1842 // same, but it isn't clear by reading of the standard that this is allowed 1843 // (and that the 'var' refered to isn't the array). 1844 return true; 1845 } 1846 1847 // Scalar variable reference, or composite variable. 1848 if (isa<DeclRefExpr>(VarExpr1)) { 1849 auto *Expr2DRE = dyn_cast<DeclRefExpr>(VarExpr2); 1850 if (!Expr2DRE) 1851 return false; 1852 1853 auto *Expr1DRE = cast<DeclRefExpr>(VarExpr1); 1854 1855 return Expr1DRE->getDecl()->getMostRecentDecl() == 1856 Expr2DRE->getDecl()->getMostRecentDecl(); 1857 } 1858 1859 llvm_unreachable("Unknown variable type encountered"); 1860 } 1861 } // namespace 1862 1863 OpenACCClause * 1864 SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses, 1865 OpenACCParsedClause &Clause) { 1866 if (Clause.getClauseKind() == OpenACCClauseKind::Invalid) 1867 return nullptr; 1868 1869 if (DiagnoseAllowedClauses(Clause.getDirectiveKind(), Clause.getClauseKind(), 1870 Clause.getBeginLoc())) 1871 return nullptr; 1872 //// Diagnose that we don't support this clause on this directive. 1873 // if (!doesClauseApplyToDirective(Clause.getDirectiveKind(), 1874 // Clause.getClauseKind())) { 1875 // Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment) 1876 // << Clause.getDirectiveKind() << Clause.getClauseKind(); 1877 // return nullptr; 1878 // } 1879 1880 if (const auto *DevTypeClause = llvm::find_if( 1881 ExistingClauses, llvm::IsaPred<OpenACCDeviceTypeClause>); 1882 DevTypeClause != ExistingClauses.end()) { 1883 if (checkValidAfterDeviceType( 1884 *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause)) 1885 return nullptr; 1886 } 1887 1888 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses}; 1889 OpenACCClause *Result = Visitor.Visit(Clause); 1890 assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) && 1891 "Created wrong clause?"); 1892 1893 return Result; 1894 } 1895 1896 /// OpenACC 3.3 section 2.5.15: 1897 /// At a mininmum, the supported data types include ... the numerical data types 1898 /// in C, C++, and Fortran. 1899 /// 1900 /// If the reduction var is a composite variable, each 1901 /// member of the composite variable must be a supported datatype for the 1902 /// reduction operation. 1903 ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind, 1904 OpenACCReductionOperator ReductionOp, 1905 Expr *VarExpr) { 1906 VarExpr = VarExpr->IgnoreParenCasts(); 1907 1908 auto TypeIsValid = [](QualType Ty) { 1909 return Ty->isDependentType() || Ty->isScalarType(); 1910 }; 1911 1912 if (isa<ArraySectionExpr>(VarExpr)) { 1913 Expr *ASExpr = VarExpr; 1914 QualType BaseTy = ArraySectionExpr::getBaseOriginalType(ASExpr); 1915 QualType EltTy = getASTContext().getBaseElementType(BaseTy); 1916 1917 if (!TypeIsValid(EltTy)) { 1918 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) 1919 << EltTy << /*Sub array base type*/ 1; 1920 return ExprError(); 1921 } 1922 } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) { 1923 if (!RD->isStruct() && !RD->isClass()) { 1924 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 1925 << /*not class or struct*/ 0 << VarExpr->getType(); 1926 return ExprError(); 1927 } 1928 1929 if (!RD->isCompleteDefinition()) { 1930 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 1931 << /*incomplete*/ 1 << VarExpr->getType(); 1932 return ExprError(); 1933 } 1934 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); 1935 CXXRD && !CXXRD->isAggregate()) { 1936 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 1937 << /*aggregate*/ 2 << VarExpr->getType(); 1938 return ExprError(); 1939 } 1940 1941 for (FieldDecl *FD : RD->fields()) { 1942 if (!TypeIsValid(FD->getType())) { 1943 Diag(VarExpr->getExprLoc(), 1944 diag::err_acc_reduction_composite_member_type); 1945 Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc); 1946 return ExprError(); 1947 } 1948 } 1949 } else if (!TypeIsValid(VarExpr->getType())) { 1950 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) 1951 << VarExpr->getType() << /*Sub array base type*/ 0; 1952 return ExprError(); 1953 } 1954 1955 // OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same 1956 // reduction 'var' must have the same reduction operator. 1957 if (!VarExpr->isInstantiationDependent()) { 1958 1959 for (const OpenACCReductionClause *RClause : ActiveReductionClauses) { 1960 if (RClause->getReductionOp() == ReductionOp) 1961 break; 1962 1963 for (Expr *OldVarExpr : RClause->getVarList()) { 1964 if (OldVarExpr->isInstantiationDependent()) 1965 continue; 1966 1967 if (areVarsEqual(VarExpr, OldVarExpr)) { 1968 Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch) 1969 << ReductionOp << RClause->getReductionOp(); 1970 Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here) 1971 << RClause->getClauseKind(); 1972 return ExprError(); 1973 } 1974 } 1975 } 1976 } 1977 1978 return VarExpr; 1979 } 1980 1981 ExprResult SemaOpenACC::CheckTileSizeExpr(Expr *SizeExpr) { 1982 if (!SizeExpr) 1983 return ExprError(); 1984 1985 assert((SizeExpr->isInstantiationDependent() || 1986 SizeExpr->getType()->isIntegerType()) && 1987 "size argument non integer?"); 1988 1989 // If dependent, or an asterisk, the expression is fine. 1990 if (SizeExpr->isInstantiationDependent() || 1991 isa<OpenACCAsteriskSizeExpr>(SizeExpr)) 1992 return ExprResult{SizeExpr}; 1993 1994 std::optional<llvm::APSInt> ICE = 1995 SizeExpr->getIntegerConstantExpr(getASTContext()); 1996 1997 // OpenACC 3.3 2.9.8 1998 // where each tile size is a constant positive integer expression or asterisk. 1999 if (!ICE || *ICE <= 0) { 2000 Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value) 2001 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); 2002 return ExprError(); 2003 } 2004 2005 return ExprResult{ 2006 ConstantExpr::Create(getASTContext(), SizeExpr, APValue{*ICE})}; 2007 } 2008 2009 ExprResult SemaOpenACC::CheckCollapseLoopCount(Expr *LoopCount) { 2010 if (!LoopCount) 2011 return ExprError(); 2012 2013 assert((LoopCount->isInstantiationDependent() || 2014 LoopCount->getType()->isIntegerType()) && 2015 "Loop argument non integer?"); 2016 2017 // If this is dependent, there really isn't anything we can check. 2018 if (LoopCount->isInstantiationDependent()) 2019 return ExprResult{LoopCount}; 2020 2021 std::optional<llvm::APSInt> ICE = 2022 LoopCount->getIntegerConstantExpr(getASTContext()); 2023 2024 // OpenACC 3.3: 2.9.1 2025 // The argument to the collapse clause must be a constant positive integer 2026 // expression. 2027 if (!ICE || *ICE <= 0) { 2028 Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count) 2029 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); 2030 return ExprError(); 2031 } 2032 2033 return ExprResult{ 2034 ConstantExpr::Create(getASTContext(), LoopCount, APValue{*ICE})}; 2035 } 2036 2037 ExprResult 2038 SemaOpenACC::CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses, 2039 OpenACCDirectiveKind DK, OpenACCGangKind GK, 2040 Expr *E) { 2041 // There are two cases for the enforcement here: the 'current' directive is a 2042 // 'loop', where we need to check the active compute construct kind, or the 2043 // current directive is a 'combined' construct, where we have to check the 2044 // current one. 2045 switch (DK) { 2046 case OpenACCDirectiveKind::ParallelLoop: 2047 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, 2048 E); 2049 case OpenACCDirectiveKind::SerialLoop: 2050 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, 2051 E); 2052 case OpenACCDirectiveKind::KernelsLoop: 2053 return CheckGangKernelsExpr(*this, ExistingClauses, DK, 2054 ActiveComputeConstructInfo.Kind, GK, E); 2055 case OpenACCDirectiveKind::Routine: 2056 return CheckGangRoutineExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, 2057 E); 2058 case OpenACCDirectiveKind::Loop: 2059 switch (ActiveComputeConstructInfo.Kind) { 2060 case OpenACCDirectiveKind::Invalid: 2061 case OpenACCDirectiveKind::Parallel: 2062 case OpenACCDirectiveKind::ParallelLoop: 2063 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, 2064 GK, E); 2065 case OpenACCDirectiveKind::SerialLoop: 2066 case OpenACCDirectiveKind::Serial: 2067 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, 2068 E); 2069 case OpenACCDirectiveKind::KernelsLoop: 2070 case OpenACCDirectiveKind::Kernels: 2071 return CheckGangKernelsExpr(*this, ExistingClauses, DK, 2072 ActiveComputeConstructInfo.Kind, GK, E); 2073 default: 2074 llvm_unreachable("Non compute construct in active compute construct?"); 2075 } 2076 case OpenACCDirectiveKind::Invalid: 2077 // This can happen in cases where the the directive was not recognized but 2078 // we continued anyway. Since the validity checking is all-over the place 2079 // (it can be a star/integer, or a constant expr depending on the tag), we 2080 // just give up and return an ExprError here. 2081 return ExprError(); 2082 default: 2083 llvm_unreachable("Invalid directive kind for a Gang clause"); 2084 } 2085 llvm_unreachable("Compute construct directive not handled?"); 2086 } 2087 2088 OpenACCClause * 2089 SemaOpenACC::CheckGangClause(OpenACCDirectiveKind DirKind, 2090 ArrayRef<const OpenACCClause *> ExistingClauses, 2091 SourceLocation BeginLoc, SourceLocation LParenLoc, 2092 ArrayRef<OpenACCGangKind> GangKinds, 2093 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) { 2094 // Reduction isn't possible on 'routine' so we don't bother checking it here. 2095 if (DirKind != OpenACCDirectiveKind::Routine) { 2096 // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive 2097 // that has a gang clause with a dim: argument whose value is greater 2098 // than 1. 2099 const auto *ReductionItr = 2100 llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 2101 2102 if (ReductionItr != ExistingClauses.end()) { 2103 const auto GangZip = llvm::zip_equal(GangKinds, IntExprs); 2104 const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) { 2105 return std::get<0>(Tuple) == OpenACCGangKind::Dim; 2106 }); 2107 2108 if (GangItr != GangZip.end()) { 2109 const Expr *DimExpr = std::get<1>(*GangItr); 2110 2111 assert((DimExpr->isInstantiationDependent() || 2112 isa<ConstantExpr>(DimExpr)) && 2113 "Improperly formed gang argument"); 2114 if (const auto *DimVal = dyn_cast<ConstantExpr>(DimExpr); 2115 DimVal && DimVal->getResultAsAPSInt() > 1) { 2116 Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict) 2117 << /*gang/reduction=*/0 << DirKind; 2118 Diag((*ReductionItr)->getBeginLoc(), 2119 diag::note_acc_previous_clause_here) 2120 << (*ReductionItr)->getClauseKind(); 2121 return nullptr; 2122 } 2123 } 2124 } 2125 } 2126 2127 return OpenACCGangClause::Create(getASTContext(), BeginLoc, LParenLoc, 2128 GangKinds, IntExprs, EndLoc); 2129 } 2130 2131 OpenACCClause *SemaOpenACC::CheckReductionClause( 2132 ArrayRef<const OpenACCClause *> ExistingClauses, 2133 OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, 2134 SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, 2135 ArrayRef<Expr *> Vars, SourceLocation EndLoc) { 2136 if (DirectiveKind == OpenACCDirectiveKind::Loop || 2137 isOpenACCCombinedDirectiveKind(DirectiveKind)) { 2138 // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive 2139 // that has a gang clause with a dim: argument whose value is greater 2140 // than 1. 2141 const auto GangClauses = llvm::make_filter_range( 2142 ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 2143 2144 for (auto *GC : GangClauses) { 2145 const auto *GangClause = cast<OpenACCGangClause>(GC); 2146 for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) { 2147 std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I); 2148 if (EPair.first != OpenACCGangKind::Dim) 2149 continue; 2150 2151 if (const auto *DimVal = dyn_cast<ConstantExpr>(EPair.second); 2152 DimVal && DimVal->getResultAsAPSInt() > 1) { 2153 Diag(BeginLoc, diag::err_acc_gang_reduction_conflict) 2154 << /*reduction/gang=*/1 << DirectiveKind; 2155 Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here) 2156 << GangClause->getClauseKind(); 2157 return nullptr; 2158 } 2159 } 2160 } 2161 } 2162 2163 auto *Ret = OpenACCReductionClause::Create( 2164 getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc); 2165 return Ret; 2166 } 2167 2168 llvm::SmallVector<Expr *> 2169 SemaOpenACC::CheckLinkClauseVarList(ArrayRef<Expr *> VarExprs) { 2170 const DeclContext *DC = removeLinkageSpecDC(getCurContext()); 2171 2172 // Link has no special restrictions on its var list unless it is not at NS/TU 2173 // scope. 2174 if (isa<NamespaceDecl, TranslationUnitDecl>(DC)) 2175 return llvm::SmallVector<Expr *>(VarExprs); 2176 2177 llvm::SmallVector<Expr *> NewVarList; 2178 2179 for (Expr *VarExpr : VarExprs) { 2180 if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(VarExpr)) { 2181 NewVarList.push_back(VarExpr); 2182 continue; 2183 } 2184 2185 // Field decls can't be global, nor extern, and declare can't refer to 2186 // non-static fields in class-scope, so this always fails the scope check. 2187 // BUT for now we add this so it gets diagnosed by the general 'declare' 2188 // rules. 2189 if (isa<MemberExpr>(VarExpr)) { 2190 NewVarList.push_back(VarExpr); 2191 continue; 2192 } 2193 2194 const auto *DRE = cast<DeclRefExpr>(VarExpr); 2195 const VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()); 2196 2197 if (!Var || !Var->hasExternalStorage()) 2198 Diag(VarExpr->getBeginLoc(), diag::err_acc_link_not_extern); 2199 else 2200 NewVarList.push_back(VarExpr); 2201 } 2202 2203 return NewVarList; 2204 } 2205 bool SemaOpenACC::CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause, 2206 OpenACCModifierKind Mods) { 2207 2208 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Declare) 2209 return false; 2210 2211 const DeclContext *DC = removeLinkageSpecDC(getCurContext()); 2212 2213 // Whether this is 'create', 'copyin', 'deviceptr', 'device_resident', or 2214 // 'link', which have 2 special rules. 2215 bool IsSpecialClause = 2216 Clause.getClauseKind() == OpenACCClauseKind::Create || 2217 Clause.getClauseKind() == OpenACCClauseKind::CopyIn || 2218 Clause.getClauseKind() == OpenACCClauseKind::DevicePtr || 2219 Clause.getClauseKind() == OpenACCClauseKind::DeviceResident || 2220 Clause.getClauseKind() == OpenACCClauseKind::Link; 2221 2222 // OpenACC 3.3 2.13: 2223 // In C or C++ global or namespace scope, only 'create', 2224 // 'copyin', 'deviceptr', 'device_resident', or 'link' clauses are 2225 // allowed. 2226 if (!IsSpecialClause && isa<NamespaceDecl, TranslationUnitDecl>(DC)) { 2227 return Diag(Clause.getBeginLoc(), diag::err_acc_declare_clause_at_global) 2228 << Clause.getClauseKind(); 2229 } 2230 2231 llvm::SmallVector<Expr *> FilteredVarList; 2232 const DeclaratorDecl *CurDecl = nullptr; 2233 for (Expr *VarExpr : Clause.getVarList()) { 2234 if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(VarExpr)) { 2235 // There isn't really anything we can do here, so we add them anyway and 2236 // we can check them again when we instantiate this. 2237 } else if (const auto *MemExpr = dyn_cast<MemberExpr>(VarExpr)) { 2238 FieldDecl *FD = 2239 cast<FieldDecl>(MemExpr->getMemberDecl()->getCanonicalDecl()); 2240 CurDecl = FD; 2241 2242 if (removeLinkageSpecDC( 2243 FD->getLexicalDeclContext()->getPrimaryContext()) != DC) { 2244 Diag(MemExpr->getBeginLoc(), diag::err_acc_declare_same_scope) 2245 << Clause.getClauseKind(); 2246 continue; 2247 } 2248 } else { 2249 const auto *DRE = cast<DeclRefExpr>(VarExpr); 2250 if (const auto *Var = dyn_cast<VarDecl>(DRE->getDecl())) { 2251 CurDecl = Var->getCanonicalDecl(); 2252 2253 // OpenACC3.3 2.13: 2254 // A 'declare' directive must be in the same scope as the declaration of 2255 // any var that appears in the clauses of the directive or any scope 2256 // within a C/C++ function. 2257 // We can't really check 'scope' here, so we check declaration context, 2258 // which is a reasonable approximation, but misses scopes inside of 2259 // functions. 2260 if (removeLinkageSpecDC( 2261 Var->getLexicalDeclContext()->getPrimaryContext()) != DC) { 2262 Diag(VarExpr->getBeginLoc(), diag::err_acc_declare_same_scope) 2263 << Clause.getClauseKind(); 2264 continue; 2265 } 2266 // OpenACC3.3 2.13: 2267 // C and C++ extern variables may only appear in 'create', 2268 // 'copyin', 'deviceptr', 'device_resident', or 'link' clauses on a 2269 // 'declare' directive. 2270 if (!IsSpecialClause && Var->hasExternalStorage()) { 2271 Diag(VarExpr->getBeginLoc(), diag::err_acc_declare_extern) 2272 << Clause.getClauseKind(); 2273 continue; 2274 } 2275 } 2276 2277 // OpenACC3.3 2.13: 2278 // A var may appear at most once in all the clauses of declare 2279 // directives for a function, subroutine, program, or module. 2280 2281 if (CurDecl) { 2282 auto [Itr, Inserted] = DeclareVarReferences.try_emplace(CurDecl); 2283 if (!Inserted) { 2284 Diag(VarExpr->getBeginLoc(), diag::err_acc_multiple_references) 2285 << Clause.getClauseKind(); 2286 Diag(Itr->second, diag::note_acc_previous_reference); 2287 continue; 2288 } else { 2289 Itr->second = VarExpr->getBeginLoc(); 2290 } 2291 } 2292 } 2293 FilteredVarList.push_back(VarExpr); 2294 } 2295 2296 Clause.setVarListDetails(FilteredVarList, Mods); 2297 return false; 2298 } 2299