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
This commit is contained in:
Richard Biener 2014-01-15 15:13:08 +00:00 committed by Richard Biener
parent 17c77f44b1
commit 6b916b36f1
4 changed files with 81 additions and 1 deletions

View File

@ -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>

View File

@ -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

View File

@ -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)]);
}

View File

@ -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 ())
{