Skip to content

Commit bdf2555

Browse files
committed
[OpenACC] Implement 'device_num' clause sema for 'init'/'shutdown'
This is a very simple sema implementation, and just required AST node plus the existing diagnostics. This patch adds tests and adds the AST node required, plus enables it for 'init' and 'shutdown' (only!)
1 parent 4bbdb01 commit bdf2555

24 files changed

+197
-48
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,20 @@ class OpenACCAsyncClause : public OpenACCClauseWithSingleIntExpr {
619619
SourceLocation EndLoc);
620620
};
621621

622+
class OpenACCDeviceNumClause : public OpenACCClauseWithSingleIntExpr {
623+
OpenACCDeviceNumClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
624+
Expr *IntExpr, SourceLocation EndLoc);
625+
626+
public:
627+
static bool classof(const OpenACCClause *C) {
628+
return C->getClauseKind() == OpenACCClauseKind::DeviceNum;
629+
}
630+
static OpenACCDeviceNumClause *Create(const ASTContext &C,
631+
SourceLocation BeginLoc,
632+
SourceLocation LParenLoc, Expr *IntExpr,
633+
SourceLocation EndLoc);
634+
};
635+
622636
/// Represents a 'collapse' clause on a 'loop' construct. This clause takes an
623637
/// integer constant expression 'N' that represents how deep to collapse the
624638
/// construct. It also takes an optional 'force' tag that permits intervening

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ CLAUSE_ALIAS(PresentOrCreate, Create, true)
4040
VISIT_CLAUSE(Default)
4141
VISIT_CLAUSE(Delete)
4242
VISIT_CLAUSE(Detach)
43+
VISIT_CLAUSE(DeviceNum)
4344
VISIT_CLAUSE(DevicePtr)
4445
VISIT_CLAUSE(DeviceType)
4546
CLAUSE_ALIAS(DType, DeviceType, false)

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,15 @@ class SemaOpenACC : public SemaBase {
296296
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
297297
ClauseKind == OpenACCClauseKind::NumWorkers ||
298298
ClauseKind == OpenACCClauseKind::Async ||
299+
ClauseKind == OpenACCClauseKind::DeviceNum ||
299300
ClauseKind == OpenACCClauseKind::Tile ||
300301
ClauseKind == OpenACCClauseKind::Worker ||
301302
ClauseKind == OpenACCClauseKind::Vector ||
302303
ClauseKind == OpenACCClauseKind::VectorLength) &&
303304
"Parsed clause kind does not have a int exprs");
304305

