diff options
author | Michael Kruse <llvm@meinersbur.de> | 2019-02-22 22:29:42 +0000 |
---|---|---|
committer | Michael Kruse <llvm@meinersbur.de> | 2019-02-22 22:29:42 +0000 |
commit | 8130704f582967dffaa0e99c1fe23889c2b6a0ba (patch) | |
tree | 6435791d09cf0701342a05448997fa57551ebd12 /lib/Parse | |
parent | 9bd1142fd002ee84a142e7cea3a02452487ef9bf (diff) |
[OpenMP 5.0] Parsing/sema support for to clause with mapper modifier.
This patch implements the parsing and sema support for OpenMP to clause
with potential user-defined mappers attached. User defined mapper is a
new feature in OpenMP 5.0. A to/from clause can have an explicit or
implicit associated mapper, which instructs the compiler to generate and
use customized mapping functions. An example is shown below:
struct S { int len; int *d; };
#pragma omp declare mapper(id: struct S s) map(s, s.d[0:s.len])
struct S ss;
#pragma omp target update to(mapper(id): ss) // use the mapper with name 'id' to map ss to device
Contributed-by: <lildmh@gmail.com>
Differential Revision: https://reviews.llvm.org/D58523
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354698 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index fafc34c960..68843f0c65 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -1959,6 +1959,34 @@ static OpenMPMapModifierKind isMapModifier(Parser &P) { return TypeModifier; } +/// Parse the mapper modifier in map, to, and from clauses. +bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) { + // Parse '('. + BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon); + if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) { + SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); + return true; + } + // Parse mapper-identifier + if (getLangOpts().CPlusPlus) + ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, + /*ObjectType=*/nullptr, + /*EnteringContext=*/false); + if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) { + Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier); + SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); + return true; + } + auto &DeclNames = Actions.getASTContext().DeclarationNames; + Data.ReductionOrMapperId = DeclarationNameInfo( + DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation()); + ConsumeToken(); + // Parse ')'. + return T.consumeClose(); +} + /// Parse map-type-modifiers in map clause. /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) @@ -1974,30 +2002,8 @@ bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) { Data.MapTypeModifiers.push_back(TypeModifier); Data.MapTypeModifiersLoc.push_back(Tok.getLocation()); ConsumeToken(); - // Parse '('. - BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon); - if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPSimpleClauseTypeName( - OMPC_map, OMPC_MAP_MODIFIER_mapper))) { - SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch); - return true; - } - // Parse mapper-identifier - if (getLangOpts().CPlusPlus) - ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, - /*ObjectType=*/nullptr, - /*EnteringContext=*/false); - if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) { - Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier); - SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch); + if (parseMapperModifier(Data)) return true; - } - auto &DeclNames = Actions.getASTContext().DeclarationNames; - Data.ReductionOrMapperId = DeclarationNameInfo( - DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation()); - ConsumeToken(); - // Parse ')'. - T.consumeClose(); } else { // For the case of unknown map-type-modifier or a map-type. // Map-type is followed by a colon; the function returns when it @@ -2053,7 +2059,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPVarListDataTy &Data) { UnqualifiedId UnqualifiedReductionId; bool InvalidReductionId = false; - bool IsInvalidMapModifier = false; + bool IsInvalidMapperModifier = false; // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); @@ -2142,9 +2148,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // Only parse map-type-modifier[s] and map-type if a colon is present in // the map clause. if (ColonPresent) { - IsInvalidMapModifier = parseMapTypeModifiers(Data); - if (!IsInvalidMapModifier) + IsInvalidMapperModifier = parseMapTypeModifiers(Data); + if (!IsInvalidMapperModifier) parseMapType(*this, Data); + else + SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch); } if (Data.MapType == OMPC_MAP_unknown) { Data.MapType = OMPC_MAP_tofrom; @@ -2153,6 +2161,28 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, if (Tok.is(tok::colon)) Data.ColonLoc = ConsumeToken(); + } else if (Kind == OMPC_to) { + if (Tok.is(tok::identifier)) { + bool IsMapperModifier = false; + auto Modifier = static_cast<OpenMPToModifierKind>( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); + if (Modifier == OMPC_TO_MODIFIER_mapper) + IsMapperModifier = true; + if (IsMapperModifier) { + // Parse the mapper modifier. + ConsumeToken(); + IsInvalidMapperModifier = parseMapperModifier(Data); + if (Tok.isNot(tok::colon)) { + if (!IsInvalidMapperModifier) + Diag(Tok, diag::warn_pragma_expected_colon) << ")"; + SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); + } + // Consume ':'. + if (Tok.is(tok::colon)) + ConsumeToken(); + } + } } bool IsComma = @@ -2214,7 +2244,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Vars.empty()) || (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || (MustHaveTail && !Data.TailExpr) || InvalidReductionId || - IsInvalidMapModifier; + IsInvalidMapperModifier; } /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', @@ -2247,10 +2277,10 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// 'depend' '(' in | out | inout : list | source ')' /// map-clause: /// 'map' '(' [ [ always [,] ] [ close [,] ] -/// [ mapper(mapper-identifier) [,] ] +/// [ mapper '(' mapper-identifier ')' [,] ] /// to | from | tofrom | alloc | release | delete ':' ] list ')'; /// to-clause: -/// 'to' '(' list ')' +/// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')' /// from-clause: /// 'from' '(' list ')' /// use_device_ptr-clause: |