gimplify.c (gimplify_call_expr): Don't call omp_resolve_declare_variant after gimplif...
authorJakub Jelinek <jakub@redhat.com>
Fri, 15 Nov 2019 08:32:36 +0000 (09:32 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 15 Nov 2019 08:32:36 +0000 (09:32 +0100)
* 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

gcc/ChangeLog
gcc/gimplify.c
gcc/omp-general.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/gomp/declare-variant-13.c [new file with mode: 0644]

index e5d9e38196cab5127587d0887c7b31bbb72d9e51..6810dfb194bcc408e856edef5cfb66bc3eead846 100644 (file)
@@ -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.
index 87a6405451416bc6998ca52a76394e568d1ef75d..0bbd475b3dd1b37f3333b8268661d487c60d64fb 100644 (file)
@@ -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)
index a8efc106779592f82b2d3a1d364ec5173fbe4dff..c9c4f3aba97299b41ec023f7abc4d9337910fc71 100644 (file)
@@ -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]));
 
index 0d96f0a3b27c9f8a7e4ac1b7f6a766ba996763ba..6d7a132f08f185e48c42ef86788b18786a763541 100644 (file)
@@ -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 (file)
index 0000000..68e6a89
--- /dev/null
@@ -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" } } */
+}