305-
// 'async' and 'wait' have an optional IntExpr, so be tolerant of that.
306+
// 'async', 'worker', 'vector', and 'wait' have an optional IntExpr, so be
307+
// tolerant of that.
306308
if ((ClauseKind == OpenACCClauseKind::Async ||
307309
ClauseKind == OpenACCClauseKind::Worker ||
308310
ClauseKind == OpenACCClauseKind::Vector ||
@@ -346,6 +348,7 @@ class SemaOpenACC : public SemaBase {
346348
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
347349
ClauseKind == OpenACCClauseKind::NumWorkers ||
348350
ClauseKind == OpenACCClauseKind::Async ||
351+
ClauseKind == OpenACCClauseKind::DeviceNum ||
349352
ClauseKind == OpenACCClauseKind::Tile ||
350353
ClauseKind == OpenACCClauseKind::Gang ||
351354
ClauseKind == OpenACCClauseKind::Worker ||
@@ -482,6 +485,7 @@ class SemaOpenACC : public SemaBase {
482485
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
483486
ClauseKind == OpenACCClauseKind::NumWorkers ||
484487
ClauseKind == OpenACCClauseKind::Async ||
488+
ClauseKind == OpenACCClauseKind::DeviceNum ||
485489
ClauseKind == OpenACCClauseKind::Tile ||
486490
ClauseKind == OpenACCClauseKind::Worker ||
487491
ClauseKind == OpenACCClauseKind::Vector ||
@@ -493,6 +497,7 @@ class SemaOpenACC : public SemaBase {
493497
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
494498
ClauseKind == OpenACCClauseKind::NumWorkers ||
495499
ClauseKind == OpenACCClauseKind::Async ||
500+
ClauseKind == OpenACCClauseKind::DeviceNum ||
496501
ClauseKind == OpenACCClauseKind::Tile ||
497502
ClauseKind == OpenACCClauseKind::Worker ||
498503
ClauseKind == OpenACCClauseKind::Vector ||

clang/lib/AST/OpenACCClause.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ bool OpenACCClauseWithCondition::classof(const OpenACCClause *C) {
4646
bool OpenACCClauseWithSingleIntExpr::classof(const OpenACCClause *C) {
4747
return OpenACCNumWorkersClause::classof(C) ||
4848
OpenACCVectorLengthClause::classof(C) ||
49+
OpenACCDeviceNumClause::classof(C) ||
4950
OpenACCVectorClause::classof(C) || OpenACCWorkerClause::classof(C) ||
5051
OpenACCCollapseClause::classof(C) || OpenACCAsyncClause::classof(C);
5152
}
@@ -218,6 +219,26 @@ OpenACCAsyncClause *OpenACCAsyncClause::Create(const ASTContext &C,
218219
return new (Mem) OpenACCAsyncClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
219220
}
220221

222+
OpenACCDeviceNumClause::OpenACCDeviceNumClause(SourceLocation BeginLoc,
223+
SourceLocation LParenLoc, Expr *IntExpr,
224+
SourceLocation EndLoc)
225+
: OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::DeviceNum, BeginLoc,
226+
LParenLoc, IntExpr, EndLoc) {
227+
assert((IntExpr->isInstantiationDependent() ||
228+
IntExpr->getType()->isIntegerType()) &&
229+
"device_num expression type not scalar/dependent");
230+
}
231+
232+
OpenACCDeviceNumClause *OpenACCDeviceNumClause::Create(const ASTContext &C,
233+
SourceLocation BeginLoc,
234+
SourceLocation LParenLoc,
235+
Expr *IntExpr,
236+
SourceLocation EndLoc) {
237+
void *Mem =
238+
C.Allocate(sizeof(OpenACCDeviceNumClause), alignof(OpenACCDeviceNumClause));
239+
return new (Mem) OpenACCDeviceNumClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
240+
}
241+
221242
OpenACCWaitClause *OpenACCWaitClause::Create(
222243
const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
223244
Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
@@ -547,6 +568,13 @@ void OpenACCClausePrinter::VisitVectorLengthClause(
547568
OS << ")";
548569
}
549570

571+
void OpenACCClausePrinter::VisitDeviceNumClause(
572+
const OpenACCDeviceNumClause &C) {
573+
OS << "device_num(";
574+
printExpr(C.getIntExpr());
575+
OS << ")";
576+
}
577+
550578
void OpenACCClausePrinter::VisitAsyncClause(const OpenACCAsyncClause &C) {
551579
OS << "async";
552580
if (C.hasIntExpr()) {

clang/lib/AST/StmtProfile.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,6 +2645,11 @@ void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
26452645
Profiler.VisitStmt(Clause.getIntExpr());
26462646
}
26472647

2648+
void OpenACCClauseProfiler::VisitDeviceNumClause(
2649+
const OpenACCDeviceNumClause &Clause) {
2650+
Profiler.VisitStmt(Clause.getIntExpr());
2651+
}
2652+
26482653
void OpenACCClauseProfiler::VisitWorkerClause(
26492654
const OpenACCWorkerClause &Clause) {
26502655
if (Clause.hasIntExpr())

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
413413
case OpenACCClauseKind::Independent:
414414
case OpenACCClauseKind::Detach:
415415
case OpenACCClauseKind::Delete:
416+
case OpenACCClauseKind::DeviceNum:
416417
case OpenACCClauseKind::DevicePtr:
417418
case OpenACCClauseKind::Finalize:
418419
case OpenACCClauseKind::FirstPrivate:

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
10851085
// TODO OpenACC: as we implement the 'rest' of the above, this 'if' should
10861086
// be removed leaving just the 'setIntExprDetails'.
10871087
if (ClauseKind == OpenACCClauseKind::NumWorkers ||
1088+
ClauseKind == OpenACCClauseKind::DeviceNum ||
10881089
ClauseKind == OpenACCClauseKind::VectorLength)
10891090
ParsedClause.setIntExprDetails(IntExpr.get());
10901091

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,17 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
444444
}
445445
}
446446

447+
case OpenACCClauseKind::DeviceNum: {
448+
switch (DirectiveKind) {
449+
case OpenACCDirectiveKind::Init:
450+
case OpenACCDirectiveKind::Shutdown:
451+
case OpenACCDirectiveKind::Set:
452+
return true;
453+
default:
454+
return false;
455+
}
456+
}
457+
447458
case OpenACCClauseKind::UseDevice: {
448459
switch (DirectiveKind) {
449460
case OpenACCDirectiveKind::HostData:
@@ -945,6 +956,20 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
945956
Clause.getEndLoc());
946957
}
947958

959+
OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(
960+
SemaOpenACC::OpenACCParsedClause &Clause) {
961+
// Restrictions only properly implemented on certain constructs, so skip/treat
962+
// as unimplemented in those cases.
963+
if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
964+
return isNotImplemented();
965+
966+
assert(Clause.getNumIntExprs() == 1 &&
967+
"Invalid number of expressions for device_num");
968+
return OpenACCDeviceNumClause::Create(
969+
Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
970+
Clause.getEndLoc());
971+
}
972+
948973
OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
949974
SemaOpenACC::OpenACCParsedClause &Clause) {
950975
// ActOnVar ensured that everything is a valid variable reference, so there

clang/lib/Sema/TreeTransform.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11877,6 +11877,29 @@ void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
1187711877
ParsedClause.getEndLoc());
1187811878
}
1187911879

11880+
template <typename Derived>
11881+
void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
11882+
const OpenACCDeviceNumClause &C) {
11883+
Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11884+
assert(IntExpr && "device_num clause constructed with invalid int expr");
11885+
11886+
ExprResult Res = Self.TransformExpr(IntExpr);
11887+
if (!Res.isUsable())
11888+
return;
11889+
11890+
Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11891+
C.getClauseKind(),
11892+
C.getBeginLoc(), Res.get());
11893+
if (!Res.isUsable())
11894+
return;
11895+
11896+
ParsedClause.setIntExprDetails(Res.get());
11897+
NewClause = OpenACCDeviceNumClause::Create(
11898+
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11899+
ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11900+
ParsedClause.getEndLoc());
11901+
}
11902+
1188011903
template <typename Derived>
1188111904
void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
1188211905
const OpenACCVectorLengthClause &C) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12405,6 +12405,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1240512405
return OpenACCNumWorkersClause::Create(getContext(), BeginLoc, LParenLoc,
1240612406
IntExpr, EndLoc);
1240712407
}
12408+
case OpenACCClauseKind::DeviceNum: {
12409+
SourceLocation LParenLoc = readSourceLocation();
12410+
Expr *IntExpr = readSubExpr();
12411+
return OpenACCDeviceNumClause::Create(getContext(), BeginLoc, LParenLoc,
12412+
IntExpr, EndLoc);
12413+
}
1240812414
case OpenACCClauseKind::VectorLength: {
1240912415
SourceLocation LParenLoc = readSourceLocation();
1241012416
Expr *IntExpr = readSubExpr();
@@ -12594,7 +12600,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1259412600
case OpenACCClauseKind::Host:
1259512601
case OpenACCClauseKind::Link:
1259612602
case OpenACCClauseKind::Bind:
12597-
case OpenACCClauseKind::DeviceNum:
1259812603
case OpenACCClauseKind::DefaultAsync:
1259912604
case OpenACCClauseKind::Invalid:
1260012605
llvm_unreachable("Clause serialization not yet implemented");

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8326,6 +8326,12 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
83268326
AddStmt(E);
83278327
return;
83288328
}
8329+
case OpenACCClauseKind::DeviceNum: {
8330+
const auto *DNC = cast<OpenACCDeviceNumClause>(C);
8331+
writeSourceLocation(DNC->getLParenLoc());
8332+
AddStmt(const_cast<Expr*>(DNC->getIntExpr()));
8333+
return;
8334+
}
83298335
case OpenACCClauseKind::NumWorkers: {
83308336
const auto *NWC = cast<OpenACCNumWorkersClause>(C);
83318337
writeSourceLocation(NWC->getLParenLoc());
@@ -8522,7 +8528,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
85228528
case OpenACCClauseKind::Host:
85238529
case OpenACCClauseKind::Link:
85248530
case OpenACCClauseKind::Bind:
8525-
case OpenACCClauseKind::DeviceNum:
85268531
case OpenACCClauseKind::DefaultAsync:
85278532
case OpenACCClauseKind::Invalid:
85288533
llvm_unreachable("Clause serialization not yet implemented");

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
unsigned Int;
44

55
void uses() {
6-
// CHECK: #pragma acc init device_type(*) if(Int == 5)
6+
// CHECK: #pragma acc init device_type(*) device_num(Int) if(Int == 5)
77
#pragma acc init device_type(*) device_num(Int) if (Int == 5)
8-
// CHECK: #pragma acc init device_type(*)
9-
// CHECK-NOT: device_num(Int)
8+
// CHECK: #pragma acc init device_type(*) device_num(Int)
109
#pragma acc init device_type(*) device_num(Int)
1110
// CHECK: #pragma acc init device_type(*) if(Int == 5)
1211
#pragma acc init device_type(*) if (Int == 5)

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
unsigned Int;
44

55
void uses() {
6-
// CHECK: #pragma acc shutdown device_type(*) if(Int == 5)
6+
// CHECK: #pragma acc shutdown device_type(*) device_num(Int) if(Int == 5)
77
#pragma acc shutdown device_type(*) device_num(Int) if (Int == 5)
8-
// CHECK: #pragma acc shutdown device_type(*)
9-
// CHECK-NOT: device_num(Int)
8+
// CHECK: #pragma acc shutdown device_type(*) device_num(Int)
109
#pragma acc shutdown device_type(*) device_num(Int)
1110
// CHECK: #pragma acc shutdown device_type(*) if(Int == 5)
1211
#pragma acc shutdown device_type(*) if (Int == 5)

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -816,10 +816,8 @@ void IntExprParsing() {
816816
// expected-note@+1{{to match this '('}}
817817
#pragma acc init device_num(5, 4)
818818

819-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented, clause ignored}}
820819
#pragma acc init device_num(5)
821820

822-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented, clause ignored}}
823821
#pragma acc init device_num(returns_int())
824822

