Skip to content

Commit 01e91a2

Browse files
committed
[OpenACC] Implement copyin, copyout, create clauses for compute construct
Like 'copy', these also have alternate names, so this implements that as well. Additionally, these have an optional tag of either 'readonly' or 'zero' depending on the clause. Otherwise, this is a pretty rote implementation of the clause, as there aren't any special rules for it.
1 parent 40cc96e commit 01e91a2

22 files changed

+1268
-74
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,87 @@ class OpenACCCopyClause final
375375
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
376376
};
377377

378+
class OpenACCCopyInClause final
379+
: public OpenACCClauseWithVarList,
380+
public llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
381+
bool IsReadOnly;
382+
383+
OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
384+
SourceLocation LParenLoc, bool IsReadOnly,
385+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
386+
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
387+
IsReadOnly(IsReadOnly) {
388+
assert((Spelling == OpenACCClauseKind::CopyIn ||
389+
Spelling == OpenACCClauseKind::PCopyIn ||
390+
Spelling == OpenACCClauseKind::PresentOrCopyIn) &&
391+
"Invalid clause kind for copyin-clause");
392+
std::uninitialized_copy(VarList.begin(), VarList.end(),
393+
getTrailingObjects<Expr *>());
394+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
395+
}
396+
397+
public:
398+
bool isReadOnly() const { return IsReadOnly; }
399+
static OpenACCCopyInClause *
400+
Create(const ASTContext &C, OpenACCClauseKind Spelling,
401+
SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly,
402+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
403+
};
404+
405+
class OpenACCCopyOutClause final
406+
: public OpenACCClauseWithVarList,
407+
public llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
408+
bool IsZero;
409+
410+
OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
411+
SourceLocation LParenLoc, bool IsZero,
412+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
413+
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
414+
IsZero(IsZero) {
415+
assert((Spelling == OpenACCClauseKind::CopyOut ||
416+
Spelling == OpenACCClauseKind::PCopyOut ||
417+
Spelling == OpenACCClauseKind::PresentOrCopyOut) &&
418+
"Invalid clause kind for copyout-clause");
419+
std::uninitialized_copy(VarList.begin(), VarList.end(),
420+
getTrailingObjects<Expr *>());
421+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
422+
}
423+
424+
public:
425+
bool isZero() const { return IsZero; }
426+
static OpenACCCopyOutClause *
427+
Create(const ASTContext &C, OpenACCClauseKind Spelling,
428+
SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero,
429+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
430+
};
431+
432+
class OpenACCCreateClause final
433+
: public OpenACCClauseWithVarList,
434+
public llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
435+
bool IsZero;
436+
437+
OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
438+
SourceLocation LParenLoc, bool IsZero,
439+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
440+
: OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
441+
IsZero(IsZero) {
442+
assert((Spelling == OpenACCClauseKind::Create ||
443+
Spelling == OpenACCClauseKind::PCreate ||
444+
Spelling == OpenACCClauseKind::PresentOrCreate) &&
445+
"Invalid clause kind for create-clause");
446+
std::uninitialized_copy(VarList.begin(), VarList.end(),
447+
getTrailingObjects<Expr *>());
448+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
449+
}
450+
451+
public:
452+
bool isZero() const { return IsZero; }
453+
static OpenACCCreateClause *
454+
Create(const ASTContext &C, OpenACCClauseKind Spelling,
455+
SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero,
456+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
457+
};
458+
378459
template <class Impl> class OpenACCClauseVisitor {
379460
Impl &getDerived() { return static_cast<Impl &>(*this); }
380461

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
VISIT_CLAUSE(Copy)
2525
CLAUSE_ALIAS(PCopy, Copy)
2626
CLAUSE_ALIAS(PresentOrCopy, Copy)
27+
VISIT_CLAUSE(CopyIn)
28+
CLAUSE_ALIAS(PCopyIn, CopyIn)
29+
CLAUSE_ALIAS(PresentOrCopyIn, CopyIn)
30+
VISIT_CLAUSE(CopyOut)
31+
CLAUSE_ALIAS(PCopyOut, CopyOut)
32+
CLAUSE_ALIAS(PresentOrCopyOut, CopyOut)
33+
VISIT_CLAUSE(Create)
34+
CLAUSE_ALIAS(PCreate, Create)
35+
CLAUSE_ALIAS(PresentOrCreate, Create)
2736
VISIT_CLAUSE(Default)
2837
VISIT_CLAUSE(FirstPrivate)
2938
VISIT_CLAUSE(If)

clang/include/clang/Basic/OpenACCKinds.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,27 @@ enum class OpenACCClauseKind {
228228
/// 'copyout' clause, allowed on Compute and Combined constructs, plus 'data',
229229
/// 'exit data', and 'declare'.
230230
CopyOut,
231+
/// 'copyout' clause alias 'pcopyout'. Preserved for diagnostic purposes.
232+
PCopyOut,
233+
/// 'copyout' clause alias 'present_or_copyout'. Preserved for diagnostic
234+
/// purposes.
235+
PresentOrCopyOut,
231236
/// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
232237
/// 'enter data', and 'declare'.
233238
CopyIn,
234-
/// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
239+
/// 'copyin' clause alias 'pcopyin'. Preserved for diagnostic purposes.
240+
PCopyIn,
241+
/// 'copyin' clause alias 'present_or_copyin'. Preserved for diagnostic
242+
/// purposes.
243+
PresentOrCopyIn,
244+
/// 'create' clause, allowed on Compute and Combined constructs, plus 'data',
235245
/// 'enter data', and 'declare'.
236246
Create,
247+
/// 'create' clause alias 'pcreate'. Preserved for diagnostic purposes.
248+
PCreate,
249+
/// 'create' clause alias 'present_or_create'. Preserved for diagnostic
250+
/// purposes.
251+
PresentOrCreate,
237252
/// 'reduction' clause, allowed on Parallel, Serial, Loop, and the combined
238253
/// constructs.
239254
Reduction,
@@ -362,12 +377,30 @@ inline StreamTy &printOpenACCClauseKind(StreamTy &Out, OpenACCClauseKind K) {
362377
case OpenACCClauseKind::CopyOut:
363378
return Out << "copyout";
364379

380+
case OpenACCClauseKind::PCopyOut:
381+
return Out << "pcopyout";
382+
383+
case OpenACCClauseKind::PresentOrCopyOut:
384+
return Out << "present_or_copyout";
385+
365386
case OpenACCClauseKind::CopyIn:
366387
return Out << "copyin";
367388

389+
case OpenACCClauseKind::PCopyIn:
390+
return Out << "pcopyin";
391+
392+
case OpenACCClauseKind::PresentOrCopyIn:
393+
return Out << "present_or_copyin";
394+
368395
case OpenACCClauseKind::Create:
369396
return Out << "create";
370397

398+
case OpenACCClauseKind::PCreate:
399+
return Out << "pcreate";
400+
401+
case OpenACCClauseKind::PresentOrCreate:
402+
return Out << "present_or_create";
403+
371404
case OpenACCClauseKind::Reduction:
372405
return Out << "reduction";
373406

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class SemaOpenACC : public SemaBase {
5050

5151
struct VarListDetails {
5252
SmallVector<Expr *> VarList;
53+
bool IsReadOnly;
54+
bool IsZero;
5355
};
5456

5557
std::variant<std::monostate, DefaultDetails, ConditionDetails,
@@ -123,6 +125,15 @@ class SemaOpenACC : public SemaBase {
123125
ClauseKind == OpenACCClauseKind::Copy ||
124126
ClauseKind == OpenACCClauseKind::PCopy ||
125127
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
128+
ClauseKind == OpenACCClauseKind::CopyIn ||
129+
ClauseKind == OpenACCClauseKind::PCopyIn ||
130+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
131+
ClauseKind == OpenACCClauseKind::CopyOut ||
132+
ClauseKind == OpenACCClauseKind::PCopyOut ||
133+
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
134+
ClauseKind == OpenACCClauseKind::Create ||
135+
ClauseKind == OpenACCClauseKind::PCreate ||
136+
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
126137
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
127138
"Parsed clause kind does not have a var-list");
128139
return std::get<VarListDetails>(Details).VarList;
@@ -132,6 +143,25 @@ class SemaOpenACC : public SemaBase {
132143
return const_cast<OpenACCParsedClause *>(this)->getVarList();
133144
}
134145

146+
bool isReadOnly() const {
147+
assert((ClauseKind == OpenACCClauseKind::CopyIn ||
148+
ClauseKind == OpenACCClauseKind::PCopyIn ||
149+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
150+
"Only copyin accepts 'readonly:' tag");
151+
return std::get<VarListDetails>(Details).IsReadOnly;
152+
}
153+
154+
bool isZero() const {
155+
assert((ClauseKind == OpenACCClauseKind::CopyOut ||
156+
ClauseKind == OpenACCClauseKind::PCopyOut ||
157+
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
158+
ClauseKind == OpenACCClauseKind::Create ||
159+
ClauseKind == OpenACCClauseKind::PCreate ||
160+
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
161+
"Only copyout/create accepts 'zero' tag");
162+
return std::get<VarListDetails>(Details).IsZero;
163+
}
164+
135165
void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
136166
void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
137167

@@ -170,28 +200,71 @@ class SemaOpenACC : public SemaBase {
170200
Details = IntExprDetails{std::move(IntExprs)};
171201
}
172202

173-
void setVarListDetails(ArrayRef<Expr *> VarList) {
203+
void setVarListDetails(ArrayRef<Expr *> VarList, bool IsReadOnly,
204+
bool IsZero) {
174205
assert((ClauseKind == OpenACCClauseKind::Private ||
175206
ClauseKind == OpenACCClauseKind::NoCreate ||
176207
ClauseKind == OpenACCClauseKind::Present ||
177208
ClauseKind == OpenACCClauseKind::Copy ||
178209
ClauseKind == OpenACCClauseKind::PCopy ||
179210
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
211+
ClauseKind == OpenACCClauseKind::CopyIn ||
212+
ClauseKind == OpenACCClauseKind::PCopyIn ||
213+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
214+
ClauseKind == OpenACCClauseKind::CopyOut ||
215+
ClauseKind == OpenACCClauseKind::PCopyOut ||
216+
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
217+
ClauseKind == OpenACCClauseKind::Create ||
218+
ClauseKind == OpenACCClauseKind::PCreate ||
219+
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
180220
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
181221
"Parsed clause kind does not have a var-list");
182-
Details = VarListDetails{{VarList.begin(), VarList.end()}};
222+
assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
223+
ClauseKind == OpenACCClauseKind::PCopyIn ||
224+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
225+
"readonly: tag only valid on copyin");
226+
assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
227+
ClauseKind == OpenACCClauseKind::PCopyOut ||
228+
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
229+
ClauseKind == OpenACCClauseKind::Create ||
230+
ClauseKind == OpenACCClauseKind::PCreate ||
231+
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
232+
"zero: tag only valid on copyout/create");
233+
Details =
234+
VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
183235
}
184236

185-
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList) {
237+
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, bool IsReadOnly,
238+
bool IsZero) {
186239
assert((ClauseKind == OpenACCClauseKind::Private ||
187240
ClauseKind == OpenACCClauseKind::NoCreate ||
188241
ClauseKind == OpenACCClauseKind::Present ||
189242
ClauseKind == OpenACCClauseKind::Copy ||
190243
ClauseKind == OpenACCClauseKind::PCopy ||
191244
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
245+
ClauseKind == OpenACCClauseKind::CopyIn ||
246+
ClauseKind == OpenACCClauseKind::PCopyIn ||
247+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
248+
ClauseKind == OpenACCClauseKind::CopyOut ||
249+
ClauseKind == OpenACCClauseKind::PCopyOut ||
250+
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
251+
ClauseKind == OpenACCClauseKind::Create ||
252+
ClauseKind == OpenACCClauseKind::PCreate ||
253+
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
192254
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
193255
"Parsed clause kind does not have a var-list");
194-
Details = VarListDetails{std::move(VarList)};
256+
assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
257+
ClauseKind == OpenACCClauseKind::PCopyIn ||
258+
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
259+
"readonly: tag only valid on copyin");
260+
assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
261+
ClauseKind == OpenACCClauseKind::PCopyOut ||
262+
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
263+
ClauseKind == OpenACCClauseKind::Create ||
264+
ClauseKind == OpenACCClauseKind::PCreate ||
265+
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
266+
"zero: tag only valid on copyout/create");
267+
Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
195268
}
196269
};
197270

clang/lib/AST/OpenACCClause.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,39 @@ OpenACCCopyClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
186186
OpenACCCopyClause(Spelling, BeginLoc, LParenLoc, VarList, EndLoc);
187187
}
188188

189+
OpenACCCopyInClause *
190+
OpenACCCopyInClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
191+
SourceLocation BeginLoc, SourceLocation LParenLoc,
192+
bool IsReadOnly, ArrayRef<Expr *> VarList,
193+
SourceLocation EndLoc) {
194+
void *Mem =
195+
C.Allocate(OpenACCCopyInClause::totalSizeToAlloc<Expr *>(VarList.size()));
196+
return new (Mem) OpenACCCopyInClause(Spelling, BeginLoc, LParenLoc,
197+
IsReadOnly, VarList, EndLoc);
198+
}
199+
200+
OpenACCCopyOutClause *
201+
OpenACCCopyOutClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
202+
SourceLocation BeginLoc, SourceLocation LParenLoc,
203+
bool IsZero, ArrayRef<Expr *> VarList,
204+
SourceLocation EndLoc) {
205+
void *Mem = C.Allocate(
206+
OpenACCCopyOutClause::totalSizeToAlloc<Expr *>(VarList.size()));
207+
return new (Mem) OpenACCCopyOutClause(Spelling, BeginLoc, LParenLoc, IsZero,
208+
VarList, EndLoc);
209+
}
210+
211+
OpenACCCreateClause *
212+
OpenACCCreateClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
213+
SourceLocation BeginLoc, SourceLocation LParenLoc,
214+
bool IsZero, ArrayRef<Expr *> VarList,
215+
SourceLocation EndLoc) {
216+
void *Mem =
217+
C.Allocate(OpenACCCreateClause::totalSizeToAlloc<Expr *>(VarList.size()));
218+
return new (Mem) OpenACCCreateClause(Spelling, BeginLoc, LParenLoc, IsZero,
219+
VarList, EndLoc);
220+
}
221+
189222
//===----------------------------------------------------------------------===//
190223
// OpenACC clauses printing methods
191224
//===----------------------------------------------------------------------===//
@@ -269,3 +302,30 @@ void OpenACCClausePrinter::VisitCopyClause(const OpenACCCopyClause &C) {
269302
[&](const Expr *E) { printExpr(E); });
270303
OS << ")";
271304
}
305+
306+
void OpenACCClausePrinter::VisitCopyInClause(const OpenACCCopyInClause &C) {
307+
OS << C.getClauseKind() << '(';
308+
if (C.isReadOnly())
309+
OS << "readonly: ";
310+
llvm::interleaveComma(C.getVarList(), OS,
311+
[&](const Expr *E) { printExpr(E); });
312+
OS << ")";
313+
}
314+
315+
void OpenACCClausePrinter::VisitCopyOutClause(const OpenACCCopyOutClause &C) {
316+
OS << C.getClauseKind() << '(';
317+
if (C.isZero())
318+
OS << "zero: ";
319+
llvm::interleaveComma(C.getVarList(), OS,
320+
[&](const Expr *E) { printExpr(E); });
321+
OS << ")";
322+
}
323+
324+
void OpenACCClausePrinter::VisitCreateClause(const OpenACCCreateClause &C) {
325+
OS << C.getClauseKind() << '(';
326+
if (C.isZero())
327+
OS << "zero: ";
328+
llvm::interleaveComma(C.getVarList(), OS,
329+
[&](const Expr *E) { printExpr(E); });
330+
OS << ")";
331+
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,6 +2496,23 @@ void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
24962496
for (auto *E : Clause.getVarList())
24972497
Profiler.VisitStmt(E);
24982498
}
2499+
void OpenACCClauseProfiler::VisitCopyInClause(
2500+
const OpenACCCopyInClause &Clause) {
2501+
for (auto *E : Clause.getVarList())
2502+
Profiler.VisitStmt(E);
2503+
}
2504+
2505+
void OpenACCClauseProfiler::VisitCopyOutClause(
2506+
const OpenACCCopyOutClause &Clause) {
2507+
for (auto *E : Clause.getVarList())
2508+
Profiler.VisitStmt(E);
2509+
}
2510+
2511+
void OpenACCClauseProfiler::VisitCreateClause(
2512+
const OpenACCCreateClause &Clause) {
2513+
for (auto *E : Clause.getVarList())
2514+
Profiler.VisitStmt(E);
2515+
}
24992516

25002517
void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
25012518
if (Clause.hasConditionExpr())

0 commit comments

Comments
 (0)