[clang] 463529f - [OpenACC] Implement 'tile' clause parsing
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 26 08:53:58 PST 2024
Author: erichkeane
Date: 2024-01-26T08:53:51-08:00
New Revision: 463529f31b90c9bc8c564a2071748683af166f11
URL: https://github.com/llvm/llvm-project/commit/463529f31b90c9bc8c564a2071748683af166f11
DIFF: https://github.com/llvm/llvm-project/commit/463529f31b90c9bc8c564a2071748683af166f11.diff
LOG: [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.
Added:
Modified:
clang/include/clang/Basic/OpenACCKinds.h
clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseOpenACC.cpp
clang/test/ParserOpenACC/parse-clauses.c
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index 3f8225c40b64187..3662798fa5abaea 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -241,6 +241,8 @@ enum class OpenACCClauseKind {
/// 'async' clause, allowed on Compute, Data, 'update', 'wait', and Combined
/// constructs.
Async,
+ /// 'tile' clause, allowed on 'loop' and Combined constructs.
+ Tile,
/// Represents an invalid clause, for the purposes of parsing.
Invalid,
@@ -366,6 +368,9 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
case OpenACCClauseKind::Async:
return Out << "async";
+ case OpenACCClauseKind::Tile:
+ return Out << "tile";
+
case OpenACCClauseKind::Invalid:
return Out << "<invalid>";
}
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index b9464002dec646e..bde1ac2242cd6c2 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3592,6 +3592,10 @@ class Parser : public CodeCompletionHandler {
/// Parses the 'async-argument', which is an integral value with two
/// 'special' values that are likely negative (but come from Macros).
ExprResult ParseOpenACCAsyncArgument();
+ /// Parses the 'size-expr', which is an integral value, or an asterisk.
+ bool ParseOpenACCSizeExpr();
+ /// Parses a comma delimited list of 'size-expr's.
+ bool ParseOpenACCSizeExprList();
private:
//===--------------------------------------------------------------------===//
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index b7b824d55fbcc95..57aa80156531c26 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -124,6 +124,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
.Case("reduction", OpenACCClauseKind::Reduction)
.Case("self", OpenACCClauseKind::Self)
.Case("seq", OpenACCClauseKind::Seq)
+ .Case("tile", OpenACCClauseKind::Tile)
.Case("use_device", OpenACCClauseKind::UseDevice)
.Case("vector", OpenACCClauseKind::Vector)
.Case("vector_length", OpenACCClauseKind::VectorLength)
@@ -494,6 +495,7 @@ ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
case OpenACCClauseKind::DefaultAsync:
case OpenACCClauseKind::DeviceType:
case OpenACCClauseKind::DType:
+ case OpenACCClauseKind::Tile:
return ClauseParensKind::Required;
case OpenACCClauseKind::Auto:
@@ -618,6 +620,47 @@ bool Parser::ParseOpenACCDeviceTypeList() {
return false;
}
+/// OpenACC 3.3 Section 2.9:
+/// size-expr is one of:
+// *
+// int-expr
+// Note that this is specified under 'gang-arg-list', but also applies to 'tile'
+// via reference.
+bool Parser::ParseOpenACCSizeExpr() {
+ // FIXME: Ensure these are constant expressions.
+
+ // The size-expr ends up being ambiguous when only looking at the current
+ // token, as it could be a deref of a variable/expression.
+ if (getCurToken().is(tok::star) &&
+ NextToken().isOneOf(tok::comma, tok::r_paren)) {
+ ConsumeToken();
+ return false;
+ }
+
+ return getActions()
+ .CorrectDelayedTyposInExpr(ParseAssignmentExpression())
+ .isInvalid();
+}
+
+bool Parser::ParseOpenACCSizeExprList() {
+ if (ParseOpenACCSizeExpr()) {
+ SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
+ Parser::StopBeforeMatch);
+ return false;
+ }
+
+ while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
+ ExpectAndConsume(tok::comma);
+
+ if (ParseOpenACCSizeExpr()) {
+ SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end,
+ Parser::StopBeforeMatch);
+ return false;
+ }
+ }
+ return false;
+}
+
// The OpenACC Clause List is a comma or space-delimited list of clauses (see
// the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't
// really have its owner grammar and each individual one has its own definition.
@@ -757,6 +800,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
return true;
}
break;
+ case OpenACCClauseKind::Tile:
+ if (ParseOpenACCSizeExprList())
+ return true;
+ break;
default:
llvm_unreachable("Not a required parens type?");
}
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index b2c5c764e3f3b73..03a9468bed0a144 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -1049,6 +1049,68 @@ void AsyncArgument() {
#pragma acc parallel async(acc_async_sync)
}
+void Tile() {
+
+ int* Foo;
+ // expected-error at +2{{expected '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile
+ for(;;){}
+ // expected-error at +4{{expected expression}}
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(
+ for(;;){}
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile()
+ for(;;){}
+ // expected-error at +4{{expected expression}}
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(,
+ for(;;){}
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(,)
+ for(;;){}
+ // expected-error at +2{{use of undeclared identifier 'invalid'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(returns_int(), *, invalid, *)
+ for(;;){}
+
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(returns_int() *, Foo, *)
+ for(;;){}
+
+ // expected-error at +2{{indirection requires pointer operand ('int' invalid)}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(* returns_int() , *)
+ for(;;){}
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(*)
+ for(;;){}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(*Foo, *Foo)
+ for(;;){}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(5)
+ for(;;){}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(*, 5)
+ for(;;){}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(5, *)
+ for(;;){}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc loop tile(5, *, 3, *)
+ for(;;){}
+}
+
// expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc routine worker, vector, seq, nohost
void bar();
More information about the cfe-commits
mailing list