aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-11-15 09:32:36 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2019-11-15 09:32:36 +0100
commit0227ffa98e122d5716d508c435cb8323cd93bfef (patch)
tree1061bae3610fd33b8be8ea3ae45c260c201f3812 /gcc
parent1c9676e2076b403eb1f6b22351bf0c58cc367ee3 (diff)
downloadgcc-0227ffa98e122d5716d508c435cb8323cd93bfef.zip
gcc-0227ffa98e122d5716d508c435cb8323cd93bfef.tar.gz
gcc-0227ffa98e122d5716d508c435cb8323cd93bfef.tar.bz2
gimplify.c (gimplify_call_expr): Don't call omp_resolve_declare_variant after gimplification.
* gimplify.c (gimplify_call_expr): Don't call omp_resolve_declare_variant after gimplification. * omp-general.c (omp_context_selector_matches): For isa that might match in some other function, defer if in declare simd function. (omp_context_compute_score): Don't look for " score" in construct trait set. Set *score to -1 if it can't ever match. (omp_resolve_declare_variant): If any variants need to be deferred, don't punt immediately, but compute scores of all variants and if ther eis a score winner that doesn't need to be deferred, return that. * c-c++-common/gomp/declare-variant-13.c: New test. From-SVN: r278280
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/gimplify.c5
-rw-r--r--gcc/omp-general.c116
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/c-c++-common/gomp/declare-variant-13.c24
5 files changed, 152 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e5d9e38..6810dfb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2019-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (gimplify_call_expr): Don't call
+ omp_resolve_declare_variant after gimplification.
+ * omp-general.c (omp_context_selector_matches): For isa that might
+ match in some other function, defer if in declare simd function.
+ (omp_context_compute_score): Don't look for " score" in construct
+ trait set. Set *score to -1 if it can't ever match.
+ (omp_resolve_declare_variant): If any variants need to be deferred,
+ don't punt immediately, but compute scores of all variants and if
+ ther eis a score winner that doesn't need to be deferred, return that.
+
2019-11-15 Luo Xiong Hu <luoxhu@linux.ibm.com>
* ipa-comdats.c: Fix comments typo.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 87a6405..0bbd475 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3391,7 +3391,10 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
/* Remember the original function pointer type. */
fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
- if (flag_openmp && fndecl)
+ if (flag_openmp
+ && fndecl
+ && cfun
+ && (cfun->curr_properties & PROP_gimple_any) == 0)
{
tree variant = omp_resolve_declare_variant (fndecl);
if (variant != fndecl)
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index a8efc10..c9c4f3a 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -939,6 +939,21 @@ omp_context_selector_matches (tree ctx)
isa);
if (r == 0 || (r == -1 && symtab->state != PARSING))
{
+ /* If isa is valid on the target, but not in the
+ current function and current function has
+ #pragma omp declare simd on it, some simd clones
+ might have the isa added later on. */
+ if (r == -1
+ && targetm.simd_clone.compute_vecsize_and_simdlen)
+ {
+ tree attrs
+ = DECL_ATTRIBUTES (current_function_decl);
+ if (lookup_attribute ("omp declare simd", attrs))
+ {
+ ret = -1;
+ continue;
+ }
+ }
/* If we are or might be in a target region or
declare target function, need to take into account
also offloading values. */
@@ -1355,12 +1370,13 @@ omp_context_compute_score (tree ctx, widest_int *score, bool declare_simd)
bool ret = false;
*score = 1;
for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
- for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
- if (tree t3 = TREE_VALUE (t2))
- if (TREE_PURPOSE (t3)
- && strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3)), " score") == 0
- && TREE_CODE (TREE_VALUE (t3)) == INTEGER_CST)
- *score += wi::to_widest (TREE_VALUE (t3));
+ if (TREE_VALUE (t1) != construct)
+ for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
+ if (tree t3 = TREE_VALUE (t2))
+ if (TREE_PURPOSE (t3)
+ && strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3)), " score") == 0
+ && TREE_CODE (TREE_VALUE (t3)) == INTEGER_CST)
+ *score += wi::to_widest (TREE_VALUE (t3));
if (construct || has_kind || has_arch || has_isa)
{
int scores[12];
@@ -1378,7 +1394,7 @@ omp_context_compute_score (tree ctx, widest_int *score, bool declare_simd)
{
if (scores[b + n] < 0)
{
- *score = 0;
+ *score = -1;
return ret;
}
*score += wi::shifted_mask <widest_int> (scores[b + n], 1, false);
@@ -1407,6 +1423,8 @@ omp_resolve_declare_variant (tree base)
{
tree variant1 = NULL_TREE, variant2 = NULL_TREE;
auto_vec <tree, 16> variants;
+ auto_vec <bool, 16> defer;
+ bool any_deferred = false;
for (tree attr = DECL_ATTRIBUTES (base); attr; attr = TREE_CHAIN (attr))
{
attr = lookup_attribute ("omp declare variant base", attr);
@@ -1421,13 +1439,95 @@ omp_resolve_declare_variant (tree base)
break;
case -1:
/* Needs to be deferred. */
- return base;
+ any_deferred = true;
+ variants.safe_push (attr);
+ defer.safe_push (true);
+ break;
default:
variants.safe_push (attr);
+ defer.safe_push (false);
+ break;
}
}
if (variants.length () == 0)
return base;
+
+ if (any_deferred)
+ {
+ widest_int max_score1 = 0;
+ widest_int max_score2 = 0;
+ bool first = true;
+ unsigned int i;
+ tree attr1, attr2;
+ FOR_EACH_VEC_ELT (variants, i, attr1)
+ {
+ widest_int score1;
+ widest_int score2;
+ bool need_two;
+ tree ctx = TREE_VALUE (TREE_VALUE (attr1));
+ need_two = omp_context_compute_score (ctx, &score1, false);
+ if (need_two)
+ omp_context_compute_score (ctx, &score2, true);
+ else
+ score2 = score1;
+ if (first)
+ {
+ first = false;
+ max_score1 = score1;
+ max_score2 = score2;
+ if (!defer[i])
+ {
+ variant1 = attr1;
+ variant2 = attr1;
+ }
+ }
+ else
+ {
+ if (max_score1 == score1)
+ variant1 = NULL_TREE;
+ else if (score1 > max_score1)
+ {
+ max_score1 = score1;
+ variant1 = defer[i] ? NULL_TREE : attr1;
+ }
+ if (max_score2 == score2)
+ variant2 = NULL_TREE;
+ else if (score2 > max_score2)
+ {
+ max_score2 = score2;
+ variant2 = defer[i] ? NULL_TREE : attr1;
+ }
+ }
+ }
+
+ /* If there is a clear winner variant with the score which is not
+ deferred, verify it is not a strict subset of any other context
+ selector and if it is not, it is the best alternative no matter
+ whether the others do or don't match. */
+ if (variant1 && variant1 == variant2)
+ {
+ tree ctx1 = TREE_VALUE (TREE_VALUE (variant1));
+ FOR_EACH_VEC_ELT (variants, i, attr2)
+ {
+ if (attr2 == variant1)
+ continue;
+ tree ctx2 = TREE_VALUE (TREE_VALUE (attr2));
+ int r = omp_context_selector_compare (ctx1, ctx2);
+ if (r == -1)
+ {
+ /* The winner is a strict subset of ctx2, can't
+ decide now. */
+ variant1 = NULL_TREE;
+ break;
+ }
+ }
+ if (variant1)
+ return TREE_PURPOSE (TREE_VALUE (variant1));
+ }
+
+ return base;
+ }
+
if (variants.length () == 1)
return TREE_PURPOSE (TREE_VALUE (variants[0]));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0d96f0a..6d7a132 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/declare-variant-13.c: New test.
+
2019-11-15 Jan Hubicka <hubicka@ucw.cz>
PR testsuite/92520
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-13.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-13.c
new file mode 100644
index 0000000..68e6a89
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-13.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target vect_simd_clones } } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+/* { dg-additional-options "-mno-sse3" { target { i?86-*-* x86_64-*-* } } } */
+
+int f01 (int);
+int f02 (int);
+int f03 (int);
+int f04 (int);
+#pragma omp declare variant (f01) match (device={isa("avx512f")}) /* 4 or 8 */
+#pragma omp declare variant (f02) match (implementation={vendor(score(3):gnu)},device={kind(cpu)}) /* (1 or 2) + 3 */
+#pragma omp declare variant (f03) match (user={condition(score(9):1)})
+#pragma omp declare variant (f04) match (implementation={vendor(score(6):gnu)},device={kind(host)}) /* (1 or 2) + 6 */
+int f05 (int);
+
+#pragma omp declare simd
+int
+test1 (int x)
+{
+ /* 0 or 1 (the latter if in a declare simd clone) constructs in OpenMP context,
+ isa has score 2^2 or 2^3. We can't decide on whether avx512f will match or
+ not, that also depends on whether it is a declare simd clone or not and which
+ one, but the f03 variant has a higher score anyway. */
+ return f05 (x); /* { dg-final { scan-tree-dump-times "f03 \\\(x" 1 "gimple" } } */
+}