Skip to content

Commit cf456ed

Browse files
authored
[OpenACC] implement loop 'worker' clause. (#112206)
The worker clause specifies iterations of the loop/ that are executed in parallel by distributing the iterations among the multiple works within a single gang. The sema rules for this type are simply that it cannot be combined with a `kernel` construct with a `num_workers` clause, child `loop` clauses cannot contain a `gang` or `worker` clause, and that the argument is oly allowed when associated with a `kernel`.
1 parent cef66aa commit cf456ed

20 files changed

+766
-75
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -145,32 +145,6 @@ class OpenACCVectorClause : public OpenACCClause {
145145
}
146146
};
147147

148-
// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
149-
// this provides a basic, do-nothing implementation. We still need to add this
150-
// type to the visitors/etc, as well as get it to take its proper arguments.
151-
class OpenACCWorkerClause : public OpenACCClause {
152-
protected:
153-
OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation EndLoc)
154-
: OpenACCClause(OpenACCClauseKind::Worker, BeginLoc, EndLoc) {
155-
llvm_unreachable("Not yet implemented");
156-
}
157-
158-
public:
159-
static bool classof(const OpenACCClause *C) {
160-
return C->getClauseKind() == OpenACCClauseKind::Worker;
161-
}
162-
163-
static OpenACCWorkerClause *
164-
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
165-
166-
child_range children() {
167-
return child_range(child_iterator(), child_iterator());
168-
}
169-
const_child_range children() const {
170-
return const_child_range(const_child_iterator(), const_child_iterator());
171-
}
172-
};
173-
174148
/// Represents a clause that has a list of parameters.
175149
class OpenACCClauseWithParams : public OpenACCClause {
176150
/// Location of the '('.
@@ -541,6 +515,22 @@ class OpenACCGangClause final
541515
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
542516
};
543517

518+
class OpenACCWorkerClause : public OpenACCClauseWithSingleIntExpr {
519+
protected:
520+
OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
521+
Expr *IntExpr, SourceLocation EndLoc);
522+
523+
public:
524+
static bool classof(const OpenACCClause *C) {
525+
return C->getClauseKind() == OpenACCClauseKind::Worker;
526+
}
527+
528+
static OpenACCWorkerClause *Create(const ASTContext &Ctx,
529+
SourceLocation BeginLoc,
530+
SourceLocation LParenLoc, Expr *IntExpr,
531+
SourceLocation EndLoc);
532+
};
533+
544534
class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
545535
OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
546536
Expr *IntExpr, SourceLocation EndLoc);

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12691,21 +12691,22 @@ def err_acc_intervening_code
1269112691
def err_acc_gang_multiple_elt
1269212692
: Error<"OpenACC 'gang' clause may have at most one %select{unnamed or "
1269312693
"'num'|'dim'|'static'}0 argument">;
12694-
def err_acc_gang_arg_invalid
12695-
: Error<"'%0' argument on 'gang' clause is not permitted on a%select{n "
12696-
"orphaned|||}1 'loop' construct %select{|associated with a "
12694+
def err_acc_int_arg_invalid
12695+
: Error<"'%1' argument on '%0' clause is not permitted on a%select{n "
12696+
"orphaned|||}2 'loop' construct %select{|associated with a "
1269712697
"'parallel' compute construct|associated with a 'kernels' compute "
12698-
"construct|associated with a 'serial' compute construct}1">;
12698+
"construct|associated with a 'serial' compute construct}2">;
1269912699
def err_acc_gang_dim_value
1270012700
: Error<"argument to 'gang' clause dimension must be %select{a constant "
1270112701
"expression|1, 2, or 3: evaluated to %1}0">;
12702-
def err_acc_gang_num_gangs_conflict
12703-
: Error<"'num' argument to 'gang' clause not allowed on a 'loop' construct "
12704-
"associated with a 'kernels' construct that has a 'num_gangs' "
12702+
def err_acc_num_arg_conflict
12703+
: Error<"'num' argument to '%0' clause not allowed on a 'loop' construct "
12704+
"associated with a 'kernels' construct that has a "
12705+
"'%select{num_gangs|num_workers}1' "
1270512706
"clause">;
12706-
def err_acc_gang_inside_gang
12707-
: Error<"loop with a 'gang' clause may not exist in the region of a 'gang' "
12708-
"clause on a 'kernels' compute construct">;
12707+
def err_acc_clause_in_clause_region
12708+
: Error<"loop with a '%0' clause may not exist in the region of a '%1' "
12709+
"clause%select{| on a 'kernels' compute construct}2">;
1270912710

