Skip to content

Commit a13c514

Browse files
committed
[OpenACC] Implement firstprivate clause for compute constructs
This clause is pretty nearly copy/paste from private, except that it doesn't support 'loop', and thus 'kernelsloop' for appertainment.
1 parent 72e07d4 commit a13c514

17 files changed

+377
-24
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,25 @@ class OpenACCPrivateClause final
294294
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
295295
};
296296

297+
class OpenACCFirstPrivateClause final
298+
: public OpenACCClauseWithVarList,
299+
public llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> {
300+
301+
OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
302+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
303+
: OpenACCClauseWithVarList(OpenACCClauseKind::FirstPrivate, BeginLoc,
304+
LParenLoc, EndLoc) {
305+
std::uninitialized_copy(VarList.begin(), VarList.end(),
306+
getTrailingObjects<Expr *>());
307+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
308+
}
309+
310+
public:
311+
static OpenACCFirstPrivateClause *
312+
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
313+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
314+
};
315+
297316
template <class Impl> class OpenACCClauseVisitor {
298317
Impl &getDerived() { return static_cast<Impl &>(*this); }
299318

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
// VISIT_CLAUSE(CLAUSE_NAME)
1717

1818
VISIT_CLAUSE(Default)
19+
VISIT_CLAUSE(FirstPrivate)
1920
VISIT_CLAUSE(If)
20-
VISIT_CLAUSE(Self)
2121
VISIT_CLAUSE(NumGangs)
2222
VISIT_CLAUSE(NumWorkers)
2323
VISIT_CLAUSE(Private)
24+
VISIT_CLAUSE(Self)
2425
VISIT_CLAUSE(VectorLength)
2526

2627
#undef VISIT_CLAUSE

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ class SemaOpenACC : public SemaBase {
117117
}
118118

119119
ArrayRef<Expr *> getVarList() {
120-
assert(ClauseKind == OpenACCClauseKind::Private &&
120+
assert((ClauseKind == OpenACCClauseKind::Private ||
121+
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
121122
"Parsed clause kind does not have a var-list");
122123
return std::get<VarListDetails>(Details).VarList;
123124
}
@@ -165,13 +166,15 @@ class SemaOpenACC : public SemaBase {
165166
}
166167

167168
void setVarListDetails(ArrayRef<Expr *> VarList) {
168-
assert(ClauseKind == OpenACCClauseKind::Private &&
169+
assert((ClauseKind == OpenACCClauseKind::Private ||
170+
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
169171
"Parsed clause kind does not have a var-list");
170172
Details = VarListDetails{{VarList.begin(), VarList.end()}};
171173
}
172174

173175
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList) {
174-
assert(ClauseKind == OpenACCClauseKind::Private &&
176+
assert((ClauseKind == OpenACCClauseKind::Private ||
177+
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
175178
"Parsed clause kind does not have a var-list");
176179
Details = VarListDetails{std::move(VarList)};
177180
}

clang/lib/AST/OpenACCClause.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ OpenACCPrivateClause *OpenACCPrivateClause::Create(const ASTContext &C,
144144
return new (Mem) OpenACCPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
145145
}
146146

147+
OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create(
148+
const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
149+
ArrayRef<Expr *> VarList, SourceLocation EndLoc) {
150+
void *Mem = C.Allocate(
151+
OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *>(VarList.size()));
152+
return new (Mem)
153+
OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
154+
}
155+
147156
//===----------------------------------------------------------------------===//
148157
// OpenACC clauses printing methods
149158
//===----------------------------------------------------------------------===//
@@ -198,3 +207,11 @@ void OpenACCClausePrinter::VisitPrivateClause(const OpenACCPrivateClause &C) {
198207
[&](const Expr *E) { printExpr(E); });
199208
OS << ")";
200209
}
210+
211+
void OpenACCClausePrinter::VisitFirstPrivateClause(
212+
const OpenACCFirstPrivateClause &C) {
213+
OS << "firstprivate(";
214+
llvm::interleaveComma(C.getVarList(), OS,
215+
[&](const Expr *E) { printExpr(E); });
216+
OS << ")";
217+
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,12 @@ void OpenACCClauseProfiler::VisitPrivateClause(
25152515
Profiler.VisitStmt(E);
25162516
}
25172517

2518+
void OpenACCClauseProfiler::VisitFirstPrivateClause(
2519+
const OpenACCFirstPrivateClause &Clause) {
2520+
for (auto *E : Clause.getVarList())
2521+
Profiler.VisitStmt(E);
2522+
}
2523+
25182524
void OpenACCClauseProfiler::VisitVectorLengthClause(
25192525
const OpenACCVectorLengthClause &Clause) {
25202526
assert(Clause.hasIntExpr() &&

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,11 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
398398
OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')';
399399
break;
400400
case OpenACCClauseKind::If:
401-
case OpenACCClauseKind::Self:
401+
case OpenACCClauseKind::FirstPrivate:
402402
case OpenACCClauseKind::NumGangs:
403403
case OpenACCClauseKind::NumWorkers:
404404
case OpenACCClauseKind::Private:
405+
case OpenACCClauseKind::Self:
405406
case OpenACCClauseKind::VectorLength:
406407
// The condition expression will be printed as a part of the 'children',
407408
// but print 'clause' here so it is clear what is happening from the dump.

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,14 +926,14 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
926926
case OpenACCClauseKind::Device:
927927
case OpenACCClauseKind::DeviceResident:
928928
case OpenACCClauseKind::DevicePtr:
929-
case OpenACCClauseKind::FirstPrivate:
930929
case OpenACCClauseKind::Host:
931930
case OpenACCClauseKind::Link:
932931
case OpenACCClauseKind::NoCreate:
933932
case OpenACCClauseKind::Present:
934933
case OpenACCClauseKind::UseDevice:
935934
ParseOpenACCVarList();
936935
break;
936+
case OpenACCClauseKind::FirstPrivate:
937937
case OpenACCClauseKind::Private:
938938
ParsedClause.setVarListDetails(ParseOpenACCVarList());
939939
break;

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
104104
default:
105105
return false;
106106
}
107+
case OpenACCClauseKind::FirstPrivate:
108+
switch (DirectiveKind) {
109+
case OpenACCDirectiveKind::Parallel:
110+
case OpenACCDirectiveKind::Serial:
111+
case OpenACCDirectiveKind::ParallelLoop:
112+
case OpenACCDirectiveKind::SerialLoop:
113+
return true;
114+
default:
115+
return false;
116+
}
107117
case OpenACCClauseKind::Private:
108118
switch (DirectiveKind) {
109119
case OpenACCDirectiveKind::Parallel:
@@ -331,6 +341,21 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
331341
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
332342
Clause.getVarList(), Clause.getEndLoc());
333343
}
344+
case OpenACCClauseKind::FirstPrivate: {
345+
// Restrictions only properly implemented on 'compute' constructs, and
346+
// 'compute' constructs are the only construct that can do anything with
347+
// this yet, so skip/treat as unimplemented in this case.
348+
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
349+
break;
350+
351+
// ActOnVar ensured that everything is a valid variable reference, so there
352+
// really isn't anything to do here. GCC does some duplicate-finding, though
353+
// it isn't apparent in the standard where this is justified.
354+
355+
return OpenACCFirstPrivateClause::Create(
356+
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
357+
Clause.getVarList(), Clause.getEndLoc());
358+
}
334359
default:
335360
break;
336361
}

clang/lib/Sema/TreeTransform.h

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11112,6 +11112,23 @@ class OpenACCClauseTransform final
1111211112
SemaOpenACC::OpenACCParsedClause &ParsedClause;
1111311113
OpenACCClause *NewClause = nullptr;
1111411114

11115+
llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11116+
llvm::SmallVector<Expr *> InstantiatedVarList;
11117+
for (Expr *CurVar : VarList) {
11118+
ExprResult Res = Self.TransformExpr(CurVar);
11119+
11120+
if (!Res.isUsable())
11121+
continue;
11122+
11123+
Res = Self.getSema().OpenACC().ActOnVar(Res.get());
11124+
11125+
if (Res.isUsable())
11126+
InstantiatedVarList.push_back(Res.get());
11127+
}
11128+
11129+
return InstantiatedVarList;
11130+
}
11131+
1111511132
public:
1111611133
OpenACCClauseTransform(TreeTransform<Derived> &Self,
1111711134
ArrayRef<const OpenACCClause *> ExistingClauses,
@@ -11206,22 +11223,20 @@ void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
1120611223
template <typename Derived>
1120711224
void OpenACCClauseTransform<Derived>::VisitPrivateClause(
1120811225
const OpenACCPrivateClause &C) {
11209-
llvm::SmallVector<Expr *> InstantiatedVarList;
11210-
11211-
for (Expr *CurVar : C.getVarList()) {
11212-
ExprResult Res = Self.TransformExpr(CurVar);
11213-
11214-
if (!Res.isUsable())
11215-
return;
11226+
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()));
1121611227

11217-
Res = Self.getSema().OpenACC().ActOnVar(Res.get());
11228+
NewClause = OpenACCPrivateClause::Create(
11229+
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11230+
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11231+
ParsedClause.getEndLoc());
11232+
}
1121811233

11219-
if (Res.isUsable())
11220-
InstantiatedVarList.push_back(Res.get());
11221-
}
11222-
ParsedClause.setVarListDetails(std::move(InstantiatedVarList));
11234+
template <typename Derived>
11235+
void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11236+
const OpenACCFirstPrivateClause &C) {
11237+
ParsedClause.setVarListDetails(VisitVarList(C.getVarList()));
1122311238

11224-
NewClause = OpenACCPrivateClause::Create(
11239+
NewClause = OpenACCFirstPrivateClause::Create(
1122511240
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
1122611241
ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
1122711242
ParsedClause.getEndLoc());

clang/lib/Serialization/ASTReader.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11835,6 +11835,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1183511835
return OpenACCPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
1183611836
VarList, EndLoc);
1183711837
}
11838+
case OpenACCClauseKind::FirstPrivate: {
11839+
SourceLocation LParenLoc = readSourceLocation();
11840+
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
11841+
return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
11842+
VarList, EndLoc);
11843+
}
1183811844
case OpenACCClauseKind::Finalize:
1183911845
case OpenACCClauseKind::IfPresent:
1184011846
case OpenACCClauseKind::Seq:
@@ -11851,7 +11857,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
1185111857
case OpenACCClauseKind::Device:
1185211858
case OpenACCClauseKind::DevicePtr:
1185311859
case OpenACCClauseKind::DeviceResident:
11854-
case OpenACCClauseKind::FirstPrivate:
1185511860
case OpenACCClauseKind::Host:
1185611861
case OpenACCClauseKind::Link:
1185711862
case OpenACCClauseKind::NoCreate:

0 commit comments

Comments
 (0)