@@ -389,6 +389,18 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
389
389
return false ;
390
390
}
391
391
}
392
+ case OpenACCClauseKind::Vector: {
393
+ switch (DirectiveKind) {
394
+ case OpenACCDirectiveKind::Loop:
395
+ case OpenACCDirectiveKind::ParallelLoop:
396
+ case OpenACCDirectiveKind::SerialLoop:
397
+ case OpenACCDirectiveKind::KernelsLoop:
398
+ case OpenACCDirectiveKind::Routine:
399
+ return true ;
400
+ default :
401
+ return false ;
402
+ }
403
+ }
392
404
}
393
405
394
406
default :
@@ -512,14 +524,6 @@ class SemaOpenACCClauseVisitor {
512
524
513
525
OpenACCClause *Visit (SemaOpenACC::OpenACCParsedClause &Clause) {
514
526
switch (Clause.getClauseKind ()) {
515
- case OpenACCClauseKind::Vector: {
516
- // TODO OpenACC: These are only implemented enough for the 'seq'
517
- // diagnostic, otherwise treats itself as unimplemented. When we
518
- // implement these, we can remove them from here.
519
- DiagIfSeqClause (Clause);
520
- return isNotImplemented ();
521
- }
522
-
523
527
#define VISIT_CLAUSE (CLAUSE_NAME ) \
524
528
case OpenACCClauseKind::CLAUSE_NAME: \
525
529
return Visit##CLAUSE_NAME##Clause (Clause);
@@ -1035,6 +1039,97 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
1035
1039
Clause.getEndLoc ());
1036
1040
}
1037
1041
1042
+ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause (
1043
+ SemaOpenACC::OpenACCParsedClause &Clause) {
1044
+ if (DiagIfSeqClause (Clause))
1045
+ return nullptr ;
1046
+ // Restrictions only properly implemented on 'loop' constructs, and it is
1047
+ // the only construct that can do anything with this, so skip/treat as
1048
+ // unimplemented for the combined constructs.
1049
+ if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Loop)
1050
+ return isNotImplemented ();
1051
+
1052
+ Expr *IntExpr =
1053
+ Clause.getNumIntExprs () != 0 ? Clause.getIntExprs ()[0 ] : nullptr ;
1054
+ if (IntExpr) {
1055
+ switch (SemaRef.getActiveComputeConstructInfo ().Kind ) {
1056
+ case OpenACCDirectiveKind::Invalid:
1057
+ case OpenACCDirectiveKind::Parallel:
1058
+ // No restriction on when 'parallel' can contain an argument.
1059
+ break ;
1060
+ case OpenACCDirectiveKind::Serial:
1061
+ // GCC disallows this, and there is no real good reason for us to permit
1062
+ // it, so disallow until we come up with a use case that makes sense.
1063
+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_int_arg_invalid)
1064
+ << OpenACCClauseKind::Vector << " num" << /* serial=*/ 3 ;
1065
+ IntExpr = nullptr ;
1066
+ break ;
1067
+ case OpenACCDirectiveKind::Kernels: {
1068
+ const auto *Itr =
1069
+ llvm::find_if (SemaRef.getActiveComputeConstructInfo ().Clauses ,
1070
+ llvm::IsaPred<OpenACCVectorLengthClause>);
1071
+ if (Itr != SemaRef.getActiveComputeConstructInfo ().Clauses .end ()) {
1072
+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1073
+ << OpenACCClauseKind::Vector << /* vector_length=*/ 2 ;
1074
+ SemaRef.Diag ((*Itr)->getBeginLoc (),
1075
+ diag::note_acc_previous_clause_here);
1076
+
1077
+ IntExpr = nullptr ;
1078
+ }
1079
+ break ;
1080
+ }
1081
+ default :
1082
+ llvm_unreachable (" Non compute construct in active compute construct" );
1083
+ }
1084
+ }
1085
+
1086
+ // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1087
+ // construct, the gang clause behaves as follows. ... The region of a loop
1088
+ // with a gang clause may not contain another loop with a gang clause unless
1089
+ // within a nested compute region.
1090
+ if (SemaRef.LoopGangClauseOnKernelLoc .isValid ()) {
1091
+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1092
+ // one of these until we get to the end of the construct.
1093
+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1094
+ << OpenACCClauseKind::Vector << OpenACCClauseKind::Gang
1095
+ << /* skip kernels construct info*/ 0 ;
1096
+ SemaRef.Diag (SemaRef.LoopGangClauseOnKernelLoc ,
1097
+ diag::note_acc_previous_clause_here);
1098
+ return nullptr ;
1099
+ }
1100
+
1101
+ // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1102
+ // contain a loop with a gang or worker clause unless within a nested compute
1103
+ // region.
1104
+ if (SemaRef.LoopWorkerClauseLoc .isValid ()) {
1105
+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1106
+ // one of these until we get to the end of the construct.
1107
+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1108
+ << OpenACCClauseKind::Vector << OpenACCClauseKind::Worker
1109
+ << /* skip kernels construct info*/ 0 ;
1110
+ SemaRef.Diag (SemaRef.LoopWorkerClauseLoc ,
1111
+ diag::note_acc_previous_clause_here);
1112
+ return nullptr ;
1113
+ }
1114
+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1115
+ // contain a loop with a gang, worker, or vector clause unless within a nested
1116
+ // compute region.
1117
+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1118
+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1119
+ // one of these until we get to the end of the construct.
1120
+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1121
+ << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1122
+ << /* skip kernels construct info*/ 0 ;
1123
+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1124
+ diag::note_acc_previous_clause_here);
1125
+ return nullptr ;
1126
+ }
1127
+
1128
+ return OpenACCVectorClause::Create (Ctx, Clause.getBeginLoc (),
1129
+ Clause.getLParenLoc (), IntExpr,
1130
+ Clause.getEndLoc ());
1131
+ }
1132
+
1038
1133
OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause (
1039
1134
SemaOpenACC::OpenACCParsedClause &Clause) {
1040
1135
if (DiagIfSeqClause (Clause))
@@ -1099,6 +1194,20 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
1099
1194
return nullptr ;
1100
1195
}
1101
1196
1197
+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1198
+ // contain a loop with a gang, worker, or vector clause unless within a nested
1199
+ // compute region.
1200
+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1201
+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1202
+ // one of these until we get to the end of the construct.
1203
+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1204
+ << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1205
+ << /* skip kernels construct info*/ 0 ;
1206
+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1207
+ diag::note_acc_previous_clause_here);
1208
+ return nullptr ;
1209
+ }
1210
+
1102
1211
return OpenACCWorkerClause::Create (Ctx, Clause.getBeginLoc (),
1103
1212
Clause.getLParenLoc (), IntExpr,
1104
1213
Clause.getEndLoc ());
@@ -1193,6 +1302,20 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
1193
1302
return nullptr ;
1194
1303
}
1195
1304
1305
+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1306
+ // contain a loop with a gang, worker, or vector clause unless within a nested
1307
+ // compute region.
1308
+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1309
+ // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1310
+ // one of these until we get to the end of the construct.
1311
+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1312
+ << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector
1313
+ << /* kernels construct info*/ 1 ;
1314
+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1315
+ diag::note_acc_previous_clause_here);
1316
+ return nullptr ;
1317
+ }
1318
+
1196
1319
return OpenACCGangClause::Create (Ctx, Clause.getBeginLoc (),
1197
1320
Clause.getLParenLoc (), GangKinds, IntExprs,
1198
1321
Clause.getEndLoc ());
@@ -1313,6 +1436,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
1313
1436
: SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
1314
1437
DirKind(DK), OldLoopGangClauseOnKernelLoc(S.LoopGangClauseOnKernelLoc),
1315
1438
OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
1439
+ OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
1316
1440
LoopRAII(SemaRef, /* PreserveDepth=*/ false ) {
1317
1441
// Compute constructs end up taking their 'loop'.
1318
1442
if (DirKind == OpenACCDirectiveKind::Parallel ||
@@ -1330,6 +1454,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
1330
1454
// Implement the 'unless within a nested compute region' part.
1331
1455
SemaRef.LoopGangClauseOnKernelLoc = {};
1332
1456
SemaRef.LoopWorkerClauseLoc = {};
1457
+ SemaRef.LoopVectorClauseLoc = {};
1333
1458
} else if (DirKind == OpenACCDirectiveKind::Loop) {
1334
1459
SetCollapseInfoBeforeAssociatedStmt (UnInstClauses, Clauses);
1335
1460
SetTileInfoBeforeAssociatedStmt (UnInstClauses, Clauses);
@@ -1355,6 +1480,10 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
1355
1480
auto *Itr = llvm::find_if (Clauses, llvm::IsaPred<OpenACCWorkerClause>);
1356
1481
if (Itr != Clauses.end ())
1357
1482
SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc ();
1483
+
1484
+ auto *Itr2 = llvm::find_if (Clauses, llvm::IsaPred<OpenACCVectorClause>);
1485
+ if (Itr2 != Clauses.end ())
1486
+ SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc ();
1358
1487
}
1359
1488
}
1360
1489
}
@@ -1429,6 +1558,7 @@ SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
1429
1558
SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
1430
1559
SemaRef.LoopGangClauseOnKernelLoc = OldLoopGangClauseOnKernelLoc;
1431
1560
SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
1561
+ SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
1432
1562
1433
1563
if (DirKind == OpenACCDirectiveKind::Parallel ||
1434
1564
DirKind == OpenACCDirectiveKind::Serial ||
0 commit comments