Skip to content

Commit 0aef005

Browse files
committed
[OpenACC] Implement 'collapse' for combined constructs.
Most of the restrictions on 'collapse' involve the contents of the loop, so this extends enforcement of all of that to all combined construct loops, and alters the diagnostics to better reflect the construct it is associated with.
1 parent 91f5f97 commit 0aef005

8 files changed

+662
-26
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12733,19 +12733,19 @@ def err_acc_size_expr_value
1273312733
"OpenACC 'tile' clause size expression must be %select{an asterisk "
1273412734
"or a constant expression|positive integer value, evaluated to %1}0">;
1273512735
def err_acc_invalid_in_loop
12736-
: Error<"%select{OpenACC '%2' construct|while loop|do loop}0 cannot appear "
12737-
"in intervening code of a 'loop' with a '%1' clause">;
12736+
: Error<"%select{OpenACC '%3' construct|while loop|do loop}0 cannot appear "
12737+
"in intervening code of a '%1' with a '%2' clause">;
1273812738
def note_acc_active_clause_here
1273912739
: Note<"active '%0' clause defined here">;
1274012740
def err_acc_clause_multiple_loops
12741-
: Error<"more than one for-loop in a loop associated with OpenACC 'loop' "
12742-
"construct with a '%select{collapse|tile}0' clause">;
12741+
: Error<"more than one for-loop in a loop associated with OpenACC '%0' "
12742+
"construct with a '%1' clause">;
1274312743
def err_acc_insufficient_loops
1274412744
: Error<"'%0' clause specifies a loop count greater than the number "
1274512745
"of available loops">;
1274612746
def err_acc_intervening_code
1274712747
: Error<"inner loops must be tightly nested inside a '%0' clause on "
12748-
"a 'loop' construct">;
12748+
"a '%1' construct">;
1274912749
def err_acc_gang_multiple_elt
1275012750
: Error<"OpenACC 'gang' clause may have at most one %select{unnamed or "
1275112751
"'num'|'dim'|'static'}0 argument">;

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class SemaOpenACC : public SemaBase {
8787
/// which allows us to diagnose if the value of 'N' is too large for the
8888
/// current number of 'for' loops.
8989
bool CollapseDepthSatisfied = true;
90+
91+
/// Records the kind of the directive that this clause is attached to, which
92+
/// allows us to use it in diagnostics.
93+
OpenACCDirectiveKind DirectiveKind = OpenACCDirectiveKind::Invalid;
9094
} CollapseInfo;
9195

9296
/// The 'tile' clause requires a bit of additional checking as well, so like

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,10 +1504,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
15041504

