Skip to content

Commit 2b939e1

Browse files
committed
[OpenACC] Implement auto/seq/independent clause Sema for 'loop'
These three clauses are all quite trivial, as they take no parameters. They are mutually exclusive, and 'seq' has some other exclusives that are implemented here. The ONE thing that isn't implemented is 2.9's restriction (line 2010): 'A loop associated with a 'loop' construct that does not have a 'seq' clause must be written to meet all the following conditions'. Future clauses will require similar work, so it'll be done as a followup.
1 parent cbe97e9 commit 2b939e1

20 files changed

+1639
-321
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,149 @@ class OpenACCClause {
5454
virtual ~OpenACCClause() = default;
5555
};
5656

57+
// Represents the 'auto' clause.
58+
class OpenACCAutoClause : public OpenACCClause {
59+
protected:
60+
OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc)
61+
: OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {}
62+
63+
public:
64+
static bool classof(const OpenACCClause *C) {
65+
return C->getClauseKind() == OpenACCClauseKind::Auto;
66+
}
67+
68+
static OpenACCAutoClause *
69+
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
70+
71+
child_range children() {
72+
return child_range(child_iterator(), child_iterator());
73+
}
74+
const_child_range children() const {
75+
return const_child_range(const_child_iterator(), const_child_iterator());
76+
}
77+
};
78+
79+
// Represents the 'independent' clause.
80+
class OpenACCIndependentClause : public OpenACCClause {
81+
protected:
82+
OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
83+
: OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {}
84+
85+
public:
86+
static bool classof(const OpenACCClause *C) {
87+
return C->getClauseKind() == OpenACCClauseKind::Independent;
88+
}
89+
90+
static OpenACCIndependentClause *
91+
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
92+
93+
child_range children() {
94+
return child_range(child_iterator(), child_iterator());
95+
}
96+
const_child_range children() const {
97+
return const_child_range(const_child_iterator(), const_child_iterator());
98+
}
99+
};
100+
// Represents the 'seq' clause.
101+
class OpenACCSeqClause : public OpenACCClause {
102+
protected:
103+
OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc)
104+
: OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {}
105+
106+
public:
107+
static bool classof(const OpenACCClause *C) {
108+
return C->getClauseKind() == OpenACCClauseKind::Seq;
109+
}
110+
111+
static OpenACCSeqClause *
112+
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
113+
114+
child_range children() {
115+
return child_range(child_iterator(), child_iterator());
116+
}
117+
const_child_range children() const {
118+
return const_child_range(const_child_iterator(), const_child_iterator());
119+
}
120+
};
121+
122+
// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
123+
// this provides a basic, do-nothing implementation. We still need to add this
124+
// type to the visitors/etc, as well as get it to take its proper arguments.
125+
class OpenACCGangClause : public OpenACCClause {
126+
protected:
127+
OpenACCGangClause(SourceLocation BeginLoc, SourceLocation EndLoc)
128+
: OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) {
129+
llvm_unreachable("Not yet implemented");
130+
}
131+
132+
public:
133+
static bool classof(const OpenACCClause *C) {
134+
return C->getClauseKind() == OpenACCClauseKind::Gang;
135+
}
136+
137+
static OpenACCGangClause *
138+
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
139+
140+
child_range children() {
141+
return child_range(child_iterator(), child_iterator());
142+
}
143+
const_child_range children() const {
144+
return const_child_range(const_child_iterator(), const_child_iterator());
145+
}
146+
};
147+
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 OpenACCVectorClause : public OpenACCClause {
152+
protected:
153+
OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation EndLoc)
154+
: OpenACCClause(OpenACCClauseKind::Vector, BeginLoc, EndLoc) {
155+
llvm_unreachable("Not yet implemented");
156+
}
157+
158+
public:
159+
static bool classof(const OpenACCClause *C) {
160+
return C->getClauseKind() == OpenACCClauseKind::Gang;
161+
}
162+
163+
static OpenACCVectorClause *
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+
174+
// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
175+
// this provides a basic, do-nothing implementation. We still need to add this
176+
// type to the visitors/etc, as well as get it to take its proper arguments.
177+
class OpenACCWorkerClause : public OpenACCClause {
178+
protected:
179+
OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation EndLoc)
180+
: OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) {
181+
llvm_unreachable("Not yet implemented");
182+
}
183+
184+
public:
185+
static bool classof(const OpenACCClause *C) {
186+
return C->getClauseKind() == OpenACCClauseKind::Gang;
187+
}
188+
189+
static OpenACCWorkerClause *
190+
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
191+
192+
child_range children() {
193+
return child_range(child_iterator(), child_iterator());
194+
}
195+
const_child_range children() const {
196+
return const_child_range(const_child_iterator(), const_child_iterator());
197+
}
198+
};
199+
57200
/// Represents a clause that has a list of parameters.
58201
class OpenACCClauseWithParams : public OpenACCClause {
59202
/// Location of the '('.

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12399,6 +12399,9 @@ def note_acc_expected_pointer_var : Note<"expected variable of pointer type">;
1239912399
def err_acc_clause_after_device_type
1240012400
: Error<"OpenACC clause '%0' may not follow a '%1' clause in a "
1240112401
"%select{'%3'|compute}2 construct">;
12402+
def err_acc_clause_cannot_combine
12403+
: Error<"OpenACC clause '%0' may not appear on the same construct as a "
12404+
"'%1' clause on a 'loop' construct">;
1240212405
def err_acc_reduction_num_gangs_conflict
1240312406
: Error<
1240412407
"OpenACC 'reduction' clause may not appear on a 'parallel' construct "
@@ -12416,6 +12419,9 @@ def note_acc_reduction_composite_member_loc : Note<"invalid field is here">;
1241612419
def err_acc_loop_not_for_loop
1241712420
: Error<"OpenACC 'loop' construct can only be applied to a 'for' loop">;
1241812421
def note_acc_construct_here : Note<"'%0' construct is here">;
12422+
def err_acc_loop_spec_conflict
12423+
: Error<"OpenACC clause '%0' on '%1' construct conflicts with previous "
12424+
"data dependence clause">;
1241912425

1242012426
// AMDGCN builtins diagnostics
1242112427
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;

clang/include/clang/Basic/OpenACCClauses.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME)
2222
#endif
2323