825823
// expected-error@+2{{expected '('}}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void uses() {
134134
for(unsigned i = 0; i < 5; ++i);
135135
#pragma acc parallel loop auto num_workers(1)
136136
for(unsigned i = 0; i < 5; ++i);
137-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}}
137+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'parallel loop' directive}}
138138
#pragma acc parallel loop auto device_num(1)
139139
for(unsigned i = 0; i < 5; ++i);
140140
// expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}}
@@ -251,7 +251,7 @@ void uses() {
251251
for(unsigned i = 0; i < 5; ++i);
252252
#pragma acc parallel loop num_workers(1) auto
253253
for(unsigned i = 0; i < 5; ++i);
254-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}}
254+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'parallel loop' directive}}
255255
#pragma acc parallel loop device_num(1) auto
256256
for(unsigned i = 0; i < 5; ++i);
257257
// expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}}
@@ -369,7 +369,7 @@ void uses() {
369369
for(unsigned i = 0; i < 5; ++i);
370370
#pragma acc parallel loop independent num_workers(1)
371371
for(unsigned i = 0; i < 5; ++i);
372-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}}
372+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'parallel loop' directive}}
373373
#pragma acc parallel loop independent device_num(1)
374374
for(unsigned i = 0; i < 5; ++i);
375375
// expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}}
@@ -486,7 +486,7 @@ void uses() {
486486
for(unsigned i = 0; i < 5; ++i);
487487
#pragma acc parallel loop num_workers(1) independent
488488
for(unsigned i = 0; i < 5; ++i);
489-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}}
489+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'parallel loop' directive}}
490490
#pragma acc parallel loop device_num(1) independent
491491
for(unsigned i = 0; i < 5; ++i);
492492
// expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}}
@@ -612,7 +612,7 @@ void uses() {
612612
for(unsigned i = 0; i < 5; ++i);
613613
#pragma acc parallel loop seq num_workers(1)
614614
for(unsigned i = 0; i < 5; ++i);
615-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}}
615+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'parallel loop' directive}}
616616
#pragma acc parallel loop seq device_num(1)
617617
for(unsigned i = 0; i < 5; ++i);
618618
// expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}}
@@ -735,7 +735,7 @@ void uses() {
735735
for(unsigned i = 0; i < 5; ++i);
736736
#pragma acc parallel loop num_workers(1) seq
737737
for(unsigned i = 0; i < 5; ++i);
738-
// expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}}
738+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'parallel loop' directive}}
739739
#pragma acc parallel loop device_num(1) seq
740740
for(unsigned i = 0; i < 5; ++i);
741741
// expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,7 @@ void uses() {
190190
for(int i = 0; i < 5; ++i);
191191
#pragma acc parallel loop device_type(*) num_workers(1)
192192
for(int i = 0; i < 5; ++i);
193-
// expected-error@+2{{OpenACC clause 'device_num' may not follow a 'device_type' clause in a 'serial loop' construct}}
194-
// expected-note@+1{{previous clause is here}}
193+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'serial loop' directive}}
195194
#pragma acc serial loop device_type(*) device_num(1)
196195
for(int i = 0; i < 5; ++i);
197196
// expected-error@+2{{OpenACC clause 'default_async' may not follow a 'device_type' clause in a 'serial loop' construct}}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,7 @@ void uses() {
195195
while(1);
196196
#pragma acc kernels device_type(*) num_workers(1)
197197
while(1);
198-
// expected-error@+2{{OpenACC clause 'device_num' may not follow a 'device_type' clause in a 'kernels' construct}}
199-
// expected-note@+1{{previous clause is here}}
198+
// expected-error@+1{{OpenACC 'device_num' clause is not valid on 'kernels' directive}}
200199
#pragma acc kernels device_type(*) device_num(1)
201200
while(1);
202201
// expected-error@+2{{OpenACC clause 'default_async' may not follow a 'device_type' clause in a 'kernels' construct}}

0 commit comments

Comments
 (0)