Skip to content

Commit bd909d2

Browse files
committed
[OpenACC] Implement no_create and present clauses on compute constructs
These two are, from a semantic checking perspective, identical to first-private/private/etc, other than appertainment. This patch implements both.
1 parent 6517c5b commit bd909d2

19 files changed

+605
-12
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,44 @@ class OpenACCFirstPrivateClause final
313313
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
314314
};
315315

316+
class OpenACCNoCreateClause final
317+
: public OpenACCClauseWithVarList,
318+
public llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
319+
320+
OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
321+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
322+
: OpenACCClauseWithVarList(OpenACCClauseKind::NoCreate, BeginLoc,
323+
LParenLoc, EndLoc) {
324+
std::uninitialized_copy(VarList.begin(), VarList.end(),
325+
getTrailingObjects<Expr *>());
326+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
327+
}
328+
329+
public:
330+
static OpenACCNoCreateClause *
331+
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
332+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
333+
};
334+
335+
class OpenACCPresentClause final
336+
: public OpenACCClauseWithVarList,
337+
public llvm::TrailingObjects<OpenACCPresentClause, Expr *> {
338+
339+
OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
340+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
341+
: OpenACCClauseWithVarList(OpenACCClauseKind::Present, BeginLoc,
342+
LParenLoc, EndLoc) {
343+
std::uninitialized_copy(VarList.begin(), VarList.end(),
344+
getTrailingObjects<Expr *>());
345+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
346+
}
347+
348+
public:
349+
static OpenACCPresentClause *
350+
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
351+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
352+
};
353+
316354
template <class Impl> class OpenACCClauseVisitor {
317355
Impl &getDerived() { return static_cast<Impl &>(*this); }
318356

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
VISIT_CLAUSE(Default)
1919
VISIT_CLAUSE(FirstPrivate)
2020
VISIT_CLAUSE(If)
21+
VISIT_CLAUSE(NoCreate)
2122
VISIT_CLAUSE(NumGangs)
2223
VISIT_CLAUSE(NumWorkers)
24+
VISIT_CLAUSE(Present)
2325
VISIT_CLAUSE(Private)
2426
VISIT_CLAUSE(Self)
2527
VISIT_CLAUSE(VectorLength)

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ class SemaOpenACC : public SemaBase {
118118

119119
ArrayRef<Expr *> getVarList() {
120120
assert((ClauseKind == OpenACCClauseKind::Private ||
121+
ClauseKind == OpenACCClauseKind::NoCreate ||
122+
ClauseKind == OpenACCClauseKind::Present ||
121123
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
122124
"Parsed clause kind does not have a var-list");
123125
return std::get<VarListDetails>(Details).VarList;
@@ -167,13 +169,17 @@ class SemaOpenACC : public SemaBase {
167169

168170
void setVarListDetails(ArrayRef<Expr *> VarList) {
169171
assert((ClauseKind == OpenACCClauseKind::Private ||
172+
ClauseKind == OpenACCClauseKind::NoCreate ||
173+
ClauseKind == OpenACCClauseKind::Present ||
170174
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
171175
"Parsed clause kind does not have a var-list");
172176
Details = VarListDetails{{VarList.begin(), VarList.end()}};
173177
}
174178

175179
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList) {
176180
assert((ClauseKind == OpenACCClauseKind::Private ||
181+
ClauseKind == OpenACCClauseKind::NoCreate ||
182+
ClauseKind == OpenACCClauseKind::Present ||
177183
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
178184
"Parsed clause kind does not have a var-list");
179185
Details = VarListDetails{std::move(VarList)};

clang/lib/AST/OpenACCClause.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,26 @@ OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create(
153153
OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
154154
}
155155

156+
OpenACCNoCreateClause *OpenACCNoCreateClause::Create(const ASTContext &C,
157+
SourceLocation BeginLoc,
158+
SourceLocation LParenLoc,
159+
ArrayRef<Expr *> VarList,
160+
SourceLocation EndLoc) {
161+
void *Mem = C.Allocate(
162+
OpenACCNoCreateClause::totalSizeToAlloc<Expr *>(VarList.size()));
163+
return new (Mem) OpenACCNoCreateClause(BeginLoc, LParenLoc, VarList, EndLoc);
164+
}
165+
166+
OpenACCPresentClause *OpenACCPresentClause::Create(const ASTContext &C,
167+
SourceLocation BeginLoc,
168+
SourceLocation LParenLoc,
169+
ArrayRef<Expr *> VarList,
170+
SourceLocation EndLoc) {
171+
void *Mem = C.Allocate(
172+
OpenACCPresentClause::totalSizeToAlloc<Expr *>(VarList.size()));
173+
return new (Mem) OpenACCPresentClause(BeginLoc, LParenLoc, VarList, EndLoc);
174+
}
175+
156176
//===----------------------------------------------------------------------===//
157177
// OpenACC clauses printing methods
158178
//===----------------------------------------------------------------------===//
@@ -215,3 +235,17 @@ void OpenACCClausePrinter::VisitFirstPrivateClause(
215235
[&](const Expr *E) { printExpr(E); });
216236
OS << ")";
217237
}
238+
239+
void OpenACCClausePrinter::VisitNoCreateClause(const OpenACCNoCreateClause &C) {
240+
OS << "no_create(";
241+
llvm::interleaveComma(C.getVarList(), OS,
242+
[&](const Expr *E) { printExpr(E); });
243+
OS << ")";
244+
}
245+
246+
void OpenACCClausePrinter::VisitPresentClause(const OpenACCPresentClause &C) {
247+
OS << "present(";
248+
llvm::interleaveComma(C.getVarList(), OS,
249+
[&](const Expr *E) { printExpr(E); });
250+
OS << ")";
251+
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,6 +2521,18 @@ void OpenACCClauseProfiler::VisitFirstPrivateClause(
25212521
Profiler.VisitStmt(E);
25222522
}
25232523

2524+
void OpenACCClauseProfiler::VisitNoCreateClause(
2525+
const OpenACCNoCreateClause &Clause) {
2526+
for (auto *E : Clause.getVarList())
2527+
Profiler.VisitStmt(E);
2528+
}
2529+
2530+
void OpenACCClauseProfiler::VisitPresentClause(
2531+
const OpenACCPresentClause &Clause) {
2532+
for (auto *E : Clause.getVarList())
2533+
Profiler.VisitStmt(E);
2534+
}
2535+
25242536
void OpenACCClauseProfiler::VisitVectorLengthClause(
25252537
const OpenACCVectorLengthClause &Clause) {
25262538
assert(Clause.hasIntExpr() &&

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,10 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
399399
break;
400400
case OpenACCClauseKind::If:
401401
case OpenACCClauseKind::FirstPrivate:
402+
case OpenACCClauseKind::NoCreate:
402403
case OpenACCClauseKind::NumGangs:
403404
case OpenACCClauseKind::NumWorkers:
405+
case OpenACCClauseKind::Present:
404406
case OpenACCClauseKind::Private:
405407
case OpenACCClauseKind::Self:
406408
case OpenACCClauseKind::VectorLength:

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -928,12 +928,12 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
928928
case OpenACCClauseKind::DevicePtr:
929929
case OpenACCClauseKind::Host:
930930
case OpenACCClauseKind::Link:
931-
case OpenACCClauseKind::NoCreate:
932-
case OpenACCClauseKind::Present:
933931
case OpenACCClauseKind::UseDevice:
934932
ParseOpenACCVarList();
935933
break;
936934
case OpenACCClauseKind::FirstPrivate:
935+
case OpenACCClauseKind::NoCreate:
936+
case OpenACCClauseKind::Present:
937937
case OpenACCClauseKind::Private:
938938
ParsedClause.setVarListDetails(ParseOpenACCVarList());
939939
break;

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,33 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
126126
default:
127127
return false;
128128
}
129+
case OpenACCClauseKind::NoCreate:
130+
switch (DirectiveKind) {
131+
case OpenACCDirectiveKind::Parallel:
132+
case OpenACCDirectiveKind::Serial:
133+
case OpenACCDirectiveKind::Kernels:
134+
case OpenACCDirectiveKind::Data:
135+
case OpenACCDirectiveKind::ParallelLoop:
136+
case OpenACCDirectiveKind::SerialLoop:
137+
case OpenACCDirectiveKind::KernelsLoop:
138+
return true;
139+
default:
140+
return false;
141+
}
142+
case OpenACCClauseKind::Present:
143+
switch (DirectiveKind) {
144+
case OpenACCDirectiveKind::Parallel:
145+
case OpenACCDirectiveKind::Serial:
146+
case OpenACCDirectiveKind::Kernels:
147+
case OpenACCDirectiveKind::Data:
148+
case OpenACCDirectiveKind::Declare:
149+
case OpenACCDirectiveKind::ParallelLoop:
150+
case OpenACCDirectiveKind::SerialLoop:
151+
case OpenACCDirectiveKind::KernelsLoop:
152+
return true;
153+
default:
154+
return false;
155+
}
129156
default:
130157
// Do nothing so we can go to the 'unimplemented' diagnostic instead.
131158
return true;
@@ -356,6 +383,36 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
356383
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
357384
Clause.getVarList(), Clause.getEndLoc());
358385
}
386+
case OpenACCClauseKind::NoCreate: {
387+
// Restrictions only properly implemented on 'compute' constructs, and
388+
// 'compute' constructs are the only construct that can do anything with
389+
// this yet, so skip/treat as unimplemented in this case.
390+
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
391+
break;
392+
393+
// ActOnVar ensured that everything is a valid variable reference, so there
394+
// really isn't anything to do here. GCC does some duplicate-finding, though
395+
// it isn't apparent in the standard where this is justified.
396+
397+
return OpenACCNoCreateClause::Create(
398+
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
399+
Clause.getVarList(), Clause.getEndLoc());
400+
}
401+
case OpenACCClauseKind::Present: {
402+
// Restrictions only properly implemented on 'compute' constructs, and
403+
// 'compute' constructs are the only construct that can do anything with
404+
// this yet, so skip/treat as unimplemented in this case.
405+
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
406+
break;
407+
408+
// ActOnVar ensured that everything is a valid variable reference, so there
409+
// really isn't anything to do here. GCC does some duplicate-finding, though
410+
// it isn't apparent in the standard where this is justified.
411+
412+
return OpenACCPresentClause::Create(
413+
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
414+
Clause.getVarList(), Clause.getEndLoc());
415+
}
359416
default:
360417
break;
361418
}

clang/lib/Sema/TreeTransform.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11242,6 +11242,28 @@ void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
1124211242
ParsedClause.getEndLoc());
1124311243
}
1124411244

11245+
template <typename Derived>
11246+
void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11247+
const OpenACCNoCreateClause &C) {
11248+
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()));
11249+
11250+
NewClause = OpenACCNoCreateClause::Create(
11251+
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11252+
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11253+
ParsedClause.getEndLoc());
11254+
}
11255+
11256+
template <typename Derived>
11257+
void OpenACCClauseTransform<Derived>::VisitPresentClause(
11258+
const OpenACCPresentClause &C) {
11259+
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()));
11260+
11261+
NewClause = OpenACCPresentClause::Create(
11262+
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11263+
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11264+
ParsedClause.getEndLoc());
11265+
}
11266+
1124511267
template <typename Derived>
1124611268
void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
1124711269
const OpenACCNumWorkersClause &C) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11841,6 +11841,18 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1184111841
return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
1184211842
VarList, EndLoc);
1184311843
}
11844+
case OpenACCClauseKind::NoCreate: {
11845+
SourceLocation LParenLoc = readSourceLocation();
11846+
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
11847+
return OpenACCNoCreateClause::Create(getContext(), BeginLoc, LParenLoc,
11848+
VarList, EndLoc);
11849+
}
11850+
case OpenACCClauseKind::Present: {
11851+
SourceLocation LParenLoc = readSourceLocation();
11852+
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
11853+
return OpenACCPresentClause::Create(getContext(), BeginLoc, LParenLoc,
11854+
VarList, EndLoc);
11855+
}
1184411856
case OpenACCClauseKind::Finalize:
1184511857
case OpenACCClauseKind::IfPresent:
1184611858
case OpenACCClauseKind::Seq:
@@ -11859,8 +11871,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1185911871
case OpenACCClauseKind::DeviceResident:
1186011872
case OpenACCClauseKind::Host:
1186111873
case OpenACCClauseKind::Link:
11862-
case OpenACCClauseKind::NoCreate:
11863-
case OpenACCClauseKind::Present:
1186411874
case OpenACCClauseKind::CopyOut:
1186511875
case OpenACCClauseKind::CopyIn:
1186611876
case OpenACCClauseKind::Create:

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7793,6 +7793,18 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
77937793
writeOpenACCVarList(FPC);
77947794
return;
77957795
}
7796+
case OpenACCClauseKind::NoCreate: {
7797+
const auto *NCC = cast<OpenACCNoCreateClause>(C);
7798+
writeSourceLocation(NCC->getLParenLoc());
7799+
writeOpenACCVarList(NCC);
7800+
return;
7801+
}
7802+
case OpenACCClauseKind::Present: {
7803+
const auto *PC = cast<OpenACCPresentClause>(C);
7804+
writeSourceLocation(PC->getLParenLoc());
7805+
writeOpenACCVarList(PC);
7806+
return;
7807+
}
77967808
case OpenACCClauseKind::Finalize:
77977809
case OpenACCClauseKind::IfPresent:
77987810
case OpenACCClauseKind::Seq:
@@ -7811,8 +7823,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
78117823
case OpenACCClauseKind::DeviceResident:
78127824
case OpenACCClauseKind::Host:
78137825
case OpenACCClauseKind::Link:
7814-
case OpenACCClauseKind::NoCreate:
7815-
case OpenACCClauseKind::Present:
78167826
case OpenACCClauseKind::CopyOut:
78177827
case OpenACCClauseKind::CopyIn:
78187828
case OpenACCClauseKind::Create:

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,16 @@ void foo() {
4242
// CHECK: #pragma acc parallel firstprivate(i, array[1], array, array[1:2])
4343
#pragma acc parallel firstprivate(i, array[1], array, array[1:2])
4444
while(true);
45+
46+
// CHECK: #pragma acc parallel no_create(i, array[1], array, array[1:2])
47+
#pragma acc parallel no_create(i, array[1], array, array[1:2])
48+
while(true);
49+
50+
// CHECK: #pragma acc parallel present(i, array[1], array, array[1:2])
51+
#pragma acc parallel present(i, array[1], array, array[1:2])
52+
while(true);
53+
// CHECK: #pragma acc parallel no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
54+
#pragma acc parallel no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
55+
while(true);
4556
}
4657

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -534,24 +534,20 @@ void VarListClauses() {
534534
#pragma acc serial use_device(s.array[s.value : 5]), seq
535535
for(;;){}
536536

537-
// expected-error@+3{{expected ','}}
538-
// expected-warning@+2{{OpenACC clause 'no_create' not yet implemented, clause ignored}}
537+
// expected-error@+2{{expected ','}}
539538
// expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
540539
#pragma acc serial no_create(s.array[s.value] s.array[s.value :5] ), seq
541540
for(;;){}
542541

543-
// expected-warning@+2{{OpenACC clause 'no_create' not yet implemented, clause ignored}}
544542
// expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
545543
#pragma acc serial no_create(s.array[s.value : 5], s.value), seq
546544
for(;;){}
547545

548-
// expected-error@+3{{expected ','}}
549-
// expected-warning@+2{{OpenACC clause 'present' not yet implemented, clause ignored}}
546+
// expected-error@+2{{expected ','}}
550547
// expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
551548
#pragma acc serial present(s.array[s.value] s.array[s.value :5] ), seq
552549
for(;;){}
553550

554-
// expected-warning@+2{{OpenACC clause 'present' not yet implemented, clause ignored}}
555551
// expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
556552
#pragma acc serial present(s.array[s.value : 5], s.value), seq
557553
for(;;){}

0 commit comments

Comments
 (0)