Commit 6b916b36 by Richard Biener Committed by Richard Biener

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
parent 17c77f44
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> 2014-01-15 Matthew Gretton-Dann <matthew.gretton-dann@linaro.org>
Kugan Vivekanandarajah <kuganv@linaro.org> Kugan Vivekanandarajah <kuganv@linaro.org>
......
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> 2014-01-15 Kirill Yukhin <kirill.yukhin@intel.com>
PR target/59808 PR target/59808
......
// { 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)]);
}
...@@ -5480,6 +5480,59 @@ permute_vec_elements (tree x, tree y, tree mask_vec, gimple stmt, ...@@ -5480,6 +5480,59 @@ permute_vec_elements (tree x, tree y, tree mask_vec, gimple stmt,
return data_ref; 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. /* vectorizable_load.
Check if STMT reads a non scalar data-ref (array/pointer/structure) that 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, ...@@ -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 /* If we have versioned for aliasing then we are sure
this is a loop invariant load and thus we can insert this is a loop invariant load and thus we can insert
it on the preheader edge. */ 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 ()) if (dump_enabled_p ())
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment