r266041 - [OPENMP 4.0] Support for 'uniform' clause in 'declare simd' directive.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 11 22:28:36 PDT 2016
Author: abataev
Date: Tue Apr 12 00:28:34 2016
New Revision: 266041
URL: http://llvm.org/viewvc/llvm-project?rev=266041&view=rev
Log:
[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.
Modified:
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/OpenMPKinds.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/OpenMPClause.cpp
cfe/trunk/lib/Basic/OpenMPKinds.cpp
cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
cfe/trunk/lib/Parse/ParseOpenMP.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/OpenMP/declare_simd_ast_print.c
cfe/trunk/test/OpenMP/declare_simd_ast_print.cpp
cfe/trunk/test/OpenMP/declare_simd_messages.cpp
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Apr 12 00:28:34 2016
@@ -2517,6 +2517,7 @@ bool RecursiveASTVisitor<Derived>::Trave
break;
#include "clang/Basic/OpenMPKinds.def"
case OMPC_threadprivate:
+ case OMPC_uniform:
case OMPC_unknown:
break;
}
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Tue Apr 12 00:28:34 2016
@@ -2276,7 +2276,7 @@ def OMPDeclareSimdDecl : Attr {
EnumArgument<"BranchState", "BranchStateTy",
[ "", "inbranch", "notinbranch" ],
[ "BS_Undefined", "BS_Inbranch", "BS_Notinbranch" ]>,
- ExprArgument<"Simdlen">
+ ExprArgument<"Simdlen">, VariadicExprArgument<"Uniforms">
];
let AdditionalMembers = [{
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
@@ -2288,6 +2288,16 @@ def OMPDeclareSimdDecl : Attr {
E->printPretty(OS, nullptr, Policy);
OS << ") ";
}
+ if (uniforms_size() > 0) {
+ OS << "uniform";
+ StringRef Sep = "(";
+ for (auto *E : uniforms()) {
+ OS << Sep;
+ E->printPretty(OS, nullptr, Policy);
+ Sep = ", ";
+ }
+ OS << ") ";
+ }
}
}];
}
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Apr 12 00:28:34 2016
@@ -8179,7 +8179,9 @@ def err_omp_schedule_nonmonotonic_ordere
def err_omp_ordered_simd : Error<
"'ordered' clause with a parameter can not be specified in '#pragma omp %0' directive">;
def err_omp_variable_in_map_and_dsa : Error<
- "%0 variable cannot be in a map clause in '#pragma omp %1' directive">;
+ "%0 variable cannot be in a map clause in '#pragma omp %1' directive">;
+def err_omp_param_or_this_in_clause : Error<
+ "expected reference to one of the parameters of function %0%select{| or 'this'}1">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.h?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.h (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.h Tue Apr 12 00:28:34 2016
@@ -35,6 +35,7 @@ enum OpenMPClauseKind {
OMPC_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_threadprivate,
+ OMPC_uniform,
OMPC_unknown
};
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Apr 12 00:28:34 2016
@@ -2528,6 +2528,25 @@ public:
/// constructs.
/// \param RLoc Returned location of right paren.
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc);
+
+ /// Data used for parsing list of variables in OpenMP clauses.
+ struct OpenMPVarListDataTy {
+ Expr *TailExpr = nullptr;
+ SourceLocation ColonLoc;
+ CXXScopeSpec ReductionIdScopeSpec;
+ DeclarationNameInfo ReductionId;
+ OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
+ OpenMPLinearClauseKind LinKind = OMPC_LINEAR_val;
+ OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
+ OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
+ bool IsMapTypeImplicit = false;
+ SourceLocation DepLinMapLoc;
+ };
+
+ /// Parses clauses with list.
+ bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind,
+ SmallVectorImpl<Expr *> &Vars,
+ OpenMPVarListDataTy &Data);
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
bool AllowDestructorName,
bool AllowConstructorName,
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Apr 12 00:28:34 2016
@@ -8110,10 +8110,9 @@ public:
/// \brief Called on well-formed '\#pragma omp declare simd' after parsing of
/// the associated method/function.
- DeclGroupPtrTy
- ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
- OMPDeclareSimdDeclAttr::BranchStateTy BS,
- Expr *Simdlen, SourceRange SR);
+ DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(
+ DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS,
+ Expr *Simdlen, ArrayRef<Expr *> Uniforms, SourceRange SR);
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
Expr *Expr,
Modified: cfe/trunk/lib/AST/OpenMPClause.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OpenMPClause.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/lib/AST/OpenMPClause.cpp (original)
+++ cfe/trunk/lib/AST/OpenMPClause.cpp Tue Apr 12 00:28:34 2016
@@ -86,6 +86,7 @@ const OMPClauseWithPreInit *OMPClauseWit
case OMPC_hint:
case OMPC_defaultmap:
case OMPC_unknown:
+ case OMPC_uniform:
break;
}
@@ -146,6 +147,7 @@ const OMPClauseWithPostUpdate *OMPClause
case OMPC_hint:
case OMPC_defaultmap:
case OMPC_unknown:
+ case OMPC_uniform:
break;
}
Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Apr 12 00:28:34 2016
@@ -55,6 +55,7 @@ OpenMPClauseKind clang::getOpenMPClauseK
return llvm::StringSwitch<OpenMPClauseKind>(Str)
#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
#include "clang/Basic/OpenMPKinds.def"
+ .Case("uniform", OMPC_uniform)
.Default(OMPC_unknown);
}
@@ -67,6 +68,8 @@ const char *clang::getOpenMPClauseName(O
case OMPC_##Name: \
return #Name;
#include "clang/Basic/OpenMPKinds.def"
+ case OMPC_uniform:
+ return "uniform";
case OMPC_threadprivate:
return "threadprivate or thread local";
}
@@ -158,6 +161,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
case OMPC_nogroup:
case OMPC_num_tasks:
case OMPC_hint:
+ case OMPC_uniform:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -292,6 +296,7 @@ const char *clang::getOpenMPSimpleClause
case OMPC_nogroup:
case OMPC_num_tasks:
case OMPC_hint:
+ case OMPC_uniform:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Apr 12 00:28:34 2016
@@ -2975,6 +2975,7 @@ static void EmitOMPAtomicExpr(CodeGenFun
case OMPC_hint:
case OMPC_dist_schedule:
case OMPC_defaultmap:
+ case OMPC_uniform:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Apr 12 00:28:34 2016
@@ -332,10 +332,12 @@ Parser::ParseOpenMPDeclareReductionDirec
/// 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(Pars
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(Parse
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(Parse
// 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::ParseOpen
//
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(Ope
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,
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::ParseOpenMPVarListCla
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::ParseOpenMPVarListCla
} 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::ParseOpenMPVarListCla
/// 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::ParseOpenMPVarListCla
// 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::ParseOpenMPVarListCla
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::ParseOpenMPVarListCla
// 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);
}
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Apr 12 00:28:34 2016
@@ -3190,10 +3190,9 @@ StmtResult Sema::ActOnOpenMPExecutableDi
return Res;
}
-Sema::DeclGroupPtrTy
-Sema::ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,
- OMPDeclareSimdDeclAttr::BranchStateTy BS,
- Expr *Simdlen, SourceRange SR) {
+Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
+ DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
+ ArrayRef<Expr *> Uniforms, SourceRange SR) {
if (!DG || DG.get().isNull())
return DeclGroupPtrTy();
@@ -3205,9 +3204,9 @@ Sema::ActOnOpenMPDeclareSimdDirective(De
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();
+ auto *FD = dyn_cast<FunctionDecl>(ADecl);
+ if (!FD) {
+ Diag(ADecl->getLocation(), diag::err_omp_function_expected);
return DeclGroupPtrTy();
}
@@ -3215,13 +3214,30 @@ Sema::ActOnOpenMPDeclareSimdDirective(De
// The parameter of the simdlen clause must be a constant positive integer
// expression.
ExprResult SL;
- if (Simdlen) {
+ if (Simdlen)
SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
- if (SL.isInvalid())
- return DG;
+ // OpenMP [2.8.2, declare simd construct, Description]
+ // 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.
+ // 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.
+ for (auto *E : Uniforms) {
+ E = E->IgnoreParenImpCasts();
+ if (auto *DRE = dyn_cast<DeclRefExpr>(E))
+ if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
+ if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
+ FD->getParamDecl(PVD->getFunctionScopeIndex())
+ ->getCanonicalDecl() == PVD->getCanonicalDecl())
+ continue;
+ if (isa<CXXThisExpr>(E))
+ continue;
+ Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
+ << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
}
- auto *NewAttr =
- OMPDeclareSimdDeclAttr::CreateImplicit(Context, BS, SL.get(), SR);
+ auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
+ Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
+ Uniforms.size(), SR);
ADecl->addAttr(NewAttr);
return ConvertDeclToDeclGroup(ADecl);
}
@@ -6386,6 +6402,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
case OMPC_dist_schedule:
case OMPC_defaultmap:
case OMPC_unknown:
+ case OMPC_uniform:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -6671,6 +6688,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
case OMPC_dist_schedule:
case OMPC_defaultmap:
case OMPC_unknown:
+ case OMPC_uniform:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -6821,6 +6839,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi
case OMPC_num_tasks:
case OMPC_hint:
case OMPC_unknown:
+ case OMPC_uniform:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -7004,6 +7023,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM
case OMPC_dist_schedule:
case OMPC_defaultmap:
case OMPC_unknown:
+ case OMPC_uniform:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -7149,6 +7169,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus
case OMPC_dist_schedule:
case OMPC_defaultmap:
case OMPC_unknown:
+ case OMPC_uniform:
llvm_unreachable("Clause is not allowed.");
}
return Res;
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Apr 12 00:28:34 2016
@@ -240,15 +240,42 @@ static void instantiateOMPDeclareSimdDec
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const OMPDeclareSimdDeclAttr &Attr, Decl *New) {
ExprResult Simdlen;
- if (auto *E = Attr.getSimdlen()) {
+ if (auto *E = Attr.getSimdlen())
Simdlen = S.SubstExpr(E, TemplateArgs);
- if (Simdlen.isInvalid())
- return;
+ // Allow 'this' in clauses with varlists.
+ if (auto *FTD = dyn_cast<FunctionTemplateDecl>(New))
+ New = FTD->getTemplatedDecl();
+ auto *FD = cast<FunctionDecl>(New);
+ auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(FD->getDeclContext());
+ SmallVector<Expr *, 4> Uniforms;
+
+ auto &&Subst = [&](Expr *E) -> ExprResult {
+ if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
+ if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
+ Sema::ContextRAII SavedContext(S, FD);
+ LocalInstantiationScope Local(S);
+ if (FD->getNumParams() > PVD->getFunctionScopeIndex())
+ Local.InstantiatedLocal(
+ PVD, FD->getParamDecl(PVD->getFunctionScopeIndex()));
+ return S.SubstExpr(E, TemplateArgs);
+ }
+ Sema::CXXThisScopeRAII ThisScope(S, ThisContext, /*TypeQuals=*/0,
+ FD->isCXXInstanceMember());
+ return S.SubstExpr(E, TemplateArgs);
+ };
+
+ if (Attr.uniforms_size() > 0) {
+ for(auto *E : Attr.uniforms()) {
+ ExprResult Inst = Subst(E);
+ if (Inst.isInvalid())
+ continue;
+ Uniforms.push_back(Inst.get());
+ }
}
(void)S.ActOnOpenMPDeclareSimdDirective(S.ConvertDeclToDeclGroup(New),
Attr.getBranchState(), Simdlen.get(),
- Attr.getRange());
+ Uniforms, Attr.getRange());
}
void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
Modified: cfe/trunk/test/OpenMP/declare_simd_ast_print.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_simd_ast_print.c?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_simd_ast_print.c (original)
+++ cfe/trunk/test/OpenMP/declare_simd_ast_print.c Tue Apr 12 00:28:34 2016
@@ -8,12 +8,12 @@
#pragma omp declare simd
#pragma omp declare simd simdlen(32)
-#pragma omp declare simd inbranch
-#pragma omp declare simd notinbranch simdlen(2)
+#pragma omp declare simd inbranch, uniform(d)
+#pragma omp declare simd notinbranch simdlen(2), uniform(s1, s2)
void add_1(float *d, float *s1, float *s2) __attribute__((cold));
-// CHECK: #pragma omp declare simd notinbranch simdlen(2)
-// CHECK-NEXT: #pragma omp declare simd inbranch
+// CHECK: #pragma omp declare simd notinbranch simdlen(2) uniform(s1, s2)
+// CHECK-NEXT: #pragma omp declare simd inbranch uniform(d)
// CHECK-NEXT: #pragma omp declare simd simdlen(32)
// CHECK-NEXT: #pragma omp declare simd
// CHECK-NEXT: void add_1(float *d, float *s1, float *s2) __attribute__((cold))
Modified: cfe/trunk/test/OpenMP/declare_simd_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_simd_ast_print.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_simd_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/declare_simd_ast_print.cpp Tue Apr 12 00:28:34 2016
@@ -48,11 +48,11 @@ void h(int *hp, int *hp2, int *hq, int *
}
class VV {
- // CHECK: #pragma omp declare simd
+ // CHECK: #pragma omp declare simd uniform(this, a)
// CHECK-NEXT: int add(int a, int b) __attribute__((cold)) {
// CHECK-NEXT: return a + b;
// CHECK-NEXT: }
- #pragma omp declare simd
+ #pragma omp declare simd uniform(this, a)
int add(int a, int b) __attribute__((cold)) { return a + b; }
// CHECK: #pragma omp declare simd
@@ -109,10 +109,10 @@ public:
// CHECK-NEXT: }
#pragma omp declare simd
- #pragma omp declare simd
+ #pragma omp declare simd uniform(this, b)
int tadd(int b) { return x[b] + b; }
-// CHECK: #pragma omp declare simd
+// CHECK: #pragma omp declare simd uniform(this, b)
// CHECK-NEXT: #pragma omp declare simd
// CHECK-NEXT: int tadd(int b) {
// CHECK-NEXT: return this->x[b] + b;
Modified: cfe/trunk/test/OpenMP/declare_simd_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_simd_messages.cpp?rev=266041&r1=266040&r2=266041&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_simd_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/declare_simd_messages.cpp Tue Apr 12 00:28:34 2016
@@ -75,8 +75,10 @@ void h(int *hp, int *hp2, int *hq, int *
#pragma omp declare simd simdlen() simdlen)
void foo();
+// expected-error at +3 2 {{expected reference to one of the parameters of function 'foo'}}
+// expected-error at +2 {{invalid use of 'this' outside of a non-static member function}}
// expected-error at +1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
-#pragma omp declare simd simdlen(N)
+#pragma omp declare simd simdlen(N) uniform(this, var)
template<int N>
void foo() {}
@@ -85,12 +87,34 @@ void test() {
foo<-3>();
}
+// expected-error at +1 {{expected '(' after 'uniform'}}
+#pragma omp declare simd uniform
+// expected-note at +3 {{to match this '('}}
+// expected-error at +2 {{expected ')'}}
+// expected-error at +1 {{expected expression}}
+#pragma omp declare simd uniform(
+// expected-error at +1 {{expected expression}}
+#pragma omp declare simd uniform()
+// expected-note at +3 {{to match this '('}}
+// expected-error at +2 {{expected ')'}}
+// expected-error at +1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd uniform(this
+// expected-note at +3 {{to match this '('}}
+// expected-error at +2 {{expected ')'}}
+// expected-error at +1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd uniform(this,a
+// expected-error at +1 {{expected expression}}
+#pragma omp declare simd uniform(,a)
+void bar(int a);
+
template <class T>
struct St {
// expected-error at +2 {{function declaration is expected after 'declare simd' directive}}
#pragma init_seg(compiler)
#pragma omp declare simd
#pragma init_seg(compiler)
+// expected-error at +1 {{use of undeclared identifier 't'}}
+#pragma omp declare simd uniform(this, t)
void h(T *hp) {
// expected-error at +1 {{unexpected OpenMP directive '#pragma omp declare simd'}}
#pragma omp declare simd
More information about the cfe-commits
mailing list