summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-10 12:44:57 +0000
committervries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-10 12:44:57 +0000
commita006c0bb7e05788e78f7968108e7a218d08a5ca3 (patch)
tree24f64fe4361e4575dd44f0faa922bd2078f8eb1c
parent880ed4be84bfc9cec83d7c9718fd4f87a9ca8f39 (diff)
downloadgcc-a006c0bb7e05788e78f7968108e7a218d08a5ca3.tar.gz
Don't parallelize loops containing phis with addr_exprs
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232199 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/autopar/pr69062.c89
-rw-r--r--gcc/tree-parloops.c34
4 files changed, 135 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 21b47fea579..dde501779f9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
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
* tree-parloops.c (try_create_reduction_list): Only allow single exit
phi for reduction.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3005c9f43b5..f8c4ed5ccd7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..e039349467f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/pr69062.c
@@ -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;
+ }
+ }
+ }
+}
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 394aba8d121..5bd9c06f315 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -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;