Skip to content

Commit 009b5e8

Browse files
committed
[OpenACC] 'vector' clause implementation for combined constructs
Similar to 'worker', the 'vector' clause has some rules that needed to be applied on its argument legality that for combined constructs need to look at the current construct, not the 'effective' parent construct. Additionally, it has some interaction with `vector_length` that needed to be encoded as well. This patch implements it.
1 parent f09b16e commit 009b5e8

8 files changed

+507
-65
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12762,9 +12762,9 @@ def err_acc_gang_dim_value
1276212762
: Error<"argument to 'gang' clause dimension must be %select{a constant "
1276312763
"expression|1, 2, or 3: evaluated to %1}0">;
1276412764
def err_acc_num_arg_conflict
12765-
: Error<"'num' argument to '%0' clause not allowed on a '%1' "
12766-
"construct%select{| associated with a '%3' construct}2 that has a "
12767-
"'%4' clause">;
12765+
: Error<"'%0' argument to '%1' clause not allowed on a '%2' "
12766+
"construct%select{| associated with a '%4' construct}3 that has a "
12767+
"'%5' clause">;
1276812768
def err_acc_num_arg_conflict_reverse
1276912769
: Error<"'%0' clause not allowed on a 'kernels loop' construct that "
1277012770
"has a '%1' clause with a%select{n| 'num'}2 argument">;

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 109 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,25 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
804804
if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
805805
return nullptr;
806806

807+
// OpenACC 3.3 Section 2.9.4:
808+
// An argument is allowed only when the 'vector_length' does not appear on the
809+
// 'kernels' construct.
810+
if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
811+
auto VectorClauses = llvm::make_filter_range(
812+
ExistingClauses, llvm::IsaPred<OpenACCVectorClause>);
813+
814+
for (auto *VC : VectorClauses) {
815+
if (cast<OpenACCVectorClause>(VC)->hasIntExpr()) {
816+
SemaRef.Diag(Clause.getBeginLoc(),
817+
diag::err_acc_num_arg_conflict_reverse)
818+
<< OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector
819+
<< /*num argument*/ 0;
820+
SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here);
821+
return nullptr;
822+
}
823+
}
824+
}
825+
807826
assert(Clause.getIntExprs().size() == 1 &&
808827
"Invalid number of expressions for NumWorkers");
809828
return OpenACCVectorLengthClause::Create(
@@ -1097,6 +1116,14 @@ ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK,
10971116
<< HasAssocKind(DK, AssocKind) << AssocKind;
10981117
return ExprError();
10991118
}
1119+
ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind,
1120+
OpenACCClauseKind CK, OpenACCDirectiveKind DK,
1121+
OpenACCDirectiveKind AssocKind) {
1122+
S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1123+
<< TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK
1124+
<< HasAssocKind(DK, AssocKind) << AssocKind;
1125+
return ExprError();
1126+
}
11001127

11011128
ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
11021129
OpenACCDirectiveKind AssocKind,
@@ -1172,8 +1199,9 @@ ExprResult CheckGangKernelsExpr(SemaOpenACC &S,
11721199

11731200
if (Itr != Collection.end()) {
11741201
S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict)
1175-
<< OpenACCClauseKind::Gang << DK << HasAssocKind(DK, AssocKind)
1176-
<< AssocKind << OpenACCClauseKind::NumGangs;
1202+
<< "num" << OpenACCClauseKind::Gang << DK
1203+
<< HasAssocKind(DK, AssocKind) << AssocKind
1204+
<< OpenACCClauseKind::NumGangs;
11771205

11781206
S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
11791207
return ExprError();
@@ -1206,63 +1234,94 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
12061234
SemaOpenACC::OpenACCParsedClause &Clause) {
12071235
if (DiagIfSeqClause(Clause))
12081236
return nullptr;
1209-
// Restrictions only properly implemented on 'loop' constructs, and it is
1210-
// the only construct that can do anything with this, so skip/treat as
1211-
// unimplemented for the combined constructs.
1212-
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
1237+
1238+
// Restrictions only properly implemented on 'loop'/'combined' constructs, and
1239+
// it is the only construct that can do anything with this, so skip/treat as
1240+
// unimplemented for the routine constructs.
1241+
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop &&
1242+
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
12131243
return isNotImplemented();
12141244

12151245
Expr *IntExpr =
12161246
Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
12171247
if (IntExpr) {
1218-
switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1219-
case OpenACCDirectiveKind::Invalid:
1220-
case OpenACCDirectiveKind::Parallel:
1221-
// No restriction on when 'parallel' can contain an argument.
1222-
break;
1223-
case OpenACCDirectiveKind::Serial:
1224-
// GCC disallows this, and there is no real good reason for us to permit
1225-
// it, so disallow until we come up with a use case that makes sense.
1226-
DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1227-
OpenACCClauseKind::Vector, Clause.getDirectiveKind(),
1228-
SemaRef.getActiveComputeConstructInfo().Kind);
1229-
IntExpr = nullptr;
1230-
break;
1231-
case OpenACCDirectiveKind::Kernels: {
1232-
const auto *Itr =
1233-
llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1234-
llvm::IsaPred<OpenACCVectorLengthClause>);
1235-
if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1236-
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1237-
<< OpenACCClauseKind::Vector << Clause.getDirectiveKind()
1238-
<< HasAssocKind(Clause.getDirectiveKind(),
1239-
SemaRef.getActiveComputeConstructInfo().Kind)
1240-
<< SemaRef.getActiveComputeConstructInfo().Kind
1241-
<< OpenACCClauseKind::VectorLength;
1242-
SemaRef.Diag((*Itr)->getBeginLoc(),
1243-
diag::note_acc_previous_clause_here);
1248+
if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1249+
switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1250+
case OpenACCDirectiveKind::Invalid:
1251+
case OpenACCDirectiveKind::Parallel:
1252+
// No restriction on when 'parallel' can contain an argument.
1253+
break;
1254+
case OpenACCDirectiveKind::Serial:
1255+
// GCC disallows this, and there is no real good reason for us to permit
1256+
// it, so disallow until we come up with a use case that makes sense.
1257+
DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1258+
Clause.getDirectiveKind(),
1259+
SemaRef.getActiveComputeConstructInfo().Kind);
1260+
IntExpr = nullptr;
1261+
break;
1262+
case OpenACCDirectiveKind::Kernels: {
1263+
const auto *Itr =
1264+
llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1265+
llvm::IsaPred<OpenACCVectorLengthClause>);
1266+
if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1267+
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1268+
<< "length" << OpenACCClauseKind::Vector
1269+
<< Clause.getDirectiveKind()
1270+
<< HasAssocKind(Clause.getDirectiveKind(),
1271+
SemaRef.getActiveComputeConstructInfo().Kind)
1272+
<< SemaRef.getActiveComputeConstructInfo().Kind
1273+
<< OpenACCClauseKind::VectorLength;
1274+
SemaRef.Diag((*Itr)->getBeginLoc(),
1275+
diag::note_acc_previous_clause_here);
12441276

1277+
IntExpr = nullptr;
1278+
}
1279+
break;
1280+
}
1281+
default:
1282+
llvm_unreachable("Non compute construct in active compute construct");
1283+
}
1284+
} else {
1285+
if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1286+
DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1287+
Clause.getDirectiveKind(),
1288+
SemaRef.getActiveComputeConstructInfo().Kind);
12451289
IntExpr = nullptr;
1290+
} else if (Clause.getDirectiveKind() ==
1291+
OpenACCDirectiveKind::KernelsLoop) {
1292+
const auto *Itr = llvm::find_if(
1293+
ExistingClauses, llvm::IsaPred<OpenACCVectorLengthClause>);
1294+
if (Itr != ExistingClauses.end()) {
1295+
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1296+
<< "length" << OpenACCClauseKind::Vector
1297+
<< Clause.getDirectiveKind()
1298+
<< HasAssocKind(Clause.getDirectiveKind(),
1299+
SemaRef.getActiveComputeConstructInfo().Kind)
1300+
<< SemaRef.getActiveComputeConstructInfo().Kind
1301+
<< OpenACCClauseKind::VectorLength;
1302+
SemaRef.Diag((*Itr)->getBeginLoc(),
1303+
diag::note_acc_previous_clause_here);
1304+
1305+
IntExpr = nullptr;
1306+
}
12461307
}
1247-
break;
1248-
}
1249-
default:
1250-
llvm_unreachable("Non compute construct in active compute construct");
12511308
}
12521309
}
12531310

1254-
// OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1255-
// contain a loop with a gang, worker, or vector clause unless within a nested
1256-
// compute region.
1257-
if (SemaRef.LoopVectorClauseLoc.isValid()) {
1258-
// This handles the 'inner loop' diagnostic, but we cannot set that we're on
1259-
// one of these until we get to the end of the construct.
1260-
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1261-
<< OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1262-
<< /*skip kernels construct info*/ 0;
1263-
SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1264-
diag::note_acc_previous_clause_here);
1265-
return nullptr;
1311+
if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1312+
// OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1313+
// contain a loop with a gang, worker, or vector clause unless within a
1314+
// nested compute region.
1315+
if (SemaRef.LoopVectorClauseLoc.isValid()) {
1316+
// This handles the 'inner loop' diagnostic, but we cannot set that we're
1317+
// on one of these until we get to the end of the construct.
1318+
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1319+
<< OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1320+
<< /*skip kernels construct info*/ 0;
1321+
SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1322+
diag::note_acc_previous_clause_here);
1323+
return nullptr;
1324+
}
12661325
}
12671326

