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@+2{{expected '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile + for(;;){} + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile( + for(;;){} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile() + for(;;){} + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(, + for(;;){} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(,) + for(;;){} + // expected-error@+2{{use of undeclared identifier 'invalid'}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(returns_int(), *, invalid, *) + for(;;){} + + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(returns_int() *, Foo, *) + for(;;){} + + // expected-error@+2{{indirection requires pointer operand ('int' invalid)}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(* returns_int() , *) + for(;;){} + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(*) + for(;;){} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(*Foo, *Foo) + for(;;){} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(5) + for(;;){} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(*, 5) + for(;;){} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(5, *) + for(;;){} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop tile(5, *, 3, *) + for(;;){} +} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc routine worker, vector, seq, nohost void bar(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits