Skip to content

Commit fbb14dd

Browse files
committed
[OpenACC] Implement 'use_device' clause AST/Sema
This is a clause that is only valid on 'host_data' constructs, and identifies variables which it should use the current device address. From a Sema perspective, the only thing novel here is mild changes to how ActOnVar works for this clause, else this is very much like the rest of the 'var-list' clauses.
1 parent 11d2911 commit fbb14dd

35 files changed

+312
-101
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,27 @@ class OpenACCDeleteClause final
788788
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
789789
};
790790

791+
class OpenACCUseDeviceClause final
792+
: public OpenACCClauseWithVarList,
793+
public llvm::TrailingObjects<OpenACCUseDeviceClause, Expr *> {
794+
795+
OpenACCUseDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
796+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
797+
: OpenACCClauseWithVarList(OpenACCClauseKind::UseDevice, BeginLoc,
798+
LParenLoc, EndLoc) {
799+
std::uninitialized_copy(VarList.begin(), VarList.end(),
800+
getTrailingObjects<Expr *>());
801+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
802+
}
803+
804+
public:
805+
static bool classof(const OpenACCClause *C) {
806+
return C->getClauseKind() == OpenACCClauseKind::UseDevice;
807+
}
808+
static OpenACCUseDeviceClause *
809+
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
810+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
811+
};
791812

792813
class OpenACCNoCreateClause final
793814
: public OpenACCClauseWithVarList,

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12682,6 +12682,9 @@ def err_acc_not_a_var_ref
1268212682
: Error<"OpenACC variable is not a valid variable name, sub-array, array "
1268312683
"element,%select{| member of a composite variable,}0 or composite "
1268412684
"variable member">;
12685+
def err_acc_not_a_var_ref_use_device
12686+
: Error<"OpenACC variable in 'use_device' clause is not a valid variable "
12687+
"name or array name">;
1268512688
def err_acc_typecheck_subarray_value
1268612689
: Error<"OpenACC sub-array subscripted value is not an array or pointer">;
1268712690
def err_acc_subarray_function_type

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ VISIT_CLAUSE(Reduction)
5858
VISIT_CLAUSE(Self)
5959
VISIT_CLAUSE(Seq)
6060
VISIT_CLAUSE(Tile)
61+
VISIT_CLAUSE(UseDevice)
6162
VISIT_CLAUSE(Vector)
6263
VISIT_CLAUSE(VectorLength)
6364
VISIT_CLAUSE(Wait)

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ class SemaOpenACC : public SemaBase {
400400
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
401401
ClauseKind == OpenACCClauseKind::Attach ||
402402
ClauseKind == OpenACCClauseKind::Delete ||
403+
ClauseKind == OpenACCClauseKind::UseDevice ||
403404
ClauseKind == OpenACCClauseKind::Detach ||
404405
ClauseKind == OpenACCClauseKind::DevicePtr ||
405406
ClauseKind == OpenACCClauseKind::Reduction ||
@@ -538,6 +539,7 @@ class SemaOpenACC : public SemaBase {
538539
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
539540
ClauseKind == OpenACCClauseKind::Attach ||
540541
ClauseKind == OpenACCClauseKind::Delete ||
542+
ClauseKind == OpenACCClauseKind::UseDevice ||
541543
ClauseKind == OpenACCClauseKind::Detach ||
542544
ClauseKind == OpenACCClauseKind::DevicePtr ||
543545
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
@@ -576,6 +578,7 @@ class SemaOpenACC : public SemaBase {
576578
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
577579
ClauseKind == OpenACCClauseKind::Attach ||
578580
ClauseKind == OpenACCClauseKind::Delete ||
581+
ClauseKind == OpenACCClauseKind::UseDevice ||
579582
ClauseKind == OpenACCClauseKind::Detach ||
580583
ClauseKind == OpenACCClauseKind::DevicePtr ||
581584
ClauseKind == OpenACCClauseKind::FirstPrivate) &&

clang/lib/AST/OpenACCClause.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) {
3333
OpenACCFirstPrivateClause::classof(C) ||
3434
OpenACCDevicePtrClause::classof(C) ||
3535
OpenACCDeleteClause::classof(C) ||
36+
OpenACCUseDeviceClause::classof(C) ||
3637
OpenACCDetachClause::classof(C) || OpenACCAttachClause::classof(C) ||
3738
OpenACCNoCreateClause::classof(C) ||
3839
OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) ||
@@ -298,6 +299,16 @@ OpenACCDeleteClause *OpenACCDeleteClause::Create(const ASTContext &C,
298299
return new (Mem) OpenACCDeleteClause(BeginLoc, LParenLoc, VarList, EndLoc);
299300
}
300301

302+
OpenACCUseDeviceClause *OpenACCUseDeviceClause::Create(const ASTContext &C,
303+
SourceLocation BeginLoc,
304+
SourceLocation LParenLoc,
305+
ArrayRef<Expr *> VarList,
306+
SourceLocation EndLoc) {
307+
void *Mem = C.Allocate(
308+
OpenACCUseDeviceClause::totalSizeToAlloc<Expr *>(VarList.size()));
309+
return new (Mem) OpenACCUseDeviceClause(BeginLoc, LParenLoc, VarList, EndLoc);
310+
}
311+
301312
OpenACCDevicePtrClause *OpenACCDevicePtrClause::Create(const ASTContext &C,
302313
SourceLocation BeginLoc,
303314
SourceLocation LParenLoc,
@@ -581,6 +592,14 @@ void OpenACCClausePrinter::VisitDeleteClause(const OpenACCDeleteClause &C) {
581592
OS << ")";
582593
}
583594

595+
void OpenACCClausePrinter::VisitUseDeviceClause(
596+
const OpenACCUseDeviceClause &C) {
597+
OS << "use_device(";
598+
llvm::interleaveComma(C.getVarList(), OS,
599+
[&](const Expr *E) { printExpr(E); });
600+
OS << ")";
601+
}
602+
584603
void OpenACCClausePrinter::VisitDevicePtrClause(
585604
const OpenACCDevicePtrClause &C) {
586605
OS << "deviceptr(";

clang/lib/AST/StmtProfile.cpp

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,11 @@ class OpenACCClauseProfiler
25152515
}
25162516
}
25172517

2518+
void VisitClauseWithVarList(const OpenACCClauseWithVarList &Clause) {
2519+
for (auto *E : Clause.getVarList())
2520+
Profiler.VisitStmt(E);
2521+
}
2522+
25182523
#define VISIT_CLAUSE(CLAUSE_NAME) \
25192524
void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
25202525

@@ -2532,25 +2537,21 @@ void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) {
25322537
}
25332538

25342539
void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
2535-
for (auto *E : Clause.getVarList())
2536-
Profiler.VisitStmt(E);
2540+
VisitClauseWithVarList(Clause);
25372541
}
25382542
void OpenACCClauseProfiler::VisitCopyInClause(
25392543
const OpenACCCopyInClause &Clause) {
2540-
for (auto *E : Clause.getVarList())
2541-
Profiler.VisitStmt(E);
2544+
VisitClauseWithVarList(Clause);
25422545
}
25432546

25442547
void OpenACCClauseProfiler::VisitCopyOutClause(
25452548
const OpenACCCopyOutClause &Clause) {
2546-
for (auto *E : Clause.getVarList())
2547-
Profiler.VisitStmt(E);
2549+
VisitClauseWithVarList(Clause);
25482550
}
25492551

25502552
void OpenACCClauseProfiler::VisitCreateClause(
25512553
const OpenACCCreateClause &Clause) {
2552-
for (auto *E : Clause.getVarList())
2553-
Profiler.VisitStmt(E);
2554+
VisitClauseWithVarList(Clause);
25542555
}
25552556

25562557
void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
@@ -2589,50 +2590,47 @@ void OpenACCClauseProfiler::VisitCollapseClause(
25892590

25902591
void OpenACCClauseProfiler::VisitPrivateClause(
25912592
const OpenACCPrivateClause &Clause) {
2592-
for (auto *E : Clause.getVarList())
2593-
Profiler.VisitStmt(E);
2593+
VisitClauseWithVarList(Clause);
25942594
}
25952595

25962596
void OpenACCClauseProfiler::VisitFirstPrivateClause(
25972597
const OpenACCFirstPrivateClause &Clause) {
2598-
for (auto *E : Clause.getVarList())
2599-
Profiler.VisitStmt(E);
2598+
VisitClauseWithVarList(Clause);
26002599
}
26012600

26022601
void OpenACCClauseProfiler::VisitAttachClause(
26032602
const OpenACCAttachClause &Clause) {
2604-
for (auto *E : Clause.getVarList())
2605-
Profiler.VisitStmt(E);
2603+
VisitClauseWithVarList(Clause);
26062604
}
26072605

26082606
void OpenACCClauseProfiler::VisitDetachClause(
26092607
const OpenACCDetachClause &Clause) {
2610-
for (auto *E : Clause.getVarList())
2611-
Profiler.VisitStmt(E);
2608+
VisitClauseWithVarList(Clause);
26122609
}
26132610

26142611
void OpenACCClauseProfiler::VisitDeleteClause(
26152612
const OpenACCDeleteClause &Clause) {
2616-
for (auto *E : Clause.getVarList())
2617-
Profiler.VisitStmt(E);
2613+
VisitClauseWithVarList(Clause);
26182614
}
26192615

26202616
void OpenACCClauseProfiler::VisitDevicePtrClause(
26212617
const OpenACCDevicePtrClause &Clause) {
2622-
for (auto *E : Clause.getVarList())
2623-
Profiler.VisitStmt(E);
2618+
VisitClauseWithVarList(Clause);
26242619
}
26252620

26262621
void OpenACCClauseProfiler::VisitNoCreateClause(
26272622
const OpenACCNoCreateClause &Clause) {
2628-
for (auto *E : Clause.getVarList())
2629-
Profiler.VisitStmt(E);
2623+
VisitClauseWithVarList(Clause);
26302624
}
26312625

26322626
void OpenACCClauseProfiler::VisitPresentClause(
26332627
const OpenACCPresentClause &Clause) {
2634-
for (auto *E : Clause.getVarList())
2635-
Profiler.VisitStmt(E);
2628+
VisitClauseWithVarList(Clause);
2629+
}
2630+
2631+
void OpenACCClauseProfiler::VisitUseDeviceClause(
2632+
const OpenACCUseDeviceClause &Clause) {
2633+
VisitClauseWithVarList(Clause);
26362634
}
26372635

26382636
void OpenACCClauseProfiler::VisitVectorLengthClause(
@@ -2684,8 +2682,7 @@ void OpenACCClauseProfiler::VisitGangClause(const OpenACCGangClause &Clause) {
26842682

26852683
void OpenACCClauseProfiler::VisitReductionClause(
26862684
const OpenACCReductionClause &Clause) {
2687-
for (auto *E : Clause.getVarList())
2688-
Profiler.VisitStmt(E);
2685+
VisitClauseWithVarList(Clause);
26892686
}
26902687
} // namespace
26912688

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
425425
case OpenACCClauseKind::Seq:
426426
case OpenACCClauseKind::Tile:
427427
case OpenACCClauseKind::Worker:
428+
case OpenACCClauseKind::UseDevice:
428429
case OpenACCClauseKind::Vector:
429430
case OpenACCClauseKind::VectorLength:
430431
// The condition expression will be printed as a part of the 'children',

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,13 +1002,13 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
10021002
case OpenACCClauseKind::DeviceResident:
10031003
case OpenACCClauseKind::Host:
10041004
case OpenACCClauseKind::Link:
1005-
case OpenACCClauseKind::UseDevice:
10061005
ParseOpenACCVarList(ClauseKind);
10071006
break;
10081007
case OpenACCClauseKind::Attach:
10091008
case OpenACCClauseKind::Delete:
10101009
case OpenACCClauseKind::Detach:
10111010
case OpenACCClauseKind::DevicePtr:
1011+
case OpenACCClauseKind::UseDevice:
10121012
ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind),
10131013
/*IsReadOnly=*/false, /*IsZero=*/false);
10141014
break;

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,15 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
442442
return false;
443443
}
444444
}
445+
446+
case OpenACCClauseKind::UseDevice: {
447+
switch (DirectiveKind) {
448+
case OpenACCDirectiveKind::HostData:
449+
return true;
450+
default:
451+
return false;
452+
}
453+
}
445454
}
446455

