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