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:
parent
983a3d80db
commit
4ba5ea117a
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user