1271012711
// AMDGCN builtins diagnostics
1271112712
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ VISIT_CLAUSE(Seq)
5656
VISIT_CLAUSE(Tile)
5757
VISIT_CLAUSE(VectorLength)
5858
VISIT_CLAUSE(Wait)
59+
VISIT_CLAUSE(Worker)
5960

6061
#undef VISIT_CLAUSE
6162
#undef CLAUSE_ALIAS

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ class SemaOpenACC : public SemaBase {
118118
/// 'kernel' construct, this will have the source location for it. This
119119
/// permits us to implement the restriction of no further 'gang' clauses.
120120
SourceLocation LoopGangClauseOnKernelLoc;
121+
/// If there is a current 'active' loop construct with a 'worker' clause on it
122+
/// (on any sort of construct), this has the source location for it. This
123+
/// permits us to implement the restriction of no further 'gang' or 'worker'
124+
/// clauses.
125+
SourceLocation LoopWorkerClauseLoc;
121126

122127
// Redeclaration of the version in OpenACCClause.h.
123128
using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
@@ -224,11 +229,15 @@ class SemaOpenACC : public SemaBase {
224229
ClauseKind == OpenACCClauseKind::NumWorkers ||
225230
ClauseKind == OpenACCClauseKind::Async ||
226231
ClauseKind == OpenACCClauseKind::Tile ||
232+
ClauseKind == OpenACCClauseKind::Worker ||
233+
ClauseKind == OpenACCClauseKind::Vector ||
227234
ClauseKind == OpenACCClauseKind::VectorLength) &&
228235
"Parsed clause kind does not have a int exprs");
229236

230237
// 'async' and 'wait' have an optional IntExpr, so be tolerant of that.
231238
if ((ClauseKind == OpenACCClauseKind::Async ||
239+
ClauseKind == OpenACCClauseKind::Worker ||
240+
ClauseKind == OpenACCClauseKind::Vector ||
232241
ClauseKind == OpenACCClauseKind::Wait) &&
233242
std::holds_alternative<std::monostate>(Details))
234243
return 0;
@@ -271,6 +280,8 @@ class SemaOpenACC : public SemaBase {
271280
ClauseKind == OpenACCClauseKind::Async ||
272281
ClauseKind == OpenACCClauseKind::Tile ||
273282
ClauseKind == OpenACCClauseKind::Gang ||
283+
ClauseKind == OpenACCClauseKind::Worker ||
284+
ClauseKind == OpenACCClauseKind::Vector ||
274285
ClauseKind == OpenACCClauseKind::VectorLength) &&
275286
"Parsed clause kind does not have a int exprs");
276287