24+
VISIT_CLAUSE(Auto)
2425
VISIT_CLAUSE(Async)
2526
VISIT_CLAUSE(Attach)
2627
VISIT_CLAUSE(Copy)
@@ -41,13 +42,15 @@ VISIT_CLAUSE(DeviceType)
4142
CLAUSE_ALIAS(DType, DeviceType)
4243
VISIT_CLAUSE(FirstPrivate)
4344
VISIT_CLAUSE(If)
45+
VISIT_CLAUSE(Independent)
4446
VISIT_CLAUSE(NoCreate)
4547
VISIT_CLAUSE(NumGangs)
4648
VISIT_CLAUSE(NumWorkers)
4749
VISIT_CLAUSE(Present)
4850
VISIT_CLAUSE(Private)
4951
VISIT_CLAUSE(Reduction)
5052
VISIT_CLAUSE(Self)
53+
VISIT_CLAUSE(Seq)
5154
VISIT_CLAUSE(VectorLength)
5255
VISIT_CLAUSE(Wait)
5356

clang/lib/AST/OpenACCClause.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,48 @@ OpenACCReductionClause *OpenACCReductionClause::Create(
320320
OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc);
321321
}
322322

323+
OpenACCAutoClause *OpenACCAutoClause::Create(const ASTContext &C,
324+
SourceLocation BeginLoc,
325+
SourceLocation EndLoc) {
326+
void *Mem = C.Allocate(sizeof(OpenACCAutoClause));
327+
return new (Mem) OpenACCAutoClause(BeginLoc, EndLoc);
328+
}
329+
330+
OpenACCIndependentClause *
331+
OpenACCIndependentClause::Create(const ASTContext &C, SourceLocation BeginLoc,
332+
SourceLocation EndLoc) {
333+
void *Mem = C.Allocate(sizeof(OpenACCIndependentClause));
334+
return new (Mem) OpenACCIndependentClause(BeginLoc, EndLoc);
335+
}
336+
337+
OpenACCSeqClause *OpenACCSeqClause::Create(const ASTContext &C,
338+
SourceLocation BeginLoc,
339+
SourceLocation EndLoc) {
340+
void *Mem = C.Allocate(sizeof(OpenACCSeqClause));
341+
return new (Mem) OpenACCSeqClause(BeginLoc, EndLoc);
342+
}
343+
344+
OpenACCGangClause *OpenACCGangClause::Create(const ASTContext &C,
345+
SourceLocation BeginLoc,
346+
SourceLocation EndLoc) {
347+
void *Mem = C.Allocate(sizeof(OpenACCGangClause));
348+
return new (Mem) OpenACCGangClause(BeginLoc, EndLoc);
349+
}
350+
351+
OpenACCWorkerClause *OpenACCWorkerClause::Create(const ASTContext &C,
352+
SourceLocation BeginLoc,
353+
SourceLocation EndLoc) {
354+
void *Mem = C.Allocate(sizeof(OpenACCWorkerClause));
355+
return new (Mem) OpenACCWorkerClause(BeginLoc, EndLoc);
356+
}
357+
358+
OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C,
359+
SourceLocation BeginLoc,
360+
SourceLocation EndLoc) {
361+
void *Mem = C.Allocate(sizeof(OpenACCVectorClause));
362+
return new (Mem) OpenACCVectorClause(BeginLoc, EndLoc);
363+
}
364+
323365
//===----------------------------------------------------------------------===//
324366
// OpenACC clauses printing methods
325367
//===----------------------------------------------------------------------===//
@@ -495,3 +537,16 @@ void OpenACCClausePrinter::VisitDeviceTypeClause(
495537
});
496538
OS << ")";
497539
}
540+
541+
void OpenACCClausePrinter::VisitAutoClause(const OpenACCAutoClause &C) {
542+
OS << "auto";
543+
}
544+
545+
void OpenACCClausePrinter::VisitIndependentClause(
546+
const OpenACCIndependentClause &C) {
547+
OS << "independent";
548+
}
549+
550+
void OpenACCClausePrinter::VisitSeqClause(const OpenACCSeqClause &C) {
551+
OS << "seq";
552+
}

