Skip to content

Commit 3351b3b

Browse files
committed
[OpenACC] implement 'detach' clause sema
This is another new clause specific to 'exit data' that takes a pointer argument. This patch implements this the same way we do a few other clauses (like attach) that have the same restrictions.
1 parent 3273d0b commit 3351b3b

22 files changed

+269
-31
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,28 @@ class OpenACCAttachClause final
744744
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
745745
};
746746

747+
class OpenACCDetachClause final
748+
: public OpenACCClauseWithVarList,
749+
public llvm::TrailingObjects<OpenACCDetachClause, Expr *> {
750+
751+
OpenACCDetachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
752+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
753+
: OpenACCClauseWithVarList(OpenACCClauseKind::Detach, BeginLoc, LParenLoc,
754+
EndLoc) {
755+
std::uninitialized_copy(VarList.begin(), VarList.end(),
756+
getTrailingObjects<Expr *>());
757+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
758+
}
759+
760+
public:
761+
static bool classof(const OpenACCClause *C) {
762+
return C->getClauseKind() == OpenACCClauseKind::Detach;
763+
}
764+
static OpenACCDetachClause *
765+
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
766+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
767+
};
768+
747769
class OpenACCNoCreateClause final
748770
: public OpenACCClauseWithVarList,
749771
public llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ VISIT_CLAUSE(Create)
3838
CLAUSE_ALIAS(PCreate, Create, true)
3939
CLAUSE_ALIAS(PresentOrCreate, Create, true)
4040
VISIT_CLAUSE(Default)
41+
VISIT_CLAUSE(Detach)
4142
VISIT_CLAUSE(DevicePtr)
4243
VISIT_CLAUSE(DeviceType)
4344
CLAUSE_ALIAS(DType, DeviceType, false)

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ class SemaOpenACC : public SemaBase {
399399
ClauseKind == OpenACCClauseKind::PCreate ||
400400
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
401401
ClauseKind == OpenACCClauseKind::Attach ||
402+
ClauseKind == OpenACCClauseKind::Detach ||
402403
ClauseKind == OpenACCClauseKind::DevicePtr ||
403404
ClauseKind == OpenACCClauseKind::Reduction ||
404405
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
@@ -535,6 +536,7 @@ class SemaOpenACC : public SemaBase {
535536
ClauseKind == OpenACCClauseKind::PCreate ||
536537
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
537538
ClauseKind == OpenACCClauseKind::Attach ||
539+
ClauseKind == OpenACCClauseKind::Detach ||
538540
ClauseKind == OpenACCClauseKind::DevicePtr ||
539541
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
540542
"Parsed clause kind does not have a var-list");
@@ -571,6 +573,7 @@ class SemaOpenACC : public SemaBase {
571573
ClauseKind == OpenACCClauseKind::PCreate ||
572574
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
573575
ClauseKind == OpenACCClauseKind::Attach ||
576+
ClauseKind == OpenACCClauseKind::Detach ||
574577
ClauseKind == OpenACCClauseKind::DevicePtr ||
575578
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
576579
"Parsed clause kind does not have a var-list");

clang/lib/AST/OpenACCClause.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) {
3333
OpenACCFirstPrivateClause::classof(C) ||
3434
OpenACCDevicePtrClause::classof(C) ||
3535
OpenACCDevicePtrClause::classof(C) ||
36-
OpenACCAttachClause::classof(C) || OpenACCNoCreateClause::classof(C) ||
36+
OpenACCDetachClause::classof(C) || OpenACCAttachClause::classof(C) ||
37+
OpenACCNoCreateClause::classof(C) ||
3738
OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) ||
3839
OpenACCCopyInClause::classof(C) || OpenACCCopyOutClause::classof(C) ||
3940
OpenACCReductionClause::classof(C) || OpenACCCreateClause::classof(C);
@@ -277,6 +278,16 @@ OpenACCAttachClause *OpenACCAttachClause::Create(const ASTContext &C,
277278
return new (Mem) OpenACCAttachClause(BeginLoc, LParenLoc, VarList, EndLoc);
278279
}
279280

281+
OpenACCDetachClause *OpenACCDetachClause::Create(const ASTContext &C,
282+
SourceLocation BeginLoc,
283+
SourceLocation LParenLoc,
284+
ArrayRef<Expr *> VarList,
285+
SourceLocation EndLoc) {
286+
void *Mem =
287+
C.Allocate(OpenACCDetachClause::totalSizeToAlloc<Expr *>(VarList.size()));
288+
return new (Mem) OpenACCDetachClause(BeginLoc, LParenLoc, VarList, EndLoc);
289+
}
290+
280291
OpenACCDevicePtrClause *OpenACCDevicePtrClause::Create(const ASTContext &C,
281292
SourceLocation BeginLoc,
282293
SourceLocation LParenLoc,
@@ -546,6 +557,13 @@ void OpenACCClausePrinter::VisitAttachClause(const OpenACCAttachClause &C) {
546557
OS << ")";
547558
}
548559

560+
void OpenACCClausePrinter::VisitDetachClause(const OpenACCDetachClause &C) {
561+
OS << "detach(";
562+
llvm::interleaveComma(C.getVarList(), OS,
563+
[&](const Expr *E) { printExpr(E); });
564+
OS << ")";
565+
}
566+
549567
void OpenACCClausePrinter::VisitDevicePtrClause(
550568
const OpenACCDevicePtrClause &C) {
551569
OS << "deviceptr(";

clang/lib/AST/StmtProfile.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,6 +2605,12 @@ void OpenACCClauseProfiler::VisitAttachClause(
26052605
Profiler.VisitStmt(E);
26062606
}
26072607

2608+
void OpenACCClauseProfiler::VisitDetachClause(
2609+
const OpenACCDetachClause &Clause) {
2610+
for (auto *E : Clause.getVarList())
2611+
Profiler.VisitStmt(E);
2612+
}
2613+
26082614
void OpenACCClauseProfiler::VisitDevicePtrClause(
26092615
const OpenACCDevicePtrClause &Clause) {
26102616
for (auto *E : Clause.getVarList())

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
411411
case OpenACCClauseKind::If:
412412
case OpenACCClauseKind::IfPresent:
413413
case OpenACCClauseKind::Independent:
414+
case OpenACCClauseKind::Detach:
414415
case OpenACCClauseKind::DevicePtr:
415416
case OpenACCClauseKind::Finalize:
416417
case OpenACCClauseKind::FirstPrivate:

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,6 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
999999
assert(DirKind == OpenACCDirectiveKind::Update);
10001000
[[fallthrough]];
10011001
case OpenACCClauseKind::Delete:
1002-
case OpenACCClauseKind::Detach:
10031002
case OpenACCClauseKind::Device:
10041003
case OpenACCClauseKind::DeviceResident:
10051004
case OpenACCClauseKind::Host:
@@ -1008,6 +1007,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
10081007
ParseOpenACCVarList(ClauseKind);
10091008
break;
10101009
case OpenACCClauseKind::Attach:
1010+
case OpenACCClauseKind::Detach:
10111011
case OpenACCClauseKind::DevicePtr:
10121012
ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind),
10131013
/*IsReadOnly=*/false, /*IsZero=*/false);

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,14 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
425425
return false;
426426
}
427427
}
428+
case OpenACCClauseKind::Detach: {
429+
switch (DirectiveKind) {
430+
case OpenACCDirectiveKind::ExitData:
431+
return true;
432+
default:
433+
return false;
434+
}
435+
}
428436
}
429437

430438
default:
@@ -1043,6 +1051,21 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
10431051
Clause.getEndLoc());
10441052
}
10451053

1054+
OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
1055+
SemaOpenACC::OpenACCParsedClause &Clause) {
1056+
// ActOnVar ensured that everything is a valid variable reference, but we
1057+
// still have to make sure it is a pointer type.
1058+
llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1059+
llvm::erase_if(VarList, [&](Expr *E) {
1060+
return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E);
1061+
});
1062+
Clause.setVarListDetails(VarList,
1063+
/*IsReadOnly=*/false, /*IsZero=*/false);
1064+
return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(),
1065+
Clause.getLParenLoc(), Clause.getVarList(),
1066+
Clause.getEndLoc());
1067+
}
1068+
10461069
OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
10471070
SemaOpenACC::OpenACCParsedClause &Clause) {
10481071
// Restrictions only properly implemented on 'compute'/'combined'/'data'

clang/lib/Sema/TreeTransform.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11755,6 +11755,28 @@ void OpenACCClauseTransform<Derived>::VisitAttachClause(
1175511755
ParsedClause.getEndLoc());
1175611756
}
1175711757

