[OPENMP 4.0] Support for 'inbranch|noinbranch' clauses in 'declare
simd'. Added parsing/semantic analysis for 'inbranch|notinbranch' clauses of '#pragma omp declare simd' construct. llvm-svn: 265287
This commit is contained in:
parent
1519491eaf
commit
20dfd77826
|
@ -2265,8 +2265,14 @@ def OMPDeclareSimdDecl : Attr {
|
||||||
let SemaHandler = 0;
|
let SemaHandler = 0;
|
||||||
let HasCustomParsing = 1;
|
let HasCustomParsing = 1;
|
||||||
let Documentation = [OMPDeclareSimdDocs];
|
let Documentation = [OMPDeclareSimdDocs];
|
||||||
|
let Args = [EnumArgument<"BranchState", "BranchStateTy",
|
||||||
|
["", "inbranch", "notinbranch"],
|
||||||
|
["BS_Undefined", "BS_Inbranch", "BS_Notinbranch"]>];
|
||||||
let AdditionalMembers = [{
|
let AdditionalMembers = [{
|
||||||
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {}
|
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
|
||||||
|
const {
|
||||||
|
OS << ' ' << ConvertBranchStateTyToStr(getBranchState());
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -961,6 +961,8 @@ def err_omp_unknown_map_type_modifier : Error<
|
||||||
"incorrect map type modifier, expected 'always'">;
|
"incorrect map type modifier, expected 'always'">;
|
||||||
def err_omp_map_type_missing : Error<
|
def err_omp_map_type_missing : Error<
|
||||||
"missing map type">;
|
"missing map type">;
|
||||||
|
def err_omp_declare_simd_inbranch_notinbranch : Error<
|
||||||
|
"unexpected '%0' clause, '%1' is specified already">;
|
||||||
|
|
||||||
// Pragma loop support.
|
// Pragma loop support.
|
||||||
def err_pragma_loop_missing_argument : Error<
|
def err_pragma_loop_missing_argument : Error<
|
||||||
|
|
|
@ -8091,8 +8091,10 @@ public:
|
||||||
|
|
||||||
/// \brief Called on well-formed '\#pragma omp declare simd' after parsing of
|
/// \brief Called on well-formed '\#pragma omp declare simd' after parsing of
|
||||||
/// the associated method/function.
|
/// the associated method/function.
|
||||||
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
|
DeclGroupPtrTy
|
||||||
SourceLocation StartLoc);
|
ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
|
||||||
|
OMPDeclareSimdDeclAttr::BranchStateTy BS,
|
||||||
|
SourceRange SR);
|
||||||
|
|
||||||
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
|
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
|
||||||
Expr *Expr,
|
Expr *Expr,
|
||||||
|
|
|
@ -323,6 +323,37 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
|
||||||
IsCorrect);
|
IsCorrect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses clauses for 'declare simd' directive.
|
||||||
|
/// clause:
|
||||||
|
/// 'inbranch' | 'notinbranch'
|
||||||
|
static void parseDeclareSimdClauses(Parser &P,
|
||||||
|
OMPDeclareSimdDeclAttr::BranchStateTy &BS) {
|
||||||
|
SourceRange BSRange;
|
||||||
|
const Token &Tok = P.getCurToken();
|
||||||
|
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||||
|
if (Tok.isNot(tok::identifier))
|
||||||
|
break;
|
||||||
|
OMPDeclareSimdDeclAttr::BranchStateTy Out;
|
||||||
|
StringRef TokName = Tok.getIdentifierInfo()->getName();
|
||||||
|
// Parse 'inranch|notinbranch' clauses.
|
||||||
|
if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(TokName, Out)) {
|
||||||
|
if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
|
||||||
|
P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
|
||||||
|
<< TokName << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS)
|
||||||
|
<< BSRange;
|
||||||
|
}
|
||||||
|
BS = Out;
|
||||||
|
BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
|
||||||
|
} else
|
||||||
|
// TODO: add parsing of other clauses.
|
||||||
|
break;
|
||||||
|
P.ConsumeToken();
|
||||||
|
// Skip ',' if any.
|
||||||
|
if (Tok.is(tok::comma))
|
||||||
|
P.ConsumeToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Parsing of declarative OpenMP directives.
|
/// \brief Parsing of declarative OpenMP directives.
|
||||||
///
|
///
|
||||||
/// threadprivate-directive:
|
/// threadprivate-directive:
|
||||||
|
@ -387,8 +418,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
|
||||||
//
|
//
|
||||||
|
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
// The last seen token is annot_pragma_openmp_end - need to check for
|
OMPDeclareSimdDeclAttr::BranchStateTy BS =
|
||||||
// extra tokens.
|
OMPDeclareSimdDeclAttr::BS_Undefined;
|
||||||
|
parseDeclareSimdClauses(*this, BS);
|
||||||
|
|
||||||
|
// Need to check for extra tokens.
|
||||||
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||||
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
|
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
|
||||||
<< getOpenMPDirectiveName(OMPD_declare_simd);
|
<< getOpenMPDirectiveName(OMPD_declare_simd);
|
||||||
|
@ -396,12 +430,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
|
||||||
ConsumeAnyToken();
|
ConsumeAnyToken();
|
||||||
}
|
}
|
||||||
// Skip the last annot_pragma_openmp_end.
|
// Skip the last annot_pragma_openmp_end.
|
||||||
ConsumeToken();
|
SourceLocation EndLoc = ConsumeToken();
|
||||||
|
|
||||||
DeclGroupPtrTy Ptr;
|
DeclGroupPtrTy Ptr;
|
||||||
if (Tok.is(tok::annot_pragma_openmp)) {
|
if (Tok.is(tok::annot_pragma_openmp))
|
||||||
Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
|
Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
|
||||||
} else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
|
else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
|
||||||
// Here we expect to see some function declaration.
|
// Here we expect to see some function declaration.
|
||||||
if (AS == AS_none) {
|
if (AS == AS_none) {
|
||||||
assert(TagType == DeclSpec::TST_unspecified);
|
assert(TagType == DeclSpec::TST_unspecified);
|
||||||
|
@ -419,7 +453,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
|
||||||
return DeclGroupPtrTy();
|
return DeclGroupPtrTy();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Actions.ActOnOpenMPDeclareSimdDirective(Ptr, Loc);
|
return Actions.ActOnOpenMPDeclareSimdDirective(Ptr, BS,
|
||||||
|
SourceRange(Loc, EndLoc));
|
||||||
}
|
}
|
||||||
case OMPD_unknown:
|
case OMPD_unknown:
|
||||||
Diag(Tok, diag::err_omp_unknown_directive);
|
Diag(Tok, diag::err_omp_unknown_directive);
|
||||||
|
|
|
@ -3183,12 +3183,13 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
||||||
|
|
||||||
Sema::DeclGroupPtrTy
|
Sema::DeclGroupPtrTy
|
||||||
Sema::ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
|
Sema::ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
|
||||||
SourceLocation StartLoc) {
|
OMPDeclareSimdDeclAttr::BranchStateTy BS,
|
||||||
|
SourceRange SR) {
|
||||||
if (!DG || DG.get().isNull())
|
if (!DG || DG.get().isNull())
|
||||||
return DeclGroupPtrTy();
|
return DeclGroupPtrTy();
|
||||||
|
|
||||||
if (!DG.get().isSingleDecl()) {
|
if (!DG.get().isSingleDecl()) {
|
||||||
Diag(StartLoc, diag::err_omp_single_decl_in_declare_simd);
|
Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
|
||||||
return DG;
|
return DG;
|
||||||
}
|
}
|
||||||
auto *ADecl = DG.get().getSingleDecl();
|
auto *ADecl = DG.get().getSingleDecl();
|
||||||
|
@ -3201,8 +3202,7 @@ Sema::ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
|
||||||
return DeclGroupPtrTy();
|
return DeclGroupPtrTy();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
|
auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(Context, BS, SR);
|
||||||
Context, SourceRange(StartLoc, StartLoc));
|
|
||||||
ADecl->addAttr(NewAttr);
|
ADecl->addAttr(NewAttr);
|
||||||
return ConvertDeclToDeclGroup(ADecl);
|
return ConvertDeclToDeclGroup(ADecl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,13 @@
|
||||||
|
|
||||||
#pragma omp declare simd
|
#pragma omp declare simd
|
||||||
#pragma omp declare simd
|
#pragma omp declare simd
|
||||||
|
#pragma omp declare simd inbranch
|
||||||
|
#pragma omp declare simd notinbranch
|
||||||
void add_1(float *d, float *s1, float *s2) __attribute__((cold));
|
void add_1(float *d, float *s1, float *s2) __attribute__((cold));
|
||||||
|
|
||||||
// CHECK: #pragma omp declare simd
|
// CHECK: #pragma omp declare simd notinbranch
|
||||||
|
// CHECK-NEXT: #pragma omp declare simd inbranch
|
||||||
|
// CHECK-NEXT: #pragma omp declare simd
|
||||||
// CHECK-NEXT: #pragma omp declare simd
|
// CHECK-NEXT: #pragma omp declare simd
|
||||||
// CHECK-NEXT: void add_1(float *d, float *s1, float *s2) __attribute__((cold))
|
// CHECK-NEXT: void add_1(float *d, float *s1, float *s2) __attribute__((cold))
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,13 @@
|
||||||
#define HEADER
|
#define HEADER
|
||||||
|
|
||||||
#pragma omp declare simd
|
#pragma omp declare simd
|
||||||
|
#pragma omp declare simd inbranch
|
||||||
|
#pragma omp declare simd notinbranch
|
||||||
void add_1(float *d) __attribute__((cold));
|
void add_1(float *d) __attribute__((cold));
|
||||||
|
|
||||||
// CHECK: #pragma omp declare simd
|
// CHECK: #pragma omp declare simd notinbranch
|
||||||
|
// CHECK-NEXT: #pragma omp declare simd inbranch
|
||||||
|
// CHECK-NEXT: #pragma omp declare simd
|
||||||
// CHECK-NEXT: void add_1(float *d) __attribute__((cold));
|
// CHECK-NEXT: void add_1(float *d) __attribute__((cold));
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,12 @@ void h(int *hp, int *hp2, int *hq, int *lin) {
|
||||||
h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
|
h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma omp declare simd inbranch inbranch
|
||||||
|
#pragma omp declare simd notinbranch notinbranch
|
||||||
|
#pragma omp declare simd inbranch inbranch notinbranch // expected-error {{unexpected 'notinbranch' clause, 'inbranch' is specified already}}
|
||||||
|
#pragma omp declare simd notinbranch notinbranch inbranch // expected-error {{unexpected 'inbranch' clause, 'notinbranch' is specified already}}
|
||||||
|
void foo();
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct St {
|
struct St {
|
||||||
// expected-error@+2 {{function declaration is expected after 'declare simd' directive}}
|
// expected-error@+2 {{function declaration is expected after 'declare simd' directive}}
|
||||||
|
|
|
@ -59,10 +59,10 @@ struct S {
|
||||||
// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <<invalid sloc>> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
|
// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <<invalid sloc>> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
|
||||||
|
|
||||||
#pragma omp declare simd
|
#pragma omp declare simd
|
||||||
#pragma omp declare simd
|
#pragma omp declare simd inbranch
|
||||||
void foo();
|
void foo();
|
||||||
|
|
||||||
// CHECK: `-FunctionDecl {{.+}} <line:63:1, col:10> col:6 foo 'void (void)'
|
// CHECK: `-FunctionDecl {{.+}} <line:63:1, col:10> col:6 foo 'void (void)'
|
||||||
// CHECK-NEXT: |-OMPDeclareSimdDeclAttr {{.+}} <line:62:9> Implicit
|
// CHECK-NEXT: |-OMPDeclareSimdDeclAttr {{.+}} <line:62:9, col:34> Implicit BS_Inbranch
|
||||||
// CHECK-NEXT: `-OMPDeclareSimdDeclAttr {{.+}} <line:61:9> Implicit
|
// CHECK-NEXT: `-OMPDeclareSimdDeclAttr {{.+}} <line:61:9, col:25> Implicit BS_Undefined
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue