diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2016-04-12 05:28:34 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-04-12 05:28:34 +0000 |
commit | e48a5fc56d7dbd6e24e7fd326c3e50630b648da7 (patch) | |
tree | e9e2cf0caa3edc7fdd7fce9eb509571ab2b2fa61 /clang/lib/Parse/ParseOpenMP.cpp | |
parent | 94f58e79aebff75f955f888f223cc2d507c41f20 (diff) | |
download | bcm5719-llvm-e48a5fc56d7dbd6e24e7fd326c3e50630b648da7.tar.gz bcm5719-llvm-e48a5fc56d7dbd6e24e7fd326c3e50630b648da7.zip |
[OPENMP 4.0] Support for 'uniform' clause in 'declare simd' directive.
OpenMP 4.0 defines clause 'uniform' in 'declare simd' directive:
'uniform' '(' <argument-list> ')'
The uniform clause declares one or more arguments to have an invariant value for all concurrent invocations of the function in the execution of a single SIMD loop.
The special this pointer can be used as if was one of the arguments to the function in any of the linear, aligned, or uniform clauses.
llvm-svn: 266041
Diffstat (limited to 'clang/lib/Parse/ParseOpenMP.cpp')
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 269 |
1 files changed, 139 insertions, 130 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index a874b8e8ebf..6112c90cacd 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -332,10 +332,12 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { /// Parses clauses for 'declare simd' directive. /// clause: /// 'inbranch' | 'notinbranch' -/// 'simdlen' '('<expr> ')' +/// 'simdlen' '(' <expr> ')' +/// { 'uniform' '(' <argument_list> ')' } static bool parseDeclareSimdClauses(Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, - ExprResult &SimdLen) { + ExprResult &SimdLen, + SmallVectorImpl<Expr *> &Uniforms) { SourceRange BSRange; const Token &Tok = P.getCurToken(); bool IsError = false; @@ -367,6 +369,13 @@ static bool parseDeclareSimdClauses(Parser &P, SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc); if (SimdLen.isInvalid()) IsError = true; + } else if (ClauseName.equals("uniform")) { + Parser::OpenMPVarListDataTy Data; + + P.ConsumeToken(); + if (P.ParseOpenMPVarList(OMPD_declare_simd, + getOpenMPClauseKind(ClauseName), Uniforms, Data)) + IsError = true; } else // TODO: add parsing of other clauses. break; @@ -446,7 +455,8 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr, OMPDeclareSimdDeclAttr::BranchStateTy BS = OMPDeclareSimdDeclAttr::BS_Undefined; ExprResult Simdlen; - bool IsError = parseDeclareSimdClauses(*this, BS, Simdlen); + SmallVector<Expr *, 4> Uniforms; + bool IsError = parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms); // Need to check for extra tokens. if (Tok.isNot(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::warn_omp_extra_tokens_at_eol) @@ -457,8 +467,8 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr, // Skip the last annot_pragma_openmp_end. SourceLocation EndLoc = ConsumeToken(); if (!IsError) - return Actions.ActOnOpenMPDeclareSimdDirective(Ptr, BS, Simdlen.get(), - SourceRange(Loc, EndLoc)); + return Actions.ActOnOpenMPDeclareSimdDirective( + Ptr, BS, Simdlen.get(), Uniforms, SourceRange(Loc, EndLoc)); return Ptr; } @@ -526,8 +536,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( // ConsumeToken(); CachedTokens Toks; - ConsumeAndStoreUntil(tok::annot_pragma_openmp_end, Toks, - /*StopAtSemi=*/false, /*ConsumeFinalToken=*/true); + while(Tok.isNot(tok::annot_pragma_openmp_end)) { + Toks.push_back(Tok); + ConsumeAnyToken(); + } + Toks.push_back(Tok); + ConsumeAnyToken(); DeclGroupPtrTy Ptr; if (Tok.is(tok::annot_pragma_openmp)) @@ -1081,6 +1095,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); break; case OMPC_threadprivate: + case OMPC_uniform: Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -1402,61 +1417,20 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, TemplateKWLoc, ReductionId); } -/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', -/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'. -/// -/// private-clause: -/// 'private' '(' list ')' -/// firstprivate-clause: -/// 'firstprivate' '(' list ')' -/// lastprivate-clause: -/// 'lastprivate' '(' list ')' -/// shared-clause: -/// 'shared' '(' list ')' -/// linear-clause: -/// 'linear' '(' linear-list [ ':' linear-step ] ')' -/// aligned-clause: -/// 'aligned' '(' list [ ':' alignment ] ')' -/// reduction-clause: -/// 'reduction' '(' reduction-identifier ':' list ')' -/// copyprivate-clause: -/// 'copyprivate' '(' list ')' -/// flush-clause: -/// 'flush' '(' list ')' -/// depend-clause: -/// 'depend' '(' in | out | inout : list | source ')' -/// map-clause: -/// 'map' '(' [ [ always , ] -/// to | from | tofrom | alloc | release | delete ':' ] list ')'; -/// -/// For 'linear' clause linear-list may have the following forms: -/// list -/// modifier(list) -/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++). -OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, - OpenMPClauseKind Kind) { - SourceLocation Loc = Tok.getLocation(); - SourceLocation LOpen = ConsumeToken(); - SourceLocation ColonLoc = SourceLocation(); - // Optional scope specifier and unqualified id for reduction identifier. - CXXScopeSpec ReductionIdScopeSpec; - UnqualifiedId ReductionId; +/// Parses clauses with list. +bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, + OpenMPClauseKind Kind, + SmallVectorImpl<Expr *> &Vars, + OpenMPVarListDataTy &Data) { + UnqualifiedId UnqualifiedReductionId; bool InvalidReductionId = false; - OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; - // OpenMP 4.1 [2.15.3.7, linear Clause] - // If no modifier is specified it is assumed to be val. - OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val; - OpenMPMapClauseKind MapType = OMPC_MAP_unknown; - OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown; - bool MapTypeIsImplicit = false; bool MapTypeModifierSpecified = false; - SourceLocation DepLinMapLoc; // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, getOpenMPClauseName(Kind))) - return nullptr; + return true; bool NeedRParenForLinear = false; BalancedDelimiterTracker LinearT(*this, tok::l_paren, @@ -1465,47 +1439,45 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, if (Kind == OMPC_reduction) { ColonProtectionRAIIObject ColonRAII(*this); if (getLangOpts().CPlusPlus) - ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, + ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec, /*ObjectType=*/nullptr, /*EnteringContext=*/false); - InvalidReductionId = - ParseReductionId(*this, ReductionIdScopeSpec, ReductionId); + InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec, + UnqualifiedReductionId); if (InvalidReductionId) { SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); } - if (Tok.is(tok::colon)) { - ColonLoc = ConsumeToken(); - } else { + if (Tok.is(tok::colon)) + Data.ColonLoc = ConsumeToken(); + else Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier"; - } + if (!InvalidReductionId) + Data.ReductionId = + Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); } else if (Kind == OMPC_depend) { // Handle dependency type for depend clause. ColonProtectionRAIIObject ColonRAII(*this); - DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType( - Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "")); - DepLinMapLoc = Tok.getLocation(); + Data.DepKind = + static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType( + Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "")); + Data.DepLinMapLoc = Tok.getLocation(); - if (DepKind == OMPC_DEPEND_unknown) { + if (Data.DepKind == OMPC_DEPEND_unknown) { SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); } else { ConsumeToken(); // Special processing for depend(source) clause. - if (DKind == OMPD_ordered && DepKind == OMPC_DEPEND_source) { + if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) { // Parse ')'. T.consumeClose(); - return Actions.ActOnOpenMPVarListClause( - Kind, llvm::None, /*TailExpr=*/nullptr, Loc, LOpen, - /*ColonLoc=*/SourceLocation(), Tok.getLocation(), - ReductionIdScopeSpec, DeclarationNameInfo(), DepKind, - LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit, - DepLinMapLoc); + return false; } } - if (Tok.is(tok::colon)) { - ColonLoc = ConsumeToken(); - } else { + if (Tok.is(tok::colon)) + Data.ColonLoc = ConsumeToken(); + else { Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren : diag::warn_pragma_expected_colon) << "dependency type"; @@ -1513,9 +1485,9 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, } else if (Kind == OMPC_linear) { // Try to parse modifier if any. if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) { - LinearModifier = static_cast<OpenMPLinearClauseKind>( + Data.LinKind = static_cast<OpenMPLinearClauseKind>( getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); - DepLinMapLoc = ConsumeToken(); + Data.DepLinMapLoc = ConsumeToken(); LinearT.consumeOpen(); NeedRParenForLinear = true; } @@ -1525,79 +1497,76 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, /// The map clause modifier token can be either a identifier or the C++ /// delete keyword. - auto IsMapClauseModifierToken = [](const Token &Tok) { + auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool { return Tok.isOneOf(tok::identifier, tok::kw_delete); }; // The first identifier may be a list item, a map-type or a // map-type-modifier. The map modifier can also be delete which has the same // spelling of the C++ delete keyword. - MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType( - Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : "")); - DepLinMapLoc = Tok.getLocation(); + Data.MapType = + IsMapClauseModifierToken(Tok) + ? static_cast<OpenMPMapClauseKind>( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) + : OMPC_MAP_unknown; + Data.DepLinMapLoc = Tok.getLocation(); bool ColonExpected = false; if (IsMapClauseModifierToken(Tok)) { if (PP.LookAhead(0).is(tok::colon)) { - MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType( - Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : "")); - if (MapType == OMPC_MAP_unknown) { + if (Data.MapType == OMPC_MAP_unknown) Diag(Tok, diag::err_omp_unknown_map_type); - } else if (MapType == OMPC_MAP_always) { + else if (Data.MapType == OMPC_MAP_always) Diag(Tok, diag::err_omp_map_type_missing); - } ConsumeToken(); } else if (PP.LookAhead(0).is(tok::comma)) { if (IsMapClauseModifierToken(PP.LookAhead(1)) && PP.LookAhead(2).is(tok::colon)) { - MapTypeModifier = - static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType( - Kind, - IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : "")); - if (MapTypeModifier != OMPC_MAP_always) { + Data.MapTypeModifier = Data.MapType; + if (Data.MapTypeModifier != OMPC_MAP_always) { Diag(Tok, diag::err_omp_unknown_map_type_modifier); - MapTypeModifier = OMPC_MAP_unknown; - } else { + Data.MapTypeModifier = OMPC_MAP_unknown; + } else MapTypeModifierSpecified = true; - } ConsumeToken(); ConsumeToken(); - MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType( - Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : "")); - if (MapType == OMPC_MAP_unknown || MapType == OMPC_MAP_always) { + Data.MapType = + IsMapClauseModifierToken(Tok) + ? static_cast<OpenMPMapClauseKind>( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) + : OMPC_MAP_unknown; + if (Data.MapType == OMPC_MAP_unknown || + Data.MapType == OMPC_MAP_always) Diag(Tok, diag::err_omp_unknown_map_type); - } ConsumeToken(); } else { - MapType = OMPC_MAP_tofrom; - MapTypeIsImplicit = true; + Data.MapType = OMPC_MAP_tofrom; + Data.IsMapTypeImplicit = true; } } else { - MapType = OMPC_MAP_tofrom; - MapTypeIsImplicit = true; + Data.MapType = OMPC_MAP_tofrom; + Data.IsMapTypeImplicit = true; } } else { - MapType = OMPC_MAP_tofrom; - MapTypeIsImplicit = true; + Data.MapType = OMPC_MAP_tofrom; + Data.IsMapTypeImplicit = true; } - if (Tok.is(tok::colon)) { - ColonLoc = ConsumeToken(); - } else if (ColonExpected) { + if (Tok.is(tok::colon)) + Data.ColonLoc = ConsumeToken(); + else if (ColonExpected) Diag(Tok, diag::warn_pragma_expected_colon) << "map type"; - } } - SmallVector<Expr *, 5> Vars; bool IsComma = - ((Kind != OMPC_reduction) && (Kind != OMPC_depend) && - (Kind != OMPC_map)) || - ((Kind == OMPC_reduction) && !InvalidReductionId) || - ((Kind == OMPC_map) && (MapType != OMPC_MAP_unknown) && - (!MapTypeModifierSpecified || MapTypeModifier == OMPC_MAP_always)) || - ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown); + (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) || + (Kind == OMPC_reduction && !InvalidReductionId) || + (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown && + (!MapTypeModifierSpecified || + Data.MapTypeModifier == OMPC_MAP_always)) || + (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown); const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && Tok.isNot(tok::annot_pragma_openmp_end))) { @@ -1605,9 +1574,9 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, // Parse variable ExprResult VarExpr = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); - if (VarExpr.isUsable()) { + if (VarExpr.isUsable()) Vars.push_back(VarExpr.get()); - } else { + else { SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); } @@ -1629,15 +1598,14 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, LinearT.consumeClose(); // Parse ':' linear-step (or ':' alignment). - Expr *TailExpr = nullptr; const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon); if (MustHaveTail) { - ColonLoc = Tok.getLocation(); + Data.ColonLoc = Tok.getLocation(); SourceLocation ELoc = ConsumeToken(); ExprResult Tail = ParseAssignmentExpression(); Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc); if (Tail.isUsable()) - TailExpr = Tail.get(); + Data.TailExpr = Tail.get(); else SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -1645,18 +1613,59 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, // Parse ')'. T.consumeClose(); - if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) || + if ((Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown && + Vars.empty()) || (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || - (MustHaveTail && !TailExpr) || InvalidReductionId) { + (MustHaveTail && !Data.TailExpr) || InvalidReductionId) + return true; + return false; +} + +/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', +/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'. +/// +/// private-clause: +/// 'private' '(' list ')' +/// firstprivate-clause: +/// 'firstprivate' '(' list ')' +/// lastprivate-clause: +/// 'lastprivate' '(' list ')' +/// shared-clause: +/// 'shared' '(' list ')' +/// linear-clause: +/// 'linear' '(' linear-list [ ':' linear-step ] ')' +/// aligned-clause: +/// 'aligned' '(' list [ ':' alignment ] ')' +/// reduction-clause: +/// 'reduction' '(' reduction-identifier ':' list ')' +/// copyprivate-clause: +/// 'copyprivate' '(' list ')' +/// flush-clause: +/// 'flush' '(' list ')' +/// depend-clause: +/// 'depend' '(' in | out | inout : list | source ')' +/// map-clause: +/// 'map' '(' [ [ always , ] +/// to | from | tofrom | alloc | release | delete ':' ] list ')'; +/// +/// For 'linear' clause linear-list may have the following forms: +/// list +/// modifier(list) +/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++). +OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, + OpenMPClauseKind Kind) { + SourceLocation Loc = Tok.getLocation(); + SourceLocation LOpen = ConsumeToken(); + SmallVector<Expr *, 4> Vars; + OpenMPVarListDataTy Data; + + if (ParseOpenMPVarList(DKind, Kind, Vars, Data)) return nullptr; - } return Actions.ActOnOpenMPVarListClause( - Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(), - ReductionIdScopeSpec, - ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId) - : DeclarationNameInfo(), - DepKind, LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit, - DepLinMapLoc); + Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(), + Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind, + Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit, + Data.DepLinMapLoc); } |