re PR tree-optimization/56878 (Issue with candidate choice in vect_gen_niters_for_prolog_loop.)

2013-04-11  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56878
	* tree-flow.h (outermost_invariant_loop_for_expr): Declare.
	* tree-ssa-loop-ivopts.c (outermost_invariant_loop_for_expr):
	New function.
	* tree-vect-data-refs.c (vect_enhance_data_refs_alignment):
	Prefer to align the DR with the most invariant base address.

From-SVN: r197769
This commit is contained in:
Richard Biener 2013-04-11 11:21:18 +00:00 committed by Richard Biener
parent 983a3d80db
commit 4ba5ea117a
4 changed files with 80 additions and 9 deletions

View File

@ -1,3 +1,12 @@
2013-04-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/56878
* tree-flow.h (outermost_invariant_loop_for_expr): Declare.
* tree-ssa-loop-ivopts.c (outermost_invariant_loop_for_expr):
New function.
* tree-vect-data-refs.c (vect_enhance_data_refs_alignment):
Prefer to align the DR with the most invariant base address.
2013-04-11 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
* opts.c (common_handle_option): Fix formatting and add FALLTHRU

View File

@ -749,6 +749,7 @@ extern void tree_check_data_deps (void);
/* In tree-ssa-loop-ivopts.c */
bool expr_invariant_in_loop_p (struct loop *, tree);
bool stmt_invariant_in_loop_p (struct loop *, gimple);
struct loop *outermost_invariant_loop_for_expr (struct loop *, tree);
bool multiplier_allowed_in_address_p (HOST_WIDE_INT, enum machine_mode,
addr_space_t);
bool may_be_nonaddressable_p (tree expr);

View File

@ -1367,6 +1367,54 @@ find_interesting_uses_cond (struct ivopts_data *data, gimple stmt)
record_use (data, NULL, civ, stmt, USE_COMPARE);
}
/* Returns the outermost loop EXPR is obviously invariant in
relative to the loop LOOP, i.e. if all its operands are defined
outside of the returned loop. Returns NULL if EXPR is not
even obviously invariant in LOOP. */
struct loop *
outermost_invariant_loop_for_expr (struct loop *loop, tree expr)
{
basic_block def_bb;
unsigned i, len;
if (is_gimple_min_invariant (expr))
return current_loops->tree_root;
if (TREE_CODE (expr) == SSA_NAME)
{
def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
if (def_bb)
{
if (flow_bb_inside_loop_p (loop, def_bb))
return NULL;
return superloop_at_depth (loop,
loop_depth (def_bb->loop_father) + 1);
}
return current_loops->tree_root;
}
if (!EXPR_P (expr))
return NULL;
unsigned maxdepth = 0;
len = TREE_OPERAND_LENGTH (expr);
for (i = 0; i < len; i++)
{
struct loop *ivloop;
if (!TREE_OPERAND (expr, i))
continue;
ivloop = outermost_invariant_loop_for_expr (loop, TREE_OPERAND (expr, i));
if (!ivloop)
return NULL;
maxdepth = MAX (maxdepth, loop_depth (ivloop));
}
return superloop_at_depth (loop, maxdepth);
}
/* Returns true if expression EXPR is obviously invariant in LOOP,
i.e. if all its operands are defined outside of the LOOP. LOOP
should not be the function body. */

View File

@ -1456,20 +1456,35 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
}
else
{
/* If we don't know all the misalignment values, we prefer
peeling for data-ref that has maximum number of data-refs
/* If we don't know any misalignment values, we prefer
peeling for data-ref that has the maximum number of data-refs
with the same alignment, unless the target prefers to align
stores over load. */
if (all_misalignments_unknown)
{
if (same_align_drs_max
< STMT_VINFO_SAME_ALIGN_REFS (stmt_info).length ()
|| !dr0)
unsigned same_align_drs
= STMT_VINFO_SAME_ALIGN_REFS (stmt_info).length ();
if (!dr0
|| same_align_drs_max < same_align_drs)
{
same_align_drs_max
= STMT_VINFO_SAME_ALIGN_REFS (stmt_info).length ();
same_align_drs_max = same_align_drs;
dr0 = dr;
}
/* For data-refs with the same number of related
accesses prefer the one where the misalign
computation will be invariant in the outermost loop. */
else if (same_align_drs_max == same_align_drs)
{
struct loop *ivloop0, *ivloop;
ivloop0 = outermost_invariant_loop_for_expr
(loop, DR_BASE_ADDRESS (dr0));
ivloop = outermost_invariant_loop_for_expr
(loop, DR_BASE_ADDRESS (dr));
if ((ivloop && !ivloop0)
|| (ivloop && ivloop0
&& flow_loop_nested_p (ivloop, ivloop0)))
dr0 = dr;
}
if (!first_store && DR_IS_WRITE (dr))
first_store = dr;
@ -1478,8 +1493,6 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
/* If there are both known and unknown misaligned accesses in the
loop, we choose peeling amount according to the known
accesses. */
if (!supportable_dr_alignment)
{
dr0 = dr;