12681327
return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(),
@@ -1305,7 +1364,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
13051364
llvm::IsaPred<OpenACCNumWorkersClause>);
13061365
if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
13071366
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1308-
<< OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1367+
<< "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
13091368
<< HasAssocKind(Clause.getDirectiveKind(),
13101369
SemaRef.getActiveComputeConstructInfo().Kind)
13111370
<< SemaRef.getActiveComputeConstructInfo().Kind
@@ -1334,7 +1393,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
13341393
llvm::IsaPred<OpenACCNumWorkersClause>);
13351394
if (Itr != ExistingClauses.end()) {
13361395
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1337-
<< OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1396+
<< "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
13381397
<< HasAssocKind(Clause.getDirectiveKind(),
13391398
SemaRef.getActiveComputeConstructInfo().Kind)
13401399
<< SemaRef.getActiveComputeConstructInfo().Kind

clang/test/AST/ast-print-openacc-combined-construct.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,46 @@ void foo() {
344344
#pragma acc kernels loop worker(num:5)
345345
for(int i = 0;i<5;++i);
346346

347+
// CHECK: #pragma acc parallel loop vector
348+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
349+
// CHECK-NEXT: ;
350+
#pragma acc parallel loop vector
351+
for(int i = 0;i<5;++i);
352+
353+
// CHECK: #pragma acc parallel loop vector(length: 5)
354+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
355+
// CHECK-NEXT: ;
356+
#pragma acc parallel loop vector(5)
357+
for(int i = 0;i<5;++i);
358+
359+
// CHECK: #pragma acc parallel loop vector(length: 5)
360+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
361+
// CHECK-NEXT: ;
362+
#pragma acc parallel loop vector(length:5)
363+
for(int i = 0;i<5;++i);
364+
365+
// CHECK-NEXT: #pragma acc kernels loop vector
366+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
367+
// CHECK-NEXT: ;
368+
#pragma acc kernels loop vector
369+
for(int i = 0;i<5;++i);
370+
371+
// CHECK-NEXT: #pragma acc kernels loop vector(length: 5)
372+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
373+
// CHECK-NEXT: ;
374+
#pragma acc kernels loop vector(5)
375+
for(int i = 0;i<5;++i);
376+
377+
// CHECK-NEXT: #pragma acc kernels loop vector(length: 5)
378+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
379+
// CHECK-NEXT: ;
380+
#pragma acc kernels loop vector(length:5)
381+
for(int i = 0;i<5;++i);
382+
383+
// CHECK-NEXT: #pragma acc serial loop vector
384+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
385+
// CHECK-NEXT: ;
386+
#pragma acc serial loop vector
387+
for(int i = 0;i<5;++i);
388+
347389
}

clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ void uses() {
4848
for(unsigned i = 0; i < 5; ++i);
4949
#pragma acc parallel loop auto worker
5050
for(unsigned i = 0; i < 5; ++i);
51-
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
5251
#pragma acc parallel loop auto vector
5352
for(unsigned i = 0; i < 5; ++i);
5453
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}
@@ -167,7 +166,6 @@ void uses() {
167166
for(unsigned i = 0; i < 5; ++i);
168167
#pragma acc parallel loop worker auto
169168
for(unsigned i = 0; i < 5; ++i);
170-
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
171169
#pragma acc parallel loop vector auto
172170
for(unsigned i = 0; i < 5; ++i);
173171
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}
@@ -287,7 +285,6 @@ void uses() {
287285
for(unsigned i = 0; i < 5; ++i);
288286
#pragma acc parallel loop independent worker
289287
for(unsigned i = 0; i < 5; ++i);
290-
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
291288
#pragma acc parallel loop independent vector
292289
for(unsigned i = 0; i < 5; ++i);
293290
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}
@@ -406,7 +403,6 @@ void uses() {
406403
for(unsigned i = 0; i < 5; ++i);
407404
#pragma acc parallel loop worker independent
408405
for(unsigned i = 0; i < 5; ++i);
409-
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
410406
#pragma acc parallel loop vector independent
411407
for(unsigned i = 0; i < 5; ++i);
412408
// expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}}
@@ -650,9 +646,8 @@ void uses() {
650646
// expected-note@+1{{previous clause is here}}
651647
#pragma acc parallel loop worker seq
652648
for(unsigned i = 0; i < 5; ++i);
653-
// TODOexpected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'vector' clause on a 'parallel loop' construct}}
654-
// TODOexpected-note@+1{{previous clause is here}}
655-
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
649+
// expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'vector' clause on a 'parallel loop' construct}}
650+
// expected-note@+1{{previous clause is here}}
656651
#pragma acc parallel loop vector seq
657652
for(unsigned i = 0; i < 5; ++i);
658653
// expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}}

clang/test/SemaOpenACC/combined-construct-device_type-clause.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ void uses() {
3939
// 'worker', 'vector', 'seq', 'independent', 'auto', and 'tile' after
4040
// 'device_type'.
4141

42-
//expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}}
4342
#pragma acc parallel loop device_type(*) vector
4443
for(int i = 0; i < 5; ++i);
4544

0 commit comments

Comments
 (0)