447456
default:
@@ -1085,6 +1094,14 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(
10851094
Clause.getEndLoc());
10861095
}
10871096

1097+
OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(
1098+
SemaOpenACC::OpenACCParsedClause &Clause) {
1099+
// ActOnVar ensured that everything is a valid variable or array, so nothing
1100+
// left to do here.
1101+
return OpenACCUseDeviceClause::Create(
1102+
Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1103+
Clause.getEndLoc());
1104+
}
10881105

10891106
OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
10901107
SemaOpenACC::OpenACCParsedClause &Clause) {
@@ -2431,6 +2448,15 @@ bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind,
24312448
ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) {
24322449
Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
24332450

2451+
// 'use_device' doesn't allow array subscript or array sections.
2452+
// OpenACC3.3 2.8:
2453+
// A 'var' in a 'use_device' clause must be the name of a variable or array.
2454+
if (CK == OpenACCClauseKind::UseDevice &&
2455+
isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
2456+
Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
2457+
return ExprError();
2458+
}
2459+
24342460
// Sub-arrays/subscript-exprs are fine as long as the base is a
24352461
// VarExpr/MemberExpr. So strip all of those off.
24362462
while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
@@ -2451,16 +2477,20 @@ ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) {
24512477
// If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a
24522478
// reduction clause must be a scalar variable name, an aggregate variable
24532479
// name, an array element, or a subarray.
2454-
// A MemberExpr that references a Field is valid.
2455-
if (CK != OpenACCClauseKind::Reduction) {
2480+
// If CK is a 'use_device', this also isn't valid, as it isn' the name of a
2481+
// variable or array.
2482+
// A MemberExpr that references a Field is valid for other clauses.
2483+
if (CK != OpenACCClauseKind::Reduction &&
2484+
CK != OpenACCClauseKind::UseDevice) {
24562485
if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
24572486
if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
24582487
return VarExpr;
24592488
}
24602489
}
24612490

2462-
// Referring to 'this' is always OK.
2463-
if (isa<CXXThisExpr>(CurVarExpr))
2491+
// Referring to 'this' is ok for the most part, but for 'use_device' doesn't
2492+
// fall into 'variable or array name'
2493+
if (CK != OpenACCClauseKind::UseDevice && isa<CXXThisExpr>(CurVarExpr))
24642494
return VarExpr;
24652495

24662496
// Nothing really we can do here, as these are dependent. So just return they
@@ -2475,8 +2505,11 @@ ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) {
24752505
if (isa<RecoveryExpr>(CurVarExpr))
24762506
return ExprError();
24772507

2478-
Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
2479-
<< (CK != OpenACCClauseKind::Reduction);
2508+
if (CK == OpenACCClauseKind::UseDevice)
2509+
Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
2510+
else
2511+
Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
2512+
<< (CK != OpenACCClauseKind::Reduction);
24802513
return ExprError();
24812514
}
24822515

clang/lib/Sema/TreeTransform.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11788,6 +11788,17 @@ void OpenACCClauseTransform<Derived>::VisitDeleteClause(
1178811788
ParsedClause.getEndLoc());
1178911789
}
1179011790

11791+
template <typename Derived>
11792+
void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
11793+
const OpenACCUseDeviceClause &C) {
11794+
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11795+
/*IsReadOnly=*/false, /*IsZero=*/false);
11796+
NewClause = OpenACCUseDeviceClause::Create(
11797+
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11798+
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11799+
ParsedClause.getEndLoc());
11800+
}
11801+
1179111802
template <typename Derived>
1179211803
void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
1179311804
const OpenACCDevicePtrClause &C) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12441,6 +12441,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1244112441
return OpenACCDeleteClause::Create(getContext(), BeginLoc, LParenLoc,
1244212442
VarList, EndLoc);
1244312443
}
12444+
case OpenACCClauseKind::UseDevice: {
12445+
SourceLocation LParenLoc = readSourceLocation();
12446+
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
12447+
return OpenACCUseDeviceClause::Create(getContext(), BeginLoc, LParenLoc,
12448+
VarList, EndLoc);
12449+
}
1244412450
case OpenACCClauseKind::DevicePtr: {
1244512451
SourceLocation LParenLoc = readSourceLocation();
1244612452
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
@@ -12583,7 +12589,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1258312589
}
1258412590

1258512591
case OpenACCClauseKind::NoHost:
12586-
case OpenACCClauseKind::UseDevice:
1258712592
case OpenACCClauseKind::Device:
1258812593
case OpenACCClauseKind::DeviceResident:
1258912594
case OpenACCClauseKind::Host:

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8368,6 +8368,12 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
83688368
writeOpenACCVarList(DC);
83698369
return;
83708370
}
8371+
case OpenACCClauseKind::UseDevice: {
8372+
const auto *UDC = cast<OpenACCUseDeviceClause>(C);
8373+
writeSourceLocation(UDC->getLParenLoc());
8374+
writeOpenACCVarList(UDC);
8375+
return;
8376+
}
83718377
case OpenACCClauseKind::DevicePtr: {
83728378
const auto *DPC = cast<OpenACCDevicePtrClause>(C);
83738379
writeSourceLocation(DPC->getLParenLoc());
@@ -8511,7 +8517,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
85118517
}
85128518

85138519
case OpenACCClauseKind::NoHost:
8514-
case OpenACCClauseKind::UseDevice:
85158520
case OpenACCClauseKind::Device:
85168521
case OpenACCClauseKind::DeviceResident:
85178522
case OpenACCClauseKind::Host:

0 commit comments

Comments
 (0)