r373502 - [OPENMP50]Add parsing/sema analysis for declare variant score.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 2 11:19:02 PDT 2019
Author: abataev
Date: Wed Oct 2 11:19:02 2019
New Revision: 373502
URL: http://llvm.org/viewvc/llvm-project?rev=373502&view=rev
Log:
[OPENMP50]Add parsing/sema analysis for declare variant score.
Context selectors may include optional score clause in format
`score(<expr>):`, where `<expr>` must be a constant integer expression.
Added parsing/sema analysis only.
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseOpenMP.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/OpenMP/declare_variant_ast_print.c
cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp
cfe/trunk/test/OpenMP/declare_variant_messages.c
cfe/trunk/test/OpenMP/declare_variant_messages.cpp
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Oct 2 11:19:02 2019
@@ -3290,12 +3290,19 @@ def OMPDeclareVariant : InheritableAttr
let Documentation = [OMPDeclareVariantDocs];
let Args = [
ExprArgument<"VariantFuncRef">,
+ ExprArgument<"Score">,
EnumArgument<"CtxSelectorSet", "CtxSelectorSetType",
[ "", "implementation"
],
[
"CtxSetUnknown", "CtxSetImplementation"
]>,
+ EnumArgument<"CtxScore", "ScoreType",
+ [ "", "score"
+ ],
+ [
+ "ScoreUnknown", "ScoreSpecified"
+ ]>,
EnumArgument<"CtxSelector", "CtxSelectorType",
[ "", "vendor"
],
@@ -3305,6 +3312,13 @@ def OMPDeclareVariant : InheritableAttr
StringArgument<"ImplVendor", 1>
];
let AdditionalMembers = [{
+ void printScore(raw_ostream & OS, const PrintingPolicy &Policy) const {
+ if (const Expr *E = getScore()) {
+ OS << "score(";
+ E->printPretty(OS, nullptr, Policy);
+ OS << "):";
+ }
+ }
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
const {
assert(getCtxSelectorSet() != CtxSetUnknown &&
@@ -3322,6 +3336,7 @@ def OMPDeclareVariant : InheritableAttr
switch (getCtxSelector()) {
case CtxVendor:
OS << "vendor(";
+ printScore(OS, Policy);
OS << getImplVendor();
OS << ")";
break;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Oct 2 11:19:02 2019
@@ -9109,11 +9109,14 @@ public:
OMPDeclareVariantAttr::CtxSelectorType Ctx =
OMPDeclareVariantAttr::CtxUnknown;
StringRef ImplVendor;
+ ExprResult CtxScore;
explicit OpenMPDeclareVariantCtsSelectorData() = default;
explicit OpenMPDeclareVariantCtsSelectorData(
OMPDeclareVariantAttr::CtxSelectorSetType CtxSet,
- OMPDeclareVariantAttr::CtxSelectorType Ctx, StringRef ImplVendor)
- : CtxSet(CtxSet), Ctx(Ctx), ImplVendor(ImplVendor) {}
+ OMPDeclareVariantAttr::CtxSelectorType Ctx, StringRef ImplVendor,
+ ExprResult CtxScore)
+ : CtxSet(CtxSet), Ctx(Ctx), ImplVendor(ImplVendor), CtxScore(CtxScore) {
+ }
};
/// Checks if the variant/multiversion functions are compatible.
Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Wed Oct 2 11:19:02 2019
@@ -786,6 +786,31 @@ Parser::ParseOMPDeclareSimdClauses(Parse
LinModifiers, Steps, SourceRange(Loc, EndLoc));
}
+/// Parse optional 'score' '(' <expr> ')' ':'.
+static ExprResult parseContextScore(Parser &P) {
+ ExprResult ScoreExpr;
+ SmallString<16> Buffer;
+ StringRef SelectorName =
+ P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
+ OMPDeclareVariantAttr::ScoreType ScoreKind =
+ OMPDeclareVariantAttr::ScoreUnknown;
+ (void)OMPDeclareVariantAttr::ConvertStrToScoreType(SelectorName, ScoreKind);
+ if (ScoreKind == OMPDeclareVariantAttr::ScoreUnknown)
+ return ScoreExpr;
+ assert(ScoreKind == OMPDeclareVariantAttr::ScoreSpecified &&
+ "Expected \"score\" clause.");
+ (void)P.ConsumeToken();
+ SourceLocation RLoc;
+ ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
+ // Parse ':'
+ if (P.getCurToken().is(tok::colon))
+ (void)P.ConsumeAnyToken();
+ else
+ P.Diag(P.getCurToken(), diag::warn_pragma_expected_colon)
+ << "context selector score clause";
+ return ScoreExpr;
+}
+
/// Parse context selector for 'implementation' selector set:
/// 'vendor' '(' <vendor> ')'
static void
@@ -815,6 +840,7 @@ parseImplementationSelector(Parser &P,
BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
(void)T.expectAndConsume(diag::err_expected_lparen_after,
CtxSelectorName.data());
+ Data.CtxScore = parseContextScore(P);
// Parse <vendor>.
StringRef VendorName;
if (Tok.is(tok::identifier)) {
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Oct 2 11:19:02 2019
@@ -5112,8 +5112,23 @@ void Sema::ActOnOpenMPDeclareVariantDire
if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown ||
Data.Ctx == OMPDeclareVariantAttr::CtxUnknown)
return;
+ Expr *Score = nullptr;
+ OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown;
+ if (Data.CtxScore.isUsable()) {
+ ST = OMPDeclareVariantAttr::ScoreSpecified;
+ Score = Data.CtxScore.get();
+ if (!Score->isTypeDependent() && !Score->isValueDependent() &&
+ !Score->isInstantiationDependent() &&
+ !Score->containsUnexpandedParameterPack()) {
+ llvm::APSInt Result;
+ ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result);
+ if (ICE.isInvalid())
+ return;
+ }
+ }
auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
- Context, VariantRef, Data.CtxSet, Data.Ctx, Data.ImplVendor, SR);
+ Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, Data.ImplVendor,
+ SR);
FD->addAttr(NewAttr);
}
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Oct 2 11:19:02 2019
@@ -388,6 +388,10 @@ static void instantiateOMPDeclareVariant
if (Expr *E = Attr.getVariantFuncRef())
VariantFuncRef = Subst(E);
+ ExprResult Score;
+ if (Expr *E = Attr.getScore())
+ Score = Subst(E);
+
// Check function/variant ref.
Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
S.checkOpenMPDeclareVariantFunction(
@@ -395,8 +399,9 @@ static void instantiateOMPDeclareVariant
if (!DeclVarData)
return;
// Instantiate the attribute.
- Sema::OpenMPDeclareVariantCtsSelectorData Data(
- Attr.getCtxSelectorSet(), Attr.getCtxSelector(), Attr.getImplVendor());
+ Sema::OpenMPDeclareVariantCtsSelectorData Data(Attr.getCtxSelectorSet(),
+ Attr.getCtxSelector(),
+ Attr.getImplVendor(), Score);
S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first,
DeclVarData.getValue().second,
Attr.getRange(), Data);
Modified: cfe/trunk/test/OpenMP/declare_variant_ast_print.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_ast_print.c?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_variant_ast_print.c (original)
+++ cfe/trunk/test/OpenMP/declare_variant_ast_print.c Wed Oct 2 11:19:02 2019
@@ -10,9 +10,11 @@ int foo(void);
#pragma omp declare variant(foo) match(xxx={vvv})
#pragma omp declare variant(foo) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
#pragma omp declare variant(foo) match(implementation={vendor(unknown)})
+#pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)})
int bar(void);
// CHECK: int foo();
+// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):ibm)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(unknown)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(ibm)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})
Modified: cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp Wed Oct 2 11:19:02 2019
@@ -17,7 +17,8 @@ T foofoo() { return T(); }
// CHECK-NEXT: return int();
// CHECK-NEXT: }
-// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
+// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(5):ibm)})
+// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(ibm)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)})
// CHECK-NEXT: int bar();
@@ -25,12 +26,14 @@ T foofoo() { return T(); }
#pragma omp declare variant(foofoo <int>) match(xxx = {vvv})
#pragma omp declare variant(foofoo <int>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
#pragma omp declare variant(foofoo <int>) match(implementation={vendor(unknown)})
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(5): ibm)})
int bar();
-// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(unknown)})
+// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5):ibm)})
+// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(unknown)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(ibm)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(llvm)})
-// CHECK-NEXT: template <typename T> T barbar();
+// CHECK-NEXT: template <typename T, int C> T barbar();
#pragma omp declare variant(foofoo <T>) match(xxx = {})
#pragma omp declare variant(foofoo <T>) match(xxx = {vvv})
#pragma omp declare variant(foofoo <T>) match(user = {score(<expr>) : condition(<expr>)})
@@ -39,19 +42,21 @@ int bar();
#pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)})
#pragma omp declare variant(foofoo <T>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
#pragma omp declare variant(foofoo <T>) match(implementation={vendor(unknown)})
-template <typename T>
+#pragma omp declare variant(foofoo <T>) match(implementation={vendor(score(C+5): ibm)})
+template <typename T, int C>
T barbar();
-// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
+// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 5):ibm)})
+// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(ibm)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)})
-// CHECK-NEXT: template<> int barbar<int>();
+// CHECK-NEXT: template<> int barbar<int, 3>();
// CHECK-NEXT: int baz() {
-// CHECK-NEXT: return barbar<int>();
+// CHECK-NEXT: return barbar<int, 3>();
// CHECK-NEXT: }
int baz() {
- return barbar<int>();
+ return barbar<int, 3>();
}
// CHECK: template <class C> void h_ref(C *hp, C *hp2, C *hq, C *lin) {
Modified: cfe/trunk/test/OpenMP/declare_variant_messages.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_messages.c?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_variant_messages.c (original)
+++ cfe/trunk/test/OpenMP/declare_variant_messages.c Wed Oct 2 11:19:02 2019
@@ -30,6 +30,11 @@ int foo(void);
#pragma omp declare variant(foo) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp declare variant(foo) match(implementation={vendor(}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp declare variant(foo) match(implementation={vendor()}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}}
+#pragma omp declare variant(foo) match(implementation={vendor(score ibm)}) // expected-error {{expected '(' after 'score'}} expected-warning {{missing ':' after context selector score clause - ignoring}}
+#pragma omp declare variant(foo) match(implementation={vendor(score( ibm)}) // expected-error {{expected ')'}} expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note {{to match this '('}}
+#pragma omp declare variant(foo) match(implementation={vendor(score(2 ibm)}) // expected-error 2 {{expected ')'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note 2 {{to match this '('}}
+#pragma omp declare variant(foo) match(implementation={vendor(score(foo()) ibm)}) // expected-warning {{missing ':' after context selector score clause - ignoring}} expected-error {{expression is not an integer constant expression}}
+#pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)})
int bar(void);
// expected-error at +2 {{'#pragma omp declare variant' can only be applied to functions}}
Modified: cfe/trunk/test/OpenMP/declare_variant_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_messages.cpp?rev=373502&r1=373501&r2=373502&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_variant_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/declare_variant_messages.cpp Wed Oct 2 11:19:02 2019
@@ -8,7 +8,7 @@
int foo();
template <typename T>
-T foofoo();
+T foofoo(); // expected-note 2 {{declared here}}
#pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}}
#pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -33,6 +33,11 @@ T foofoo();
#pragma omp declare variant(foofoo <int>) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp declare variant(foofoo <int>) match(implementation={vendor(}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp declare variant(foofoo <int>) match(implementation={vendor()}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score ibm)}) // expected-error {{expected '(' after 'score'}} expected-warning {{missing ':' after context selector score clause - ignoring}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score( ibm)}) // expected-error {{expected ')'}} expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note {{to match this '('}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(2 ibm)}) // expected-error 2 {{expected ')'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note 2 {{to match this '('}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(foofoo <int>()) ibm)}) // expected-warning {{missing ':' after context selector score clause - ignoring}} expected-error {{expression is not an integral constant expression}} expected-note {{non-constexpr function 'foofoo<int>' cannot be used in a constant expression}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(5): ibm)})
int bar();
#pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}}
@@ -57,7 +62,12 @@ int bar();
#pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)})
#pragma omp declare variant(foofoo <T>) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}}
#pragma omp declare variant(foofoo <T>) match(xxx = {vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-template <typename T>
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score ibm)}) // expected-error {{expected '(' after 'score'}} expected-warning {{missing ':' after context selector score clause - ignoring}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score( ibm)}) // expected-error {{expected ')'}} expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note {{to match this '('}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(C ibm)}) // expected-error 2 {{expected ')'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note 2 {{to match this '('}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(foofoo <int>()) ibm)}) // expected-warning {{missing ':' after context selector score clause - ignoring}} expected-error {{expression is not an integral constant expression}} expected-note {{non-constexpr function 'foofoo<int>' cannot be used in a constant expression}}
+#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(C+5): ibm)})
+template <typename T, int C>
T barbar();
// expected-error at +2 {{'#pragma omp declare variant' can only be applied to functions}}
More information about the cfe-commits
mailing list