From 3907c6cf931af4e874cb217addd29b24063b6367 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Sun, 10 Jan 2016 12:44:57 +0000 Subject: [PATCH] Don't parallelize loops containing phis with addr_exprs 2016-01-10 Tom de Vries 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 | 7 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/autopar/pr69062.c | 89 ++++++++++++++++++++++++++ gcc/tree-parloops.c | 34 ++++++++++ 4 files changed, 135 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/autopar/pr69062.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21b47fea579..dde501779f9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-01-10 Tom de Vries + + 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 PR tree-optimization/69039 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 + + PR tree-optimization/69062 + * gcc.dg/autopar/pr69062.c: New test. + 2016-01-10 Thomas Schwinge * 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 + +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;