clang/lib/AST/StmtProfile.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,6 +2589,13 @@ void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
25892589
void OpenACCClauseProfiler::VisitDeviceTypeClause(
25902590
const OpenACCDeviceTypeClause &Clause) {}
25912591

2592+
void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {}
2593+
2594+
void OpenACCClauseProfiler::VisitIndependentClause(
2595+
const OpenACCIndependentClause &Clause) {}
2596+
2597+
void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {}
2598+
25922599
void OpenACCClauseProfiler::VisitReductionClause(
25932600
const OpenACCReductionClause &Clause) {
25942601
for (auto *E : Clause.getVarList())

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,13 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
398398
OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')';
399399
break;
400400
case OpenACCClauseKind::Async:
401+
case OpenACCClauseKind::Auto:
401402
case OpenACCClauseKind::Attach:
402403
case OpenACCClauseKind::Copy:
403404
case OpenACCClauseKind::PCopy:
404405
case OpenACCClauseKind::PresentOrCopy:
405406
case OpenACCClauseKind::If:
407+
case OpenACCClauseKind::Independent:
406408
case OpenACCClauseKind::DevicePtr:
407409
case OpenACCClauseKind::FirstPrivate:
408410
case OpenACCClauseKind::NoCreate:
@@ -411,6 +413,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
411413
case OpenACCClauseKind::Present:
412414
case OpenACCClauseKind::Private:
413415
case OpenACCClauseKind::Self:
416+
case OpenACCClauseKind::Seq:
414417
case OpenACCClauseKind::VectorLength:
415418
// The condition expression will be printed as a part of the 'children',
416419
// but print 'clause' here so it is clear what is happening from the dump.

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,8 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
11321132
// clause, as we are a 'single token' clause.
11331133
ParsedClause.setEndLoc(ClauseLoc);
11341134
}
1135+
} else {
1136+
ParsedClause.setEndLoc(ClauseLoc);
11351137
}
11361138
return OpenACCSuccess(
11371139
Actions.OpenACC().ActOnClause(ExistingClauses, ParsedClause));

0 commit comments

Comments
 (0)