Skip to content

Commit cb6a02a

Browse files
committed
[OpenACC] Implement 'worker' clause for combined constructs
This is very similar to 'gang', except with fewer restrictions, and only an interaction with 'num_workers', plus disallowing 'gang' and 'worker' in its associated statement. This patch implements this, the same as how 'gang' implemented it.
1 parent abb6919 commit cb6a02a

8 files changed

+431
-68
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12766,8 +12766,8 @@ def err_acc_num_arg_conflict
1276612766
"construct%select{| associated with a '%3' construct}2 that has a "
1276712767
"'%4' clause">;
1276812768
def err_acc_num_arg_conflict_reverse
12769-
: Error<"'num_gangs' clause not allowed on a 'kernels loop' construct that "
12770-
"has a 'gang' clause with a 'num' argument">;
12769+
: Error<"'%0' clause not allowed on a 'kernels loop' construct that "
12770+
"has a '%1' clause with a%select{n| 'num'}2 argument">;
1277112771
def err_acc_clause_in_clause_region
1277212772
: Error<"loop with a '%0' clause may not exist in the region of a '%1' "
1277312773
"clause%select{| on a '%3' construct}2">;

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 111 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,9 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
748748
for (auto *GC : GangClauses) {
749749
if (cast<OpenACCGangClause>(GC)->hasExprOfKind(OpenACCGangKind::Num)) {
750750
SemaRef.Diag(Clause.getBeginLoc(),
751-
diag::err_acc_num_arg_conflict_reverse);
751+
diag::err_acc_num_arg_conflict_reverse)
752+
<< OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang
753+
<< /*Num argument*/ 1;
752754
SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here);
753755
return nullptr;
754756
}
@@ -768,6 +770,25 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
768770
if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
769771
return nullptr;
770772

773+
// OpenACC 3.3 Section 2.9.2:
774+
// An argument is allowed only when the 'num_workers' does not appear on the
775+
// kernels construct.
776+
if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
777+
auto WorkerClauses = llvm::make_filter_range(
778+
ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>);
779+
780+
for (auto *WC : WorkerClauses) {
781+
if (cast<OpenACCWorkerClause>(WC)->hasIntExpr()) {
782+
SemaRef.Diag(Clause.getBeginLoc(),
783+
diag::err_acc_num_arg_conflict_reverse)
784+
<< OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker
785+
<< /*num argument*/ 0;
786+
SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here);
787+
return nullptr;
788+
}
789+
}
790+
}
791+
771792
assert(Clause.getIntExprs().size() == 1 &&
772793
"Invalid number of expressions for NumWorkers");
773794
return OpenACCNumWorkersClause::Create(
@@ -1254,74 +1275,107 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
12541275
if (DiagIfSeqClause(Clause))
12551276
return nullptr;
12561277

1257-
// Restrictions only properly implemented on 'loop' constructs, and it is
1258-
// the only construct that can do anything with this, so skip/treat as
1259-
// unimplemented for the combined constructs.
1260-
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
1278+
// Restrictions only properly implemented on 'loop'/'combined' constructs, and
1279+
// it is the only construct that can do anything with this, so skip/treat as
1280+
// unimplemented for the routine constructs.
1281+
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop &&
1282+
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
12611283
return isNotImplemented();
12621284

12631285
Expr *IntExpr =
12641286
Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
12651287

12661288
if (IntExpr) {
1267-
switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1268-
case OpenACCDirectiveKind::Invalid:
1269-
case OpenACCDirectiveKind::Parallel:
1270-
case OpenACCDirectiveKind::Serial:
1271-
DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1272-
OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1273-
SemaRef.getActiveComputeConstructInfo().Kind);
1274-
IntExpr = nullptr;
1275-
break;
1276-
case OpenACCDirectiveKind::Kernels: {
1277-
const auto *Itr =
1278-
llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1279-
llvm::IsaPred<OpenACCNumWorkersClause>);
1280-
if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1281-
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1282-
<< OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1283-
<< HasAssocKind(Clause.getDirectiveKind(),
1284-
SemaRef.getActiveComputeConstructInfo().Kind)
1285-
<< SemaRef.getActiveComputeConstructInfo().Kind
1286-
<< OpenACCClauseKind::NumWorkers;
1287-
SemaRef.Diag((*Itr)->getBeginLoc(),
1288-
diag::note_acc_previous_clause_here);
1289-
1289+
if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1290+
switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1291+
case OpenACCDirectiveKind::Invalid:
1292+
case OpenACCDirectiveKind::ParallelLoop:
1293+
case OpenACCDirectiveKind::SerialLoop:
1294+
case OpenACCDirectiveKind::Parallel:
1295+
case OpenACCDirectiveKind::Serial:
1296+
DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1297+
OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1298+
SemaRef.getActiveComputeConstructInfo().Kind);
12901299
IntExpr = nullptr;
1300+
break;
1301+
case OpenACCDirectiveKind::KernelsLoop:
1302+
case OpenACCDirectiveKind::Kernels: {
1303+
const auto *Itr =
1304+
llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1305+
llvm::IsaPred<OpenACCNumWorkersClause>);
1306+
if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1307+
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1308+
<< OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1309+
<< HasAssocKind(Clause.getDirectiveKind(),
1310+
SemaRef.getActiveComputeConstructInfo().Kind)
1311+
<< SemaRef.getActiveComputeConstructInfo().Kind
1312+
<< OpenACCClauseKind::NumWorkers;
1313+
SemaRef.Diag((*Itr)->getBeginLoc(),
1314+
diag::note_acc_previous_clause_here);
1315+
1316+
IntExpr = nullptr;
1317+
}
1318+
break;
1319+
}
1320+
default:
1321+
llvm_unreachable("Non compute construct in active compute construct");
1322+
}
1323+
} else {
1324+
if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop ||
1325+
Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1326+
DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1327+
OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1328+
SemaRef.getActiveComputeConstructInfo().Kind);
1329+
IntExpr = nullptr;
1330+
} else {
1331+
assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop &&
1332+
"Unknown combined directive kind?");
1333+
const auto *Itr = llvm::find_if(ExistingClauses,
1334+
llvm::IsaPred<OpenACCNumWorkersClause>);
1335+
if (Itr != ExistingClauses.end()) {
1336+
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1337+
<< OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1338+
<< HasAssocKind(Clause.getDirectiveKind(),
1339+
SemaRef.getActiveComputeConstructInfo().Kind)
1340+
<< SemaRef.getActiveComputeConstructInfo().Kind
1341+
<< OpenACCClauseKind::NumWorkers;
1342+
SemaRef.Diag((*Itr)->getBeginLoc(),
1343+
diag::note_acc_previous_clause_here);
1344+
1345+
IntExpr = nullptr;
1346+
}
12911347
}
1292-
break;
1293-
}
1294-
default:
1295-
llvm_unreachable("Non compute construct in active compute construct");
12961348
}
12971349
}
12981350

1299-
// OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1300-
// contain a loop with a gang or worker clause unless within a nested compute
1301-
// region.
1302-
if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1303-
// This handles the 'inner loop' diagnostic, but we cannot set that we're on
1304-
// one of these until we get to the end of the construct.
1305-
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1306-
<< OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1307-
<< /*skip kernels construct info*/ 0;
1308-
SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1309-
diag::note_acc_previous_clause_here);
1310-
return nullptr;
1311-
}
1351+
if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1352+
// OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1353+
// contain a loop with a gang or worker clause unless within a nested
1354+
// compute region.
1355+
if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1356+
// This handles the 'inner loop' diagnostic, but we cannot set that we're
1357+
// on one of these until we get to the end of the construct.
1358+
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1359+
<< OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1360+
<< /*skip kernels construct info*/ 0;
1361+
SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1362+
diag::note_acc_previous_clause_here);
1363+
return nullptr;
1364+
}
13121365

1313-
// OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1314-
// contain a loop with a gang, worker, or vector clause unless within a nested
1315-
// compute region.
1316-
if (SemaRef.LoopVectorClauseLoc.isValid()) {
1317-
// This handles the 'inner loop' diagnostic, but we cannot set that we're on
1318-
// one of these until we get to the end of the construct.
1319-
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1320-
<< OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1321-
<< /*skip kernels construct info*/ 0;
1322-
SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1323-
diag::note_acc_previous_clause_here);
1324-
return nullptr;
1366+
// OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1367+
// contain a loop with a gang, worker, or vector clause unless within a
1368+
// nested compute region.
1369+
if (SemaRef.LoopVectorClauseLoc.isValid()) {
1370+
// This handles the 'inner loop' diagnostic, but we cannot set that we're
1371+
// on one of these until we get to the end of the construct.
1372+
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1373+
<< OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1374+
<< /*skip kernels construct info*/ 0;
1375+
SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1376+
diag::note_acc_previous_clause_here);
1377+
return nullptr;
1378+
}
13251379
}
13261380

