diff options
author | Richard Biener <rguenther@suse.de> | 2014-01-15 15:13:08 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-01-15 15:13:08 +0000 |
commit | 6b916b36f11df5c86b437f7bf6e38aab437006c5 (patch) | |
tree | 2ce49f0eb56f8261c3d8f328a8bea6e3fe3e6e99 /gcc | |
parent | 17c77f44b188b16f24b43bfdde90a4a069d65d95 (diff) | |
download | gcc-6b916b36f11df5c86b437f7bf6e38aab437006c5.zip gcc-6b916b36f11df5c86b437f7bf6e38aab437006c5.tar.gz gcc-6b916b36f11df5c86b437f7bf6e38aab437006c5.tar.bz2 |
re PR tree-optimization/59822 (ice in compute_live_loop_exits with -O3)
2014-01-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/59822
* tree-vect-stmts.c (hoist_defs_of_uses): New function.
(vectorizable_load): Use it to hoist defs of uses of invariant
loads out of the loop.
* g++.dg/torture/pr59822.C: New testcase.
From-SVN: r206630
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr59822.C | 14 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 56 |
4 files changed, 81 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f993e48..7ddff75 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-01-15 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59822 + * tree-vect-stmts.c (hoist_defs_of_uses): New function. + (vectorizable_load): Use it to hoist defs of uses of invariant + loads out of the loop. + 2014-01-15 Matthew Gretton-Dann <matthew.gretton-dann@linaro.org> Kugan Vivekanandarajah <kuganv@linaro.org> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dde7878..1df5c3a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-01-15 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59822 + * g++.dg/torture/pr59822.C: New testcase. + 2014-01-15 Kirill Yukhin <kirill.yukhin@intel.com> PR target/59808 diff --git a/gcc/testsuite/g++.dg/torture/pr59822.C b/gcc/testsuite/g++.dg/torture/pr59822.C new file mode 100644 index 0000000..7357b6d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr59822.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +typedef struct rtvec_def *rtvec; +enum machine_mode { VOIDmode }; +struct rtvec_def { void *elem[1]; }; +extern void *const_tiny_rtx[2]; +void +ix86_build_const_vector (enum machine_mode mode, bool vect, + void *value, rtvec v, int n_elt) +{ + int i; + for (i = 1; i < n_elt; ++i) + ((v)->elem[i]) = vect ? value : (const_tiny_rtx[(int) (mode)]); +} diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index acdaa2d..820df7e 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -5480,6 +5480,59 @@ permute_vec_elements (tree x, tree y, tree mask_vec, gimple stmt, return data_ref; } +/* Hoist the definitions of all SSA uses on STMT out of the loop LOOP, + inserting them on the loops preheader edge. Returns true if we + were successful in doing so (and thus STMT can be moved then), + otherwise returns false. */ + +static bool +hoist_defs_of_uses (gimple stmt, struct loop *loop) +{ + ssa_op_iter i; + tree op; + bool any = false; + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE) + { + gimple def_stmt = SSA_NAME_DEF_STMT (op); + if (!gimple_nop_p (def_stmt) + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))) + { + /* Make sure we don't need to recurse. While we could do + so in simple cases when there are more complex use webs + we don't have an easy way to preserve stmt order to fulfil + dependencies within them. */ + tree op2; + ssa_op_iter i2; + FOR_EACH_SSA_TREE_OPERAND (op2, def_stmt, i2, SSA_OP_USE) + { + gimple def_stmt2 = SSA_NAME_DEF_STMT (op2); + if (!gimple_nop_p (def_stmt2) + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt2))) + return false; + } + any = true; + } + } + + if (!any) + return true; + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE) + { + gimple def_stmt = SSA_NAME_DEF_STMT (op); + if (!gimple_nop_p (def_stmt) + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))) + { + gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt); + gsi_remove (&gsi, false); + gsi_insert_on_edge_immediate (loop_preheader_edge (loop), def_stmt); + } + } + + return true; +} + /* vectorizable_load. Check if STMT reads a non scalar data-ref (array/pointer/structure) that @@ -6384,7 +6437,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, /* If we have versioned for aliasing then we are sure this is a loop invariant load and thus we can insert it on the preheader edge. */ - if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)) + if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo) + && hoist_defs_of_uses (stmt, loop)) { if (dump_enabled_p ()) { |