15051505
OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(
15061506
SemaOpenACC::OpenACCParsedClause &Clause) {
1507-
// TODO: Remove this check once we implement this for combined constructs.
1508-
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
1509-
Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
1510-
return isNotImplemented();
15111507
// Duplicates here are not really sensible. We could possible permit
15121508
// multiples if they all had the same value, but there isn't really a good
15131509
// reason to do so. Also, this simplifies the suppression of duplicates, in
@@ -1701,6 +1697,7 @@ void SemaOpenACC::AssociatedStmtRAII::SetCollapseInfoBeforeAssociatedStmt(
17011697
SemaRef.CollapseInfo.CollapseDepthSatisfied = false;
17021698
SemaRef.CollapseInfo.CurCollapseCount =
17031699
cast<ConstantExpr>(LoopCount)->getResultAsAPSInt();
1700+
SemaRef.CollapseInfo.DirectiveKind = DirKind;
17041701
}
17051702

17061703
void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt(
@@ -2597,7 +2594,8 @@ void SemaOpenACC::ActOnWhileStmt(SourceLocation WhileLoc) {
25972594

25982595
if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
25992596
Diag(WhileLoc, diag::err_acc_invalid_in_loop)
2600-
<< /*while loop*/ 1 << OpenACCClauseKind::Collapse;
2597+
<< /*while loop*/ 1 << CollapseInfo.DirectiveKind
2598+
<< OpenACCClauseKind::Collapse;
26012599
assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
26022600
Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
26032601
diag::note_acc_active_clause_here)
@@ -2610,7 +2608,8 @@ void SemaOpenACC::ActOnWhileStmt(SourceLocation WhileLoc) {
26102608

26112609
if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
26122610
Diag(WhileLoc, diag::err_acc_invalid_in_loop)
2613-
<< /*while loop*/ 1 << OpenACCClauseKind::Tile;
2611+
<< /*while loop*/ 1 << OpenACCDirectiveKind::Loop
2612+
<< OpenACCClauseKind::Tile;
26142613
assert(TileInfo.ActiveTile && "tile count without object?");
26152614
Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
26162615
<< OpenACCClauseKind::Tile;
@@ -2630,7 +2629,8 @@ void SemaOpenACC::ActOnDoStmt(SourceLocation DoLoc) {
26302629

26312630
if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
26322631
Diag(DoLoc, diag::err_acc_invalid_in_loop)
2633-
<< /*do loop*/ 2 << OpenACCClauseKind::Collapse;
2632+
<< /*do loop*/ 2 << CollapseInfo.DirectiveKind
2633+
<< OpenACCClauseKind::Collapse;
26342634
assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
26352635
Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
26362636
diag::note_acc_active_clause_here)
@@ -2643,7 +2643,8 @@ void SemaOpenACC::ActOnDoStmt(SourceLocation DoLoc) {
26432643

26442644
if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
26452645
Diag(DoLoc, diag::err_acc_invalid_in_loop)
2646-
<< /*do loop*/ 2 << OpenACCClauseKind::Tile;
2646+
<< /*do loop*/ 2 << OpenACCDirectiveKind::Loop
2647+
<< OpenACCClauseKind::Tile;
26472648
assert(TileInfo.ActiveTile && "tile count without object?");
26482649
Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
26492650
<< OpenACCClauseKind::Tile;
@@ -2670,7 +2671,8 @@ void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,
26702671
// This checks for more than 1 loop at the current level, the
26712672
// 'depth'-satisifed checking manages the 'not zero' case.
26722673
if (LoopInfo.CurLevelHasLoopAlready) {
2673-
Diag(ForLoc, diag::err_acc_clause_multiple_loops) << /*Collapse*/ 0;
2674+
Diag(ForLoc, diag::err_acc_clause_multiple_loops)
2675+
<< CollapseInfo.DirectiveKind << OpenACCClauseKind::Collapse;
26742676
assert(CollapseInfo.ActiveCollapse && "No collapse object?");
26752677
Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
26762678
diag::note_acc_active_clause_here)
@@ -2689,7 +2691,8 @@ void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,
26892691
C.check();
26902692

26912693
if (LoopInfo.CurLevelHasLoopAlready) {
2692-
Diag(ForLoc, diag::err_acc_clause_multiple_loops) << /*Tile*/ 1;
2694+
Diag(ForLoc, diag::err_acc_clause_multiple_loops)
2695+
<< OpenACCDirectiveKind::Loop << OpenACCClauseKind::Tile;
26932696
assert(TileInfo.ActiveTile && "No tile object?");
26942697
Diag(TileInfo.ActiveTile->getBeginLoc(),
26952698
diag::note_acc_active_clause_here)
@@ -3192,15 +3195,15 @@ void SemaOpenACC::ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body) {
31923195

31933196
if (OtherStmtLoc.isValid() && IsActiveCollapse) {
31943197
Diag(OtherStmtLoc, diag::err_acc_intervening_code)
3195-
<< OpenACCClauseKind::Collapse;
3198+
<< OpenACCClauseKind::Collapse << CollapseInfo.DirectiveKind;
31963199
Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
31973200
diag::note_acc_active_clause_here)
31983201
<< OpenACCClauseKind::Collapse;
31993202
}
32003203

32013204
if (OtherStmtLoc.isValid() && IsActiveTile) {
32023205
Diag(OtherStmtLoc, diag::err_acc_intervening_code)
3203-
<< OpenACCClauseKind::Tile;
3206+
<< OpenACCClauseKind::Tile << OpenACCDirectiveKind::Loop;
32043207
Diag(TileInfo.ActiveTile->getBeginLoc(),
32053208
diag::note_acc_active_clause_here)
32063209
<< OpenACCClauseKind::Tile;
@@ -3220,15 +3223,17 @@ bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
32203223
// ALL constructs are ill-formed if there is an active 'collapse'
32213224
if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
32223225
Diag(StartLoc, diag::err_acc_invalid_in_loop)
3223-
<< /*OpenACC Construct*/ 0 << OpenACCClauseKind::Collapse << K;
3226+
<< /*OpenACC Construct*/ 0 << CollapseInfo.DirectiveKind
3227+
<< OpenACCClauseKind::Collapse << K;
32243228
assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
32253229
Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
32263230
diag::note_acc_active_clause_here)
32273231
<< OpenACCClauseKind::Collapse;
32283232
}
32293233
if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
32303234
Diag(StartLoc, diag::err_acc_invalid_in_loop)
3231-
<< /*OpenACC Construct*/ 0 << OpenACCClauseKind::Tile << K;
3235+
<< /*OpenACC Construct*/ 0 << OpenACCDirectiveKind::Loop
3236+
<< OpenACCClauseKind::Tile << K;
32323237
assert(TileInfo.ActiveTile && "Tile count without object?");
32333238
Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
32343239
<< OpenACCClauseKind::Tile;

clang/test/AST/ast-print-openacc-combined-construct.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,29 @@ void foo() {
185185
// CHECK: #pragma acc parallel loop create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
186186
#pragma acc parallel loop create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
187187
for(int i = 0;i<5;++i);
188+
189+
// CHECK: #pragma acc parallel loop collapse(1)
190+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
191+
// CHECK-NEXT: ;
192+
#pragma acc parallel loop collapse(1)
193+
for(int i = 0;i<5;++i);
194+
// CHECK: #pragma acc serial loop collapse(force:1)
195+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
196+
// CHECK-NEXT: ;
197+
#pragma acc serial loop collapse(force:1)
198+
for(int i = 0;i<5;++i);
199+
// CHECK: #pragma acc kernels loop collapse(2)
200+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
201+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
202+
// CHECK-NEXT: ;
203+
#pragma acc kernels loop collapse(2)
204+
for(int i = 0;i<5;++i)
205+
for(int i = 0;i<5;++i);
206+
// CHECK: #pragma acc parallel loop collapse(force:2)
207+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
208+
// CHECK-NEXT: for (int i = 0; i < 5; ++i)
209+
// CHECK-NEXT: ;
210+
#pragma acc parallel loop collapse(force:2)
211+
for(int i = 0;i<5;++i)
212+
for(int i = 0;i<5;++i);
188213
}

clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ void uses() {
129129
// expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}}
130130
#pragma acc parallel loop auto reduction(+:Var)
131131
for(unsigned i = 0; i < 5; ++i);
132-
// expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}}
133132
#pragma acc parallel loop auto collapse(1)
134133
for(unsigned i = 0; i < 5; ++i);
135134
// expected-warning@+1{{OpenACC clause 'bind' not yet implemented}}
@@ -258,7 +257,6 @@ void uses() {
258257
// expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}}
259258
#pragma acc parallel loop reduction(+:Var) auto
260259
for(unsigned i = 0; i < 5; ++i);
261-
// expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}}
262260
#pragma acc parallel loop collapse(1) auto
263261
for(unsigned i = 0; i < 5; ++i);
264262
// expected-warning@+1{{OpenACC clause 'bind' not yet implemented}}
@@ -388,7 +386,6 @@ void uses() {
388386
// expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}}
389387
#pragma acc parallel loop independent reduction(+:Var)
390388
for(unsigned i = 0; i < 5; ++i);
391-
// expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}}
392389
#pragma acc parallel loop independent collapse(1)
393390
for(unsigned i = 0; i < 5; ++i);
394391
// expected-warning@+1{{OpenACC clause 'bind' not yet implemented}}
@@ -517,7 +514,6 @@ void uses() {
517514
// expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}}
518515
#pragma acc parallel loop reduction(+:Var) independent
519516
for(unsigned i = 0; i < 5; ++i);
520-
// expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}}
521517
#pragma acc parallel loop collapse(1) independent
522518
for(unsigned i = 0; i < 5; ++i);
523519
// expected-warning@+1{{OpenACC clause 'bind' not yet implemented}}
@@ -653,7 +649,6 @@ void uses() {
653649
// expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}}
654650
#pragma acc parallel loop seq reduction(+:Var)
655651
for(unsigned i = 0; i < 5; ++i);
656-
// expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}}
657652
#pragma acc parallel loop seq collapse(1)
658653
for(unsigned i = 0; i < 5; ++i);
659654
// expected-warning@+1{{OpenACC clause 'bind' not yet implemented}}
@@ -788,7 +783,6 @@ void uses() {
788783
// expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}}
789784
#pragma acc parallel loop reduction(+:Var) seq
790785
for(unsigned i = 0; i < 5; ++i);
791-
// expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}}
792786
#pragma acc parallel loop collapse(1) seq
793787
for(unsigned i = 0; i < 5; ++i);
794788
// expected-warning@+1{{OpenACC clause 'bind' not yet implemented}}

0 commit comments

Comments
 (0)