Skip to content

Commit fa67986

Browse files
authored
[OpenACC] Private Clause on Compute Constructs (#90521)
The private clause is the first that takes a 'var-list', thus this has a lot of additional work to enable the var-list type. A 'var' is a traditional variable reference, subscript, member-expression, or array-section, so checking of these is pretty minor. Note: This ran into some issues with array-sections (aka sub-arrays) that will be fixed in a follow-up patch.
1 parent 8009bbe commit fa67986

22 files changed

+1225
-118
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -156,51 +156,50 @@ class OpenACCSelfClause : public OpenACCClauseWithCondition {
156156
Expr *ConditionExpr, SourceLocation EndLoc);
157157
};
158158

159-
/// Represents a clause that has one or more IntExprs. It does not own the
160-
/// IntExprs, but provides 'children' and other accessors.
161-
class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
162-
MutableArrayRef<Expr *> IntExprs;
159+
/// Represents a clause that has one or more expressions associated with it.
160+
class OpenACCClauseWithExprs : public OpenACCClauseWithParams {
161+
MutableArrayRef<Expr *> Exprs;
163162

164163
protected:
165-
OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
166-
SourceLocation LParenLoc, SourceLocation EndLoc)
164+
OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
165+
SourceLocation LParenLoc, SourceLocation EndLoc)
167166
: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {}
168167

169168
/// Used only for initialization, the leaf class can initialize this to
170169
/// trailing storage.
171-
void setIntExprs(MutableArrayRef<Expr *> NewIntExprs) {
172-
assert(IntExprs.empty() && "Cannot change IntExprs list");
173-
IntExprs = NewIntExprs;
170+
void setExprs(MutableArrayRef<Expr *> NewExprs) {
171+
assert(Exprs.empty() && "Cannot change Exprs list");
172+
Exprs = NewExprs;
174173
}
175174

176-
/// Gets the entire list of integer expressions, but leave it to the
175+
/// Gets the entire list of expressions, but leave it to the
177176
/// individual clauses to expose this how they'd like.
178-
llvm::ArrayRef<Expr *> getIntExprs() const { return IntExprs; }
177+
llvm::ArrayRef<Expr *> getExprs() const { return Exprs; }
179178

180179
public:
181180
child_range children() {
182-
return child_range(reinterpret_cast<Stmt **>(IntExprs.begin()),
183-
reinterpret_cast<Stmt **>(IntExprs.end()));
181+
return child_range(reinterpret_cast<Stmt **>(Exprs.begin()),
182+
reinterpret_cast<Stmt **>(Exprs.end()));
184183
}
185184

186185
const_child_range children() const {
187186
child_range Children =
188-
const_cast<OpenACCClauseWithIntExprs *>(this)->children();
187+
const_cast<OpenACCClauseWithExprs *>(this)->children();
189188
return const_child_range(Children.begin(), Children.end());
190189
}
191190
};
192191

193192
class OpenACCNumGangsClause final
194-
: public OpenACCClauseWithIntExprs,
193+
: public OpenACCClauseWithExprs,
195194
public llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {
196195

197196
OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
198197
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc)
199-
: OpenACCClauseWithIntExprs(OpenACCClauseKind::NumGangs, BeginLoc,
200-
LParenLoc, EndLoc) {
198+
: OpenACCClauseWithExprs(OpenACCClauseKind::NumGangs, BeginLoc, LParenLoc,
199+
EndLoc) {
201200
std::uninitialized_copy(IntExprs.begin(), IntExprs.end(),
202201
getTrailingObjects<Expr *>());
203-
setIntExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size()));
202+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size()));
204203
}
205204

206205
public:
@@ -209,35 +208,35 @@ class OpenACCNumGangsClause final
209208
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
210209

211210
llvm::ArrayRef<Expr *> getIntExprs() {
212-
return OpenACCClauseWithIntExprs::getIntExprs();
211+
return OpenACCClauseWithExprs::getExprs();
213212
}
214213

215214
llvm::ArrayRef<Expr *> getIntExprs() const {
216-
return OpenACCClauseWithIntExprs::getIntExprs();
215+
return OpenACCClauseWithExprs::getExprs();
217216
}
218217
};
219218

220219
/// Represents one of a handful of clauses that have a single integer
221220
/// expression.
222-
class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
221+
class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs {
223222
Expr *IntExpr;
224223

225224
protected:
226225
OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc,
227226
SourceLocation LParenLoc, Expr *IntExpr,
228227
SourceLocation EndLoc)
229-
: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, EndLoc),
228+
: OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc),
230229
IntExpr(IntExpr) {
231-
setIntExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
230+
setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
232231
}
233232

234233
public:
235-
bool hasIntExpr() const { return !getIntExprs().empty(); }
234+
bool hasIntExpr() const { return !getExprs().empty(); }
236235
const Expr *getIntExpr() const {
237-
return hasIntExpr() ? getIntExprs()[0] : nullptr;
236+
return hasIntExpr() ? getExprs()[0] : nullptr;
238237
}
239238

240-
Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; };
239+
Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; };
241240
};
242241

243242
class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
@@ -261,6 +260,40 @@ class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr {
261260
Expr *IntExpr, SourceLocation EndLoc);
262261
};
263262

263+
/// Represents a clause with one or more 'var' objects, represented as an expr,
264+
/// as its arguments. Var-list is expected to be stored in trailing storage.
265+
/// For now, we're just storing the original expression in its entirety, unlike
266+
/// OMP which has to do a bunch of work to create a private.
267+
class OpenACCClauseWithVarList : public OpenACCClauseWithExprs {
268+
protected:
269+
OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc,
270+
SourceLocation LParenLoc, SourceLocation EndLoc)
271+
: OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {}
272+
273+
public:
274+
ArrayRef<Expr *> getVarList() { return getExprs(); }
275+
ArrayRef<Expr *> getVarList() const { return getExprs(); }
276+
};
277+
278+
class OpenACCPrivateClause final
279+
: public OpenACCClauseWithVarList,
280+
public llvm::TrailingObjects<OpenACCPrivateClause, Expr *> {
281+
282+
OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
283+
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
284+
: OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc,
285+
LParenLoc, EndLoc) {
286+
std::uninitialized_copy(VarList.begin(), VarList.end(),
287+
getTrailingObjects<Expr *>());
288+
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
289+
}
290+
291+
public:
292+
static OpenACCPrivateClause *
293+
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
294+
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
295+
};
296+
264297
template <class Impl> class OpenACCClauseVisitor {
265298
Impl &getDerived() { return static_cast<Impl &>(*this); }
266299

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12307,4 +12307,7 @@ def err_acc_num_gangs_num_args
1230712307
"OpenACC 'num_gangs' "
1230812308
"%select{|clause: '%1' directive expects maximum of %2, %3 were "
1230912309
"provided}0">;
12310+
def err_acc_not_a_var_ref
12311+
: Error<"OpenACC variable is not a valid variable name, sub-array, array "
12312+
"element, or composite variable member">;
1231012313
} // end of sema component.

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ VISIT_CLAUSE(If)
2020
VISIT_CLAUSE(Self)
2121
VISIT_CLAUSE(NumGangs)
2222
VISIT_CLAUSE(NumWorkers)
23+
VISIT_CLAUSE(Private)
2324
VISIT_CLAUSE(VectorLength)
2425

2526
#undef VISIT_CLAUSE

clang/include/clang/Parse/Parser.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3654,11 +3654,12 @@ class Parser : public CodeCompletionHandler {
36543654
ExprResult ParseOpenACCIDExpression();
36553655
/// Parses the variable list for the `cache` construct.
36563656
void ParseOpenACCCacheVarList();
3657+
3658+
using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
36573659
/// Parses a single variable in a variable list for OpenACC.
3658-
bool ParseOpenACCVar();
3659-
/// Parses the variable list for the variety of clauses that take a var-list,
3660-
/// including the optional Special Token listed for some,based on clause type.
3661-
bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
3660+
OpenACCVarParseResult ParseOpenACCVar();
3661+
/// Parses the variable list for the variety of places that take a var-list.
3662+
llvm::SmallVector<Expr *> ParseOpenACCVarList();
36623663
/// Parses any parameters for an OpenACC Clause, including required/optional
36633664
/// parens.
36643665
OpenACCClauseParseResult

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ class SemaOpenACC : public SemaBase {
4848
SmallVector<Expr *> IntExprs;
4949
};
5050

51+
struct VarListDetails {
52+
SmallVector<Expr *> VarList;
53+
};
54+
5155
std::variant<std::monostate, DefaultDetails, ConditionDetails,
52-
IntExprDetails>
56+
IntExprDetails, VarListDetails>
5357
Details = std::monostate{};
5458

5559
public:
@@ -112,6 +116,16 @@ class SemaOpenACC : public SemaBase {
112116
return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
113117
}
114118

119+
ArrayRef<Expr *> getVarList() {
120+
assert(ClauseKind == OpenACCClauseKind::Private &&
121+
"Parsed clause kind does not have a var-list");
122+
return std::get<VarListDetails>(Details).VarList;
123+
}
124+
125+
ArrayRef<Expr *> getVarList() const {
126+
return const_cast<OpenACCParsedClause *>(this)->getVarList();
127+
}
128+
115129
void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
116130
void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
117131

@@ -147,7 +161,19 @@ class SemaOpenACC : public SemaBase {
147161
ClauseKind == OpenACCClauseKind::NumWorkers ||
148162
ClauseKind == OpenACCClauseKind::VectorLength) &&
149163
"Parsed clause kind does not have a int exprs");
150-
Details = IntExprDetails{IntExprs};
164+
Details = IntExprDetails{std::move(IntExprs)};
165+
}
166+
167+
void setVarListDetails(ArrayRef<Expr *> VarList) {
168+
assert(ClauseKind == OpenACCClauseKind::Private &&
169+
"Parsed clause kind does not have a var-list");
170+
Details = VarListDetails{{VarList.begin(), VarList.end()}};
171+
}
172+
173+
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList) {
174+
assert(ClauseKind == OpenACCClauseKind::Private &&
175+
"Parsed clause kind does not have a var-list");
176+
Details = VarListDetails{std::move(VarList)};
151177
}
152178
};
153179

@@ -194,6 +220,10 @@ class SemaOpenACC : public SemaBase {
194220
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
195221
SourceLocation Loc, Expr *IntExpr);
196222

223+
/// Called when encountering a 'var' for OpenACC, ensures it is actually a
224+
/// declaration reference to a variable of the correct type.
225+
ExprResult ActOnVar(Expr *VarExpr);
226+
197227
/// Checks and creates an Array Section used in an OpenACC construct/clause.
198228
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
199229
Expr *LowerBound,

clang/include/clang/Serialization/ASTRecordReader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ class ASTRecordReader
269269
/// Read an OpenMP children, advancing Idx.
270270
void readOMPChildren(OMPChildren *Data);
271271

272+
/// Read a list of Exprs used for a var-list.
273+
llvm::SmallVector<Expr *> readOpenACCVarList();
274+
272275
/// Read an OpenACC clause, advancing Idx.
273276
OpenACCClause *readOpenACCClause();
274277

clang/include/clang/Serialization/ASTRecordWriter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H
1616

1717
#include "clang/AST/AbstractBasicWriter.h"
18+
#include "clang/AST/OpenACCClause.h"
1819
#include "clang/AST/OpenMPClause.h"
1920
#include "clang/Serialization/ASTWriter.h"
2021
#include "clang/Serialization/SourceLocationEncoding.h"
@@ -293,6 +294,8 @@ class ASTRecordWriter
293294
/// Writes data related to the OpenMP directives.
294295
void writeOMPChildren(OMPChildren *Data);
295296

297+
void writeOpenACCVarList(const OpenACCClauseWithVarList *C);
298+
296299
/// Writes out a single OpenACC Clause.
297300
void writeOpenACCClause(const OpenACCClause *C);
298301

clang/lib/AST/OpenACCClause.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ OpenACCNumGangsClause *OpenACCNumGangsClause::Create(const ASTContext &C,
134134
return new (Mem) OpenACCNumGangsClause(BeginLoc, LParenLoc, IntExprs, EndLoc);
135135
}
136136

137+
OpenACCPrivateClause *OpenACCPrivateClause::Create(const ASTContext &C,
138+
SourceLocation BeginLoc,
139+
SourceLocation LParenLoc,
140+
ArrayRef<Expr *> VarList,
141+
SourceLocation EndLoc) {
142+
void *Mem = C.Allocate(
143+
OpenACCPrivateClause::totalSizeToAlloc<Expr *>(VarList.size()));
144+
return new (Mem) OpenACCPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
145+
}
146+
137147
//===----------------------------------------------------------------------===//
138148
// OpenACC clauses printing methods
139149
//===----------------------------------------------------------------------===//
@@ -181,3 +191,10 @@ void OpenACCClausePrinter::VisitVectorLengthClause(
181191
printExpr(C.getIntExpr());
182192
OS << ")";
183193
}
194+
195+
void OpenACCClausePrinter::VisitPrivateClause(const OpenACCPrivateClause &C) {
196+
OS << "private(";
197+
llvm::interleaveComma(C.getVarList(), OS,
198+
[&](const Expr *E) { printExpr(E); });
199+
OS << ")";
200+
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,6 +2509,12 @@ void OpenACCClauseProfiler::VisitNumWorkersClause(
25092509
Profiler.VisitStmt(Clause.getIntExpr());
25102510
}
25112511

2512+
void OpenACCClauseProfiler::VisitPrivateClause(
2513+
const OpenACCPrivateClause &Clause) {
2514+
for (auto *E : Clause.getVarList())
2515+
Profiler.VisitStmt(E);
2516+
}
2517+
25122518
void OpenACCClauseProfiler::VisitVectorLengthClause(
25132519
const OpenACCVectorLengthClause &Clause) {
25142520
assert(Clause.hasIntExpr() &&

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
401401
case OpenACCClauseKind::Self:
402402
case OpenACCClauseKind::NumGangs:
403403
case OpenACCClauseKind::NumWorkers:
404+
case OpenACCClauseKind::Private:
404405
case OpenACCClauseKind::VectorLength:
405406
// The condition expression will be printed as a part of the 'children',
406407
// but print 'clause' here so it is clear what is happening from the dump.

0 commit comments

Comments
 (0)