summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-03-30 10:43:55 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-03-30 10:43:55 +0000
commit587e1de4ea2af5a01f5d53647201c974a8fea1f2 (patch)
treeb792d7e01dbfff2d4cc77d4e4a50dc4ffae8c6ff /clang/lib
parent8e46cd05a17c0499f744a85f8ef905cafb47eb3e (diff)
downloadbcm5719-llvm-587e1de4ea2af5a01f5d53647201c974a8fea1f2.tar.gz
bcm5719-llvm-587e1de4ea2af5a01f5d53647201c974a8fea1f2.zip
[OPENMP 4.0] Initial support for '#pragma omp declare simd' directive.
Initial parsing/sema/serialization/deserialization support for '#pragma omp declare simd' directive. The 'declare simd' construct can be applied to a function to enable the creation of one or more versions that can process multiple arguments using SIMD instructions from a single invocation from a SIMD loop. If the function has any declarations, then the declare simd construct for any declaration that has one must be equivalent to the one specified for the definition. Otherwise, the result is unspecified. This pragma can be applied many times to the same declaration. Internally this pragma is represented as an attribute. But we need special processing for this pragma because it must be used before function declaration, this directive is applied to. Differential Revision: http://reviews.llvm.org/D10599 llvm-svn: 264853
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp2
-rw-r--r--clang/lib/Parse/ParseDecl.cpp6
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp3
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp57
-rw-r--r--clang/lib/Parse/Parser.cpp6
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp28
6 files changed, 95 insertions, 7 deletions
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 3b5bc56036b..fa40d016c9e 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -485,6 +485,8 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_declare_simd:
+ break;
case OMPD_cancel:
switch (CKind) {
#define OPENMP_CANCEL_CLAUSE(Name) \
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index fef5d8d4441..84204aadb18 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3654,8 +3654,10 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
}
if (Tok.is(tok::annot_pragma_openmp)) {
- // There may be declared reduction operator inside structure/union.
- (void)ParseOpenMPDeclarativeDirective(AS_public);
+ // Result can be ignored, because it must be always empty.
+ AccessSpecifier AS = AS_none;
+ ParsedAttributesWithRange Attrs(AttrFactory);
+ (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
continue;
}
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 9d8106361e6..cfe49ca2cc3 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2919,7 +2919,8 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
}
if (Tok.is(tok::annot_pragma_openmp))
- return ParseOpenMPDeclarativeDirective(AS);
+ return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, AccessAttrs, TagType,
+ TagDecl);
// Parse all the comma separated declarators.
return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList());
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 7a924b4ce2b..96cf37912f2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -65,6 +65,7 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
static const unsigned F[][3] = {
{ OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
{ OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
+ { OMPD_declare, OMPD_simd, OMPD_declare_simd },
{ OMPD_target, OMPD_data, OMPD_target_data },
{ OMPD_target, OMPD_enter, OMPD_target_enter },
{ OMPD_target, OMPD_exit, OMPD_target_exit },
@@ -332,8 +333,14 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
/// annot_pragma_openmp 'declare' 'reduction' [...]
/// annot_pragma_openmp_end
///
-Parser::DeclGroupPtrTy
-Parser::ParseOpenMPDeclarativeDirective(AccessSpecifier AS) {
+/// declare-simd-directive:
+/// annot_pragma_openmp 'declare simd' {<clause> [,]}
+/// annot_pragma_openmp_end
+/// <function declaration/definition>
+///
+Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
+ AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
+ DeclSpec::TST TagType, Decl *Tag) {
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
ParenBraceBracketBalancer BalancerRAIIObj(*this);
@@ -373,6 +380,47 @@ Parser::ParseOpenMPDeclarativeDirective(AccessSpecifier AS) {
return Res;
}
break;
+ case OMPD_declare_simd: {
+ // The syntax is:
+ // { #pragma omp declare simd }
+ // <function-declaration-or-definition>
+ //
+
+ ConsumeToken();
+ // The last seen token is annot_pragma_openmp_end - need to check for
+ // extra tokens.
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+ << getOpenMPDirectiveName(OMPD_declare_simd);
+ while (Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
+ }
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeToken();
+
+ DeclGroupPtrTy Ptr;
+ if (Tok.is(tok::annot_pragma_openmp)) {
+ Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
+ } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
+ // Here we expect to see some function declaration.
+ if (AS == AS_none) {
+ assert(TagType == DeclSpec::TST_unspecified);
+ MaybeParseCXX11Attributes(Attrs);
+ MaybeParseMicrosoftAttributes(Attrs);
+ ParsingDeclSpec PDS(*this);
+ Ptr = ParseExternalDeclaration(Attrs, &PDS);
+ } else {
+ Ptr =
+ ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
+ }
+ }
+ if (!Ptr) {
+ Diag(Loc, diag::err_omp_decl_in_declare_simd);
+ return DeclGroupPtrTy();
+ }
+
+ return Actions.ActOnOpenMPDeclareSimdDirective(Ptr, Loc);
+ }
case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive);
break;
@@ -627,6 +675,11 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
OMPDirectiveScope.Exit();
break;
}
+ case OMPD_declare_simd:
+ Diag(Tok, diag::err_omp_unexpected_directive)
+ << getOpenMPDirectiveName(DKind);
+ SkipUntil(tok::annot_pragma_openmp_end);
+ break;
case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive);
SkipUntil(tok::annot_pragma_openmp_end);
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 07f60cbbe16..9ed2d72fcd9 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -659,8 +659,10 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
case tok::annot_pragma_opencl_extension:
HandlePragmaOpenCLExtension();
return nullptr;
- case tok::annot_pragma_openmp:
- return ParseOpenMPDeclarativeDirective(/*AS=*/AS_none);
+ case tok::annot_pragma_openmp: {
+ AccessSpecifier AS = AS_none;
+ return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, attrs);
+ }
case tok::annot_pragma_ms_pointers_to_members:
HandlePragmaMSPointersToMembers();
return nullptr;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 8ce67c8f9c2..3c50eec3a67 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1701,6 +1701,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
case OMPD_target_enter_data:
case OMPD_target_exit_data:
case OMPD_declare_reduction:
+ case OMPD_declare_simd:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -3155,6 +3156,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
break;
case OMPD_threadprivate:
case OMPD_declare_reduction:
+ case OMPD_declare_simd:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -3175,6 +3177,32 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
return Res;
}
+Sema::DeclGroupPtrTy
+Sema::ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
+ SourceLocation StartLoc) {
+ if (!DG || DG.get().isNull())
+ return DeclGroupPtrTy();
+
+ if (!DG.get().isSingleDecl()) {
+ Diag(StartLoc, diag::err_omp_single_decl_in_declare_simd);
+ return DG;
+ }
+ auto *ADecl = DG.get().getSingleDecl();
+ if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
+ ADecl = FTD->getTemplatedDecl();
+
+ if (!isa<FunctionDecl>(ADecl)) {
+ Diag(ADecl->getLocation(), diag::err_omp_function_expected)
+ << ADecl->getDeclContext()->isFileContext();
+ return DeclGroupPtrTy();
+ }
+
+ auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
+ Context, SourceRange(StartLoc, StartLoc));
+ ADecl->addAttr(NewAttr);
+ return ConvertDeclToDeclGroup(ADecl);
+}
+
StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
OpenPOWER on IntegriCloud