11758+
template <typename Derived>
11759+
void OpenACCClauseTransform<Derived>::VisitDetachClause(
11760+
const OpenACCDetachClause &C) {
11761+
llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11762+
11763+
// Ensure each var is a pointer type.
11764+
VarList.erase(
11765+
std::remove_if(VarList.begin(), VarList.end(),
11766+
[&](Expr *E) {
11767+
return Self.getSema().OpenACC().CheckVarIsPointerType(
11768+
OpenACCClauseKind::Detach, E);
11769+
}),
11770+
VarList.end());
11771+
11772+
ParsedClause.setVarListDetails(VarList,
11773+
/*IsReadOnly=*/false, /*IsZero=*/false);
11774+
NewClause = OpenACCDetachClause::Create(
11775+
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11776+
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11777+
ParsedClause.getEndLoc());
11778+
}
11779+
1175811780
template <typename Derived>
1175911781
void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
1176011782
const OpenACCDevicePtrClause &C) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12442,6 +12442,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1244212442
return OpenACCAttachClause::Create(getContext(), BeginLoc, LParenLoc,
1244312443
VarList, EndLoc);
1244412444
}
12445+
case OpenACCClauseKind::Detach: {
12446+
SourceLocation LParenLoc = readSourceLocation();
12447+
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
12448+
return OpenACCDetachClause::Create(getContext(), BeginLoc, LParenLoc,
12449+
VarList, EndLoc);
12450+
}
1244512451
case OpenACCClauseKind::DevicePtr: {
1244612452
SourceLocation LParenLoc = readSourceLocation();
1244712453
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
@@ -12586,7 +12592,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1258612592
case OpenACCClauseKind::NoHost:
1258712593
case OpenACCClauseKind::UseDevice:
1258812594
case OpenACCClauseKind::Delete:
12589-
case OpenACCClauseKind::Detach:
1259012595
case OpenACCClauseKind::Device:
1259112596
case OpenACCClauseKind::DeviceResident:
1259212597
case OpenACCClauseKind::Host:

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8356,6 +8356,12 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
83568356
writeOpenACCVarList(AC);
83578357
return;
83588358
}
8359+
case OpenACCClauseKind::Detach: {
8360+
const auto *DC = cast<OpenACCDetachClause>(C);
8361+
writeSourceLocation(DC->getLParenLoc());
8362+
writeOpenACCVarList(DC);
8363+
return;
8364+
}
83598365
case OpenACCClauseKind::DevicePtr: {
83608366
const auto *DPC = cast<OpenACCDevicePtrClause>(C);
83618367
writeSourceLocation(DPC->getLParenLoc());
@@ -8501,7 +8507,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
85018507
case OpenACCClauseKind::NoHost:
85028508
case OpenACCClauseKind::UseDevice:
85038509
case OpenACCClauseKind::Delete:
8504-
case OpenACCClauseKind::Detach:
85058510
case OpenACCClauseKind::Device:
85068511
case OpenACCClauseKind::DeviceResident:
85078512
case OpenACCClauseKind::Host:

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,7 @@ void foo() {
117117
// CHECK: #pragma acc host_data if_present
118118
#pragma acc host_data use_device(i) if_present
119119
;
120+
// CHECK: #pragma acc exit data copyout(i) detach(iPtr, arrayPtr[0])
121+
#pragma acc exit data copyout(i) detach(iPtr, arrayPtr[0])
122+
120123
}

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -488,14 +488,13 @@ void VarListClauses() {
488488
#pragma acc serial attach(IsPointer), self
489489
for(int i = 0; i < 5;++i) {}
490490

491-
// expected-error@+2{{expected ','}}
492-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented, clause ignored}}
493-
#pragma acc serial detach(s.array[s.value] s.array[s.value :5] ), self
494-
for(int i = 0; i < 5;++i) {}
491+
// expected-error@+4{{expected ','}}
492+
// expected-error@+3{{expected pointer in 'detach' clause, type is 'char'}}
493+
// expected-error@+2{{OpenACC sub-array is not allowed here}}
494+
// expected-note@+1{{expected variable of pointer type}}
495+
#pragma acc exit data copyout(s) detach(s.array[s.value] s.array[s.value :5])
495496

496-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented, clause ignored}}
497-
#pragma acc serial detach(s.array[s.value : 5], s.value), self
498-
for(int i = 0; i < 5;++i) {}
497+
#pragma acc exit data copyout(s) detach(IsPointer)
499498

500499
// expected-error@+1{{expected ','}}
501500
#pragma acc serial private(s.array[s.value] s.array[s.value :5] ), self

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void uses() {
7272
// expected-warning@+1{{OpenACC clause 'delete' not yet implemented}}
7373
#pragma acc parallel loop auto delete(Var)
7474
for(unsigned i = 0; i < 5; ++i);
75-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented}}
75+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
7676
#pragma acc parallel loop auto detach(Var)
7777
for(unsigned i = 0; i < 5; ++i);
7878
// expected-warning@+1{{OpenACC clause 'device' not yet implemented}}
@@ -189,7 +189,7 @@ void uses() {
189189
// expected-warning@+1{{OpenACC clause 'delete' not yet implemented}}
190190
#pragma acc parallel loop delete(Var) auto
191191
for(unsigned i = 0; i < 5; ++i);
192-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented}}
192+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
193193
#pragma acc parallel loop detach(Var) auto
194194
for(unsigned i = 0; i < 5; ++i);
195195
// expected-warning@+1{{OpenACC clause 'device' not yet implemented}}
@@ -307,7 +307,7 @@ void uses() {
307307
// expected-warning@+1{{OpenACC clause 'delete' not yet implemented}}
308308
#pragma acc parallel loop independent delete(Var)
309309
for(unsigned i = 0; i < 5; ++i);
310-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented}}
310+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
311311
#pragma acc parallel loop independent detach(Var)
312312
for(unsigned i = 0; i < 5; ++i);
313313
// expected-warning@+1{{OpenACC clause 'device' not yet implemented}}
@@ -424,7 +424,7 @@ void uses() {
424424
// expected-warning@+1{{OpenACC clause 'delete' not yet implemented}}
425425
#pragma acc parallel loop delete(Var) independent
426426
for(unsigned i = 0; i < 5; ++i);
427-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented}}
427+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
428428
#pragma acc parallel loop detach(Var) independent
429429
for(unsigned i = 0; i < 5; ++i);
430430
// expected-warning@+1{{OpenACC clause 'device' not yet implemented}}
@@ -550,7 +550,7 @@ void uses() {
550550
// expected-warning@+1{{OpenACC clause 'delete' not yet implemented}}
551551
#pragma acc parallel loop seq delete(Var)
552552
for(unsigned i = 0; i < 5; ++i);
553-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented}}
553+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
554554
#pragma acc parallel loop seq detach(Var)
555555
for(unsigned i = 0; i < 5; ++i);
556556
// expected-warning@+1{{OpenACC clause 'device' not yet implemented}}
@@ -673,7 +673,7 @@ void uses() {
673673
// expected-warning@+1{{OpenACC clause 'delete' not yet implemented}}
674674
#pragma acc parallel loop delete(Var) seq
675675
for(unsigned i = 0; i < 5; ++i);
676-
// expected-warning@+1{{OpenACC clause 'detach' not yet implemented}}
676+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
677677
#pragma acc parallel loop detach(Var) seq
678678
for(unsigned i = 0; i < 5; ++i);
679679
// expected-warning@+1{{OpenACC clause 'device' 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
@@ -99,8 +99,7 @@ void uses() {
9999
// expected-note@+1{{previous clause is here}}
100100
#pragma acc serial loop device_type(*) delete(Var)
101101
for(int i = 0; i < 5; ++i);
102-
// expected-error@+2{{OpenACC clause 'detach' may not follow a 'device_type' clause in a 'kernels loop' construct}}
103-
// expected-note@+1{{previous clause is here}}
102+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'kernels loop' directive}}
104103
#pragma acc kernels loop device_type(*) detach(Var)
105104
for(int i = 0; i < 5; ++i);
106105
// expected-error@+2{{OpenACC clause 'device' may not follow a 'device_type' clause in a 'parallel 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
@@ -103,8 +103,7 @@ void uses() {
103103
// expected-note@+1{{previous clause is here}}
104104
#pragma acc kernels device_type(*) delete(Var)
105105
while(1);
106-
// expected-error@+2{{OpenACC clause 'detach' may not follow a 'device_type' clause in a 'kernels' construct}}
107-
// expected-note@+1{{previous clause is here}}
106+
// expected-error@+1{{OpenACC 'detach' clause is not valid on 'kernels' directive}}
108107
#pragma acc kernels device_type(*) detach(Var)
109108
while(1);
110109
// expected-error@+2{{OpenACC clause 'device' may not follow a 'device_type' clause in a 'kernels' construct}}

0 commit comments

Comments
 (0)