Skip to content

Commit 463529f

Browse files
committed
[OpenACC] Implement 'tile' clause parsing
The 'tile' clause takes a 'size-expr-list', where a 'size-expr' is either an asterisk or an integral constant expression. This patch parsess it as an assignment expression, which we'll check for constness and type in Sema.
1 parent 67c1c1d commit 463529f

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

clang/include/clang/Basic/OpenACCKinds.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ enum class OpenACCClauseKind {
241241
/// 'async' clause, allowed on Compute, Data, 'update', 'wait', and Combined
242242
/// constructs.
243243
Async,
244+
/// 'tile' clause, allowed on 'loop' and Combined constructs.
245+
Tile,
244246

245247
/// Represents an invalid clause, for the purposes of parsing.
246248
Invalid,
@@ -366,6 +368,9 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
366368
case OpenACCClauseKind::Async:
367369
return Out << "async";
368370

371+
case OpenACCClauseKind::Tile:
372+
return Out << "tile";
373+
369374
case OpenACCClauseKind::Invalid:
370375
return Out << "<invalid>";
371376
}

clang/include/clang/Parse/Parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3592,6 +3592,10 @@ class Parser : public CodeCompletionHandler {
35923592
/// Parses the 'async-argument', which is an integral value with two
35933593
/// 'special' values that are likely negative (but come from Macros).
35943594
ExprResult ParseOpenACCAsyncArgument();
3595+
/// Parses the 'size-expr', which is an integral value, or an asterisk.
3596+
bool ParseOpenACCSizeExpr();
3597+
/// Parses a comma delimited list of 'size-expr's.
3598+
bool ParseOpenACCSizeExprList();
35953599

35963600
private:
35973601
//===--------------------------------------------------------------------===//

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
124124
.Case("reduction", OpenACCClauseKind::Reduction)
125125
.Case("self", OpenACCClauseKind::Self)
126126
.Case("seq", OpenACCClauseKind::Seq)
127+
.Case("tile", OpenACCClauseKind::Tile)
127128
.Case("use_device", OpenACCClauseKind::UseDevice)
128129
.Case("vector", OpenACCClauseKind::Vector)
129130
.Case("vector_length", OpenACCClauseKind::VectorLength)
@@ -494,6 +495,7 @@ ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
494495
case OpenACCClauseKind::DefaultAsync:
495496
case OpenACCClauseKind::DeviceType:
496497
case OpenACCClauseKind::DType:
498+
case OpenACCClauseKind::Tile:
497499
return ClauseParensKind::Required;
498500

499501
case OpenACCClauseKind::Auto:
@@ -618,6 +620,47 @@ bool Parser::ParseOpenACCDeviceTypeList() {
618620
return false;
619621
}
620622

623+
/// OpenACC 3.3 Section 2.9:
624+
/// size-expr is one of:
625+
// *
626+
// int-expr
627+
// Note that this is specified under 'gang-arg-list', but also applies to 'tile'
628+
// via reference.
629+
bool Parser::ParseOpenACCSizeExpr() {
630+
// FIXME: Ensure these are constant expressions.
631+
632+
// The size-expr ends up being ambiguous when only looking at the current
633+
// token, as it could be a deref of a variable/expression.
634+
if (getCurToken().is(tok::star) &&
635+
NextToken().isOneOf(tok::comma, tok::r_paren)) {
636+
ConsumeToken();
637+
return false;
638+
}
639+
640+
return getActions()
641+
.CorrectDelayedTyposInExpr(ParseAssignmentExpression())
642+
.isInvalid();
643+
}
644+
645+
bool Parser::ParseOpenACCSizeExprList() {
646+
if (ParseOpenACCSizeExpr()) {
647+
SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
648+
Parser::StopBeforeMatch);
649+
return false;
650+
}
651+
652+
while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
653+
ExpectAndConsume(tok::comma);
654+
655+
if (ParseOpenACCSizeExpr()) {
656+
SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
657+
Parser::StopBeforeMatch);
658+
return false;
659+
}
660+
}
661+
return false;
662+
}
663+
621664
// The OpenACC Clause List is a comma or space-delimited list of clauses (see
622665
// the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't
623666
// really have its owner grammar and each individual one has its own definition.
@@ -757,6 +800,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
757800
return true;
758801
}
759802
break;
803+
case OpenACCClauseKind::Tile:
804+
if (ParseOpenACCSizeExprList())
805+
return true;
806+
break;
760807
default:
761808
llvm_unreachable("Not a required parens type?");
762809
}

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,68 @@ void AsyncArgument() {
10491049
#pragma acc parallel async(acc_async_sync)
10501050
}
10511051

1052+
void Tile() {
1053+
1054+
int* Foo;
1055+
// expected-error@+2{{expected '('}}
1056+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1057+
#pragma acc loop tile
1058+
for(;;){}
1059+
// expected-error@+4{{expected expression}}
1060+
// expected-error@+3{{expected ')'}}
1061+
// expected-note@+2{{to match this '('}}
1062+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1063+
#pragma acc loop tile(
1064+
for(;;){}
1065+
// expected-error@+2{{expected expression}}
1066+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1067+
#pragma acc loop tile()
1068+
for(;;){}
1069+
// expected-error@+4{{expected expression}}
1070+
// expected-error@+3{{expected ')'}}
1071+
// expected-note@+2{{to match this '('}}
1072+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1073+
#pragma acc loop tile(,
1074+
for(;;){}
1075+
// expected-error@+2{{expected expression}}
1076+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1077+
#pragma acc loop tile(,)
1078+
for(;;){}
1079+
// expected-error@+2{{use of undeclared identifier 'invalid'}}
1080+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1081+
#pragma acc loop tile(returns_int(), *, invalid, *)
1082+
for(;;){}
1083+
1084+
// expected-error@+2{{expected expression}}
1085+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1086+
#pragma acc loop tile(returns_int() *, Foo, *)
1087+
for(;;){}
1088+
1089+
// expected-error@+2{{indirection requires pointer operand ('int' invalid)}}
1090+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1091+
#pragma acc loop tile(* returns_int() , *)
1092+
for(;;){}
1093+
1094+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1095+
#pragma acc loop tile(*)
1096+
for(;;){}
1097+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1098+
#pragma acc loop tile(*Foo, *Foo)
1099+
for(;;){}
1100+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1101+
#pragma acc loop tile(5)
1102+
for(;;){}
1103+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1104+
#pragma acc loop tile(*, 5)
1105+
for(;;){}
1106+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1107+
#pragma acc loop tile(5, *)
1108+
for(;;){}
1109+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
1110+
#pragma acc loop tile(5, *, 3, *)
1111+
for(;;){}
1112+
}
1113+
10521114
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
10531115
#pragma acc routine worker, vector, seq, nohost
10541116
void bar();

0 commit comments

Comments
 (0)