13271381
return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(),

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,35 @@ void foo() {
313313
// CHECK-NEXT: ;
314314
#pragma acc serial loop gang(static:*)
315315
for(int i = 0;i<5;++i);
316+
317+
// CHECK: #pragma acc parallel loop worker
318+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
319+
// CHECK-NEXT: ;
320+
#pragma acc parallel loop worker
321+
for(int i = 0;i<5;++i);
322+
323+
// CHECK-NEXT: #pragma acc parallel loop worker
324+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
325+
// CHECK-NEXT: ;
326+
#pragma acc parallel loop worker
327+
for(int i = 0;i<5;++i);
328+
329+
// CHECK-NEXT: #pragma acc serial loop worker
330+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
331+
// CHECK-NEXT: ;
332+
#pragma acc serial loop worker
333+
for(int i = 0;i<5;++i);
334+
335+
// CHECK-NEXT: #pragma acc kernels loop worker(num: 5)
336+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
337+
// CHECK-NEXT: ;
338+
#pragma acc kernels loop worker(5)
339+
for(int i = 0;i<5;++i);
340+
341+
// CHECK-NEXT: #pragma acc kernels loop worker(num: 5)
342+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
343+
// CHECK-NEXT: ;
344+
#pragma acc kernels loop worker(num:5)
345+
for(int i = 0;i<5;++i);
346+
316347
}

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ void uses() {
4646
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
4747
#pragma acc parallel loop auto if_present
4848
for(unsigned i = 0; i < 5; ++i);
49-
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
5049
#pragma acc parallel loop auto worker
5150
for(unsigned i = 0; i < 5; ++i);
5251
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
@@ -166,7 +165,6 @@ void uses() {
166165
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
167166
#pragma acc parallel loop if_present auto
168167
for(unsigned i = 0; i < 5; ++i);
169-
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
170168
#pragma acc parallel loop worker auto
171169
for(unsigned i = 0; i < 5; ++i);
172170
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
@@ -287,7 +285,6 @@ void uses() {
287285
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
288286
#pragma acc parallel loop independent if_present
289287
for(unsigned i = 0; i < 5; ++i);
290-
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
291288
#pragma acc parallel loop independent worker
292289
for(unsigned i = 0; i < 5; ++i);
293290
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
@@ -407,7 +404,6 @@ void uses() {
407404
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
408405
#pragma acc parallel loop if_present independent
409406
for(unsigned i = 0; i < 5; ++i);
410-
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
411407
#pragma acc parallel loop worker independent
412408
for(unsigned i = 0; i < 5; ++i);
413409
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
@@ -650,9 +646,8 @@ void uses() {
650646
// expected-note@+1{{previous clause is here}}
651647
#pragma acc parallel loop gang 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 'worker' clause on a 'parallel loop' construct}}
654-
// TODOexpected-note@+1{{previous clause is here}}
655-
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
649+
// expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'worker' clause on a 'parallel loop' construct}}
650+
// expected-note@+1{{previous clause is here}}
656651
#pragma acc parallel loop worker seq
657652
for(unsigned i = 0; i < 5; ++i);
658653
// TODOexpected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'vector' clause on a 'parallel loop' construct}}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ void uses() {
5757
for(int i = 0; i < 5; ++i);
5858
#pragma acc kernels loop device_type(*) auto
5959
for(int i = 0; i < 5; ++i);
60-
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
6160
#pragma acc parallel loop device_type(*) worker
6261
for(int i = 0; i < 5; ++i);
6362
// expected-error@+2{{OpenACC clause 'nohost' may not follow a 'device_type' clause in a 'serial loop' construct}}

clang/test/SemaOpenACC/combined-construct-gang-ast.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
32

43
// Test this with PCH.

0 commit comments

Comments
 (0)