]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Don't parallelize loops containing phis with addr_exprs
authorTom de Vries <tom@codesourcery.com>
Sun, 10 Jan 2016 12:44:57 +0000 (12:44 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Sun, 10 Jan 2016 12:44:57 +0000 (12:44 +0000)
2016-01-10  Tom de Vries  <tom@codesourcery.com>

PR tree-optimization/69062
* tree-parloops.c (loop_has_phi_with_address_arg): New function.
(parallelize_loops): Don't paralelize loop that has phi with address
arg.

* gcc.dg/autopar/pr69062.c: New test.

From-SVN: r232199

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/autopar/pr69062.c [new file with mode: 0644]
gcc/tree-parloops.c

index 21b47fea57924dc7ece6a3be398327a70c3bb01d..dde501779f9c4bdcb99f8b380468e1d00a93cd24 100644 (file)
@@ -1,3 +1,10 @@
+2016-01-10  Tom de Vries  <tom@codesourcery.com>
+
+       PR tree-optimization/69062
+       * tree-parloops.c (loop_has_phi_with_address_arg): New function.
+       (parallelize_loops): Don't paralelize loop that has phi with address
+       arg.
+
 2016-01-10  Tom de Vries  <tom@codesourcery.com>
 
        PR tree-optimization/69039
index 3005c9f43b5b7b842f093006e94ef935497fe466..f8c4ed5ccd758ac7b9e9c986624464b5405f63fa 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-10  Tom de Vries  <tom@codesourcery.com>
+
+       PR tree-optimization/69062
+       * gcc.dg/autopar/pr69062.c: New test.
+
 2016-01-10  Thomas Schwinge  <thomas@codesourcery.com>
 
        * gcc.dg/vect/slp-perm-1.c: Fix scan-tree-dump syntax.
diff --git a/gcc/testsuite/gcc.dg/autopar/pr69062.c b/gcc/testsuite/gcc.dg/autopar/pr69062.c
new file mode 100644 (file)
index 0000000..e039349
--- /dev/null
@@ -0,0 +1,89 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=2" } */
+
+#include <stdbool.h>
+
+typedef unsigned long HARD_REG_ELT_TYPE;
+typedef HARD_REG_ELT_TYPE HARD_REG_SET[1];
+struct target_ira
+{
+  HARD_REG_SET x_ira_prohibited_class_mode_regs[1][1];
+};
+extern struct target_ira *this_target_ira;
+static inline bool
+ira_object_conflict_iter_cond ()
+{
+}
+
+static inline bool
+check_hard_reg_p (int num_objects, int hard_regno,
+                 HARD_REG_SET * conflict_regs, HARD_REG_SET profitable_regs)
+{
+  int j, nwords, nregs;
+  if ((! !
+       (((this_target_ira->
+         x_ira_prohibited_class_mode_regs)[0][0])[(hard_regno) /
+                                                  ((unsigned) (8 * 8))] &
+       (((HARD_REG_ELT_TYPE) (1)) <<
+        ((hard_regno) % ((unsigned) (8 * 8)))))))
+    return false;
+  nwords = num_objects;
+  for (j = 0; j < nregs; j++)
+    {
+      int k;
+      int set_to_test_start = 0, set_to_test_end = nwords;
+      if (nregs == nwords)
+       {
+         if (0)
+           set_to_test_start = nwords - j - 1;
+         else
+           set_to_test_start = j;
+       }
+      for (k = set_to_test_start; k < set_to_test_end; k++)
+       if ((! !
+            ((conflict_regs[k])[(hard_regno + j) / ((unsigned) (8 * 8))] &
+             (((HARD_REG_ELT_TYPE) (1)) <<
+              ((hard_regno + j) % ((unsigned) (8 * 8)))))))
+         break;
+      if (k != set_to_test_end)
+       break;
+    }
+  return j == nregs;
+}
+
+void
+improve_allocation (void)
+{
+  int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
+  int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
+  int costs[81];
+  HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
+  int a;
+  for (;;)
+    {
+      nwords = a;
+      for (word = 0; word < nwords; word++)
+       {
+         for (; ira_object_conflict_iter_cond ();)
+           {
+             for (r = conflict_hregno;
+                  r < conflict_hregno + conflict_nregs; r++)
+               if (check_hard_reg_p
+                   (a, r, conflicting_regs, profitable_hard_regs))
+                 costs[r] += spill_cost;
+           }
+         if (check_hard_reg_p
+             (a, hregno, conflicting_regs, profitable_hard_regs)
+             && min_cost > costs[hregno])
+           {
+             best = hregno;
+           }
+         for (; ira_object_conflict_iter_cond ();)
+           {
+             if (best + nregs <= conflict_hregno
+                 || conflict_hregno + conflict_nregs <= best)
+               continue;
+           }
+       }
+    }
+}
index 394aba8d121f68b6afdd79bb1ba85bb412e01db9..5bd9c06f31542fa5e5a928a89754f7fad9997eea 100644 (file)
@@ -2640,6 +2640,37 @@ try_create_reduction_list (loop_p loop,
   return true;
 }
 
+/* Return true if LOOP contains phis with ADDR_EXPR in args.  */
+
+static bool
+loop_has_phi_with_address_arg (struct loop *loop)
+{
+  basic_block *bbs = get_loop_body (loop);
+  bool res = false;
+
+  unsigned i, j;
+  gphi_iterator gsi;
+  for (i = 0; i < loop->num_nodes; i++)
+    for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
+      {
+       gphi *phi = gsi.phi ();
+       for (j = 0; j < gimple_phi_num_args (phi); j++)
+         {
+           tree arg = gimple_phi_arg_def (phi, j);
+           if (TREE_CODE (arg) == ADDR_EXPR)
+             {
+               /* This should be handled by eliminate_local_variables, but that
+                  function currently ignores phis.  */
+               res = true;
+               goto end;
+             }
+         }
+      }
+ end:
+  free (bbs);
+  return res;
+}
+
 /* Detect parallel loops and generate parallel code using libgomp
    primitives.  Returns true if some loop was parallelized, false
    otherwise.  */
@@ -2734,6 +2765,9 @@ parallelize_loops (void)
       if (!try_create_reduction_list (loop, &reduction_list))
        continue;
 
+      if (loop_has_phi_with_address_arg (loop))
+       continue;
+
       if (!flag_loop_parallelize_all
          && !loop_parallel_p (loop, &parloop_obstack))
        continue;