[PATCH] D10599: [OPENMP 4.0] Initial support for '#pragma omp declare simd' directive.

hfinkel at anl.gov hfinkel at anl.gov
Wed Jul 8 17:50:41 PDT 2015


hfinkel added a comment.

In http://reviews.llvm.org/D10599#201312, @aaron.ballman wrote:

> LGTM with one question below. I would wait for review from Richard or
>  Hal before committing.


I'm not really the right person to okay this patch. Richard, can you please look at this?

> 

> 

> > Index: lib/Parse/ParseOpenMP.cpp

> 

> >  ===================================================================

> 

> > 

> 

> >   - lib/Parse/ParseOpenMP.cpp +++ lib/Parse/ParseOpenMP.cpp @@ -30,6 +30,7 @@ // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd // TODO: add other combined directives in topological order. const OpenMPDirectiveKind F[][3] = { +      {OMPD_unknown /*declare*/, OMPD_simd, OMPD_declare_simd}, {OMPD_unknown /*cancellation*/, OMPD_unknown /*point*/, OMPD_cancellation_point}, {OMPD_for, OMPD_simd, OMPD_for_simd}, @@ -43,25 +44,25 @@ : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok)); bool TokenMatched = false; for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {

> 

> > - if (!Tok.isAnnotation() && DKind == OMPD_unknown) { +    if (!Tok.isAnnotation() && DKind == OMPD_unknown) TokenMatched =

> 

> > - (i == 0) &&

> 

> > - !P.getPreprocessor().getSpelling(Tok).compare("cancellation");

> 

> > - } else { +          ((i == 0) && +           !P.getPreprocessor().getSpelling(Tok).compare("declare")) || +          ((i == 1) && +           !P.getPreprocessor().getSpelling(Tok).compare("cancellation")); +    else TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown;

> 

> > - } if (TokenMatched) { Tok = P.getPreprocessor().LookAhead(0); auto SDKind = Tok.isAnnotation() ? OMPD_unknown : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));

> 

> > - if (!Tok.isAnnotation() && DKind == OMPD_unknown) { +      if (!Tok.isAnnotation() && SDKind == OMPD_unknown) TokenMatched =

> 

> > - (i == 0) && !P.getPreprocessor().getSpelling(Tok).compare("point");

> 

> > - } else { +            (i == 1) && !P.getPreprocessor().getSpelling(Tok).compare("point"); +      else TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown;

> 

> > - } if (TokenMatched) { P.ConsumeToken(); DKind = F[i][2]; @@ -75,14 +76,25 @@ /// ///       threadprivate-directive: ///         annot_pragma_openmp 'threadprivate' simple-variable-list +///         annot_pragma_omp_end /// -Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { +///       declare-simd-directive: +///         annot_pragma_openmp 'declare simd' {<clause> [,]} +///         annot_pragma_omp_end +///         <function declaration/definition> +/// +Parser::DeclGroupPtrTy +Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(bool IsInTagDecl, +                                                   unsigned Level) { assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); ParenBraceBracketBalancer BalancerRAIIObj(*this);

> 

> > 

> 

> >   +  auto AnnotationVal = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()); SourceLocation Loc = ConsumeToken(); SmallVector<Expr *, 5> Identifiers;

> 

> > - auto DKind = ParseOpenMPDirectiveKind(*this); +  OpenMPDirectiveKind DKind = +      (AnnotationVal == 0) ? ParseOpenMPDirectiveKind(*this) +                           : static_cast<OpenMPDirectiveKind>(AnnotationVal);

> 

> > 

> 

> >   switch (DKind) { case OMPD_threadprivate: @@ -100,6 +112,86 @@ return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers); } break; +  case OMPD_declare_simd: { +    // The syntax is: +    // { #pragma omp declare simd } +    // <function-declaration-or-definition> +    // +    if (AnnotationVal == 0) +      // Skip 'simd' if it was restored from cached tokens. +      ConsumeToken(); +    if (IsInTagDecl) { +      LateParseOpenMPDeclarativeDirectiveWithTemplateFunction( +          /*DKind=*/OMPD_declare_simd, Loc); +      return DeclGroupPtrTy(); +    } + +    SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> +        FirstClauses(OMPC_unknown + 1); +    SmallVector<OMPClause *, 4> Clauses; +    SmallVector<Token, 8> CachedPragmas; + +    while (Tok.isNot(tok::annot_pragma_openmp_end) && Tok.isNot(tok::eof)) { +      CachedPragmas.push_back(Tok); +      ConsumeAnyToken(); +    } +    CachedPragmas.push_back(Tok); +    if (Tok.isNot(tok::eof)) +      ConsumeAnyToken(); + +    DeclGroupPtrTy Ptr; +    if (Tok.is(tok::annot_pragma_openmp)) { +      Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(IsInTagDecl, Level + 1); +    } else { +      // Here we expect to see some function declaration. +      ParsedAttributesWithRange Attrs(AttrFactory); +      MaybeParseCXX11Attributes(Attrs); +      MaybeParseMicrosoftAttributes(Attrs); +      ParsingDeclSpec PDS(*this); +      Ptr = ParseExternalDeclaration(Attrs, &PDS); +    } +    if (!Ptr || Ptr.get().isNull()) +      return DeclGroupPtrTy(); +    if (Ptr.get().isDeclGroup()) { +      Diag(Tok, diag::err_omp_single_decl_in_declare_simd); +      return DeclGroupPtrTy();

> 

> 

> Would it make sense to return Ptr here instead so that further

>  diagnostics can be reported?

> 

> ~Aaron





================
Comment at: lib/Parse/ParseOpenMP.cpp:149
@@ +148,3 @@
+      MaybeParseCXX11Attributes(Attrs);
+      MaybeParseMicrosoftAttributes(Attrs);
+      ParsingDeclSpec PDS(*this);
----------------
This is not your fault, and should not be fixed by this patch, but this series of three:

      ParsedAttributesWithRange Attrs(AttrFactory);
      MaybeParseCXX11Attributes(Attrs);
      MaybeParseMicrosoftAttributes(Attrs);

occurs a lot. It would be nice to factor this into one function to reduce the amount of repeated logic.



http://reviews.llvm.org/D10599







More information about the cfe-commits mailing list