@@ -401,6 +412,8 @@ class SemaOpenACC : public SemaBase {
401412
ClauseKind == OpenACCClauseKind::NumWorkers ||
402413
ClauseKind == OpenACCClauseKind::Async ||
403414
ClauseKind == OpenACCClauseKind::Tile ||
415+
ClauseKind == OpenACCClauseKind::Worker ||
416+
ClauseKind == OpenACCClauseKind::Vector ||
404417
ClauseKind == OpenACCClauseKind::VectorLength) &&
405418
"Parsed clause kind does not have a int exprs");
406419
Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
@@ -410,6 +423,8 @@ class SemaOpenACC : public SemaBase {
410423
ClauseKind == OpenACCClauseKind::NumWorkers ||
411424
ClauseKind == OpenACCClauseKind::Async ||
412425
ClauseKind == OpenACCClauseKind::Tile ||
426+
ClauseKind == OpenACCClauseKind::Worker ||
427+
ClauseKind == OpenACCClauseKind::Vector ||
413428
ClauseKind == OpenACCClauseKind::VectorLength) &&
414429
"Parsed clause kind does not have a int exprs");
415430
Details = IntExprDetails{std::move(IntExprs)};
@@ -663,6 +678,7 @@ class SemaOpenACC : public SemaBase {
663678
ComputeConstructInfo OldActiveComputeConstructInfo;
664679
OpenACCDirectiveKind DirKind;
665680
SourceLocation OldLoopGangClauseOnKernelLoc;
681+
SourceLocation OldLoopWorkerClauseLoc;
666682
llvm::SmallVector<OpenACCLoopConstruct *> ParentlessLoopConstructs;
667683
LoopInConstructRAII LoopRAII;
668684

clang/lib/AST/OpenACCClause.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ bool OpenACCClauseWithCondition::classof(const OpenACCClause *C) {
4444
bool OpenACCClauseWithSingleIntExpr::classof(const OpenACCClause *C) {
4545
return OpenACCNumWorkersClause::classof(C) ||
4646
OpenACCVectorLengthClause::classof(C) ||
47-
OpenACCCollapseClause::classof(C) || OpenACCAsyncClause::classof(C);
47+
OpenACCWorkerClause::classof(C) || OpenACCCollapseClause::classof(C) ||
48+
OpenACCAsyncClause::classof(C);
4849
}
4950
OpenACCDefaultClause *OpenACCDefaultClause::Create(const ASTContext &C,
5051
OpenACCDefaultClauseKind K,
@@ -403,11 +404,24 @@ OpenACCGangClause::Create(const ASTContext &C, SourceLocation BeginLoc,
403404
OpenACCGangClause(BeginLoc, LParenLoc, GangKinds, IntExprs, EndLoc);
404405
}
405406

407+
OpenACCWorkerClause::OpenACCWorkerClause(SourceLocation BeginLoc,
408+
SourceLocation LParenLoc,
409+
Expr *IntExpr, SourceLocation EndLoc)
410+
: OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::Worker, BeginLoc,
411+
LParenLoc, IntExpr, EndLoc) {
412+
assert((!IntExpr || IntExpr->isInstantiationDependent() ||
413+
IntExpr->getType()->isIntegerType()) &&
414+
"Int expression type not scalar/dependent");
415+
}
416+
406417
OpenACCWorkerClause *OpenACCWorkerClause::Create(const ASTContext &C,
407418
SourceLocation BeginLoc,
419+
SourceLocation LParenLoc,
420+
Expr *IntExpr,
408421
SourceLocation EndLoc) {
409-
void *Mem = C.Allocate(sizeof(OpenACCWorkerClause));
410-
return new (Mem) OpenACCWorkerClause(BeginLoc, EndLoc);
422+
void *Mem =
423+
C.Allocate(sizeof(OpenACCWorkerClause), alignof(OpenACCWorkerClause));
424+
return new (Mem) OpenACCWorkerClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
411425
}
412426

413427
OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C,
@@ -638,3 +652,13 @@ void OpenACCClausePrinter::VisitGangClause(const OpenACCGangClause &C) {
638652
OS << ")";
639653
}
640654
}
655+
656+
void OpenACCClausePrinter::VisitWorkerClause(const OpenACCWorkerClause &C) {
657+
OS << "worker";
658+
659+
if (C.hasIntExpr()) {
660+
OS << "(num: ";
661+
printExpr(C.getIntExpr());
662+
OS << ")";
663+
}
664+
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,6 +2629,12 @@ void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
26292629
Profiler.VisitStmt(Clause.getIntExpr());
26302630
}
26312631

2632+
void OpenACCClauseProfiler::VisitWorkerClause(
2633+
const OpenACCWorkerClause &Clause) {
2634+
if (Clause.hasIntExpr())
2635+
Profiler.VisitStmt(Clause.getIntExpr());
2636+
}
2637+
26322638
void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
26332639
if (Clause.hasDevNumExpr())
26342640
Profiler.VisitStmt(Clause.getDevNumExpr());

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
420420
case OpenACCClauseKind::Self:
421421
case OpenACCClauseKind::Seq:
422422
case OpenACCClauseKind::Tile:
423+
case OpenACCClauseKind::Worker:
423424
case OpenACCClauseKind::VectorLength:
424425
// The condition expression will be printed as a part of the 'children',
425426
// but print 'clause' here so it is clear what is happening from the dump.

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
11301130
Parens.skipToEnd();
11311131
return OpenACCCanContinue();
11321132
}
1133+
ParsedClause.setIntExprDetails(IntExpr.get());
11331134
break;
11341135
}
11351136
case OpenACCClauseKind::Async: {

0 commit comments

Comments
 (0)