aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-07-03 13:36:13 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-07-03 13:36:13 +0000
commit3f5e8a7690d91daba3d8988318895fe51b7749ec (patch)
tree72acbcd4a626f9138dea9686c90e6c41182d293b /gcc/tree-vect-data-refs.c
parent63d03dcecdafe34715282a5155cfc2162375feca (diff)
downloadgcc-3f5e8a7690d91daba3d8988318895fe51b7749ec.zip
gcc-3f5e8a7690d91daba3d8988318895fe51b7749ec.tar.gz
gcc-3f5e8a7690d91daba3d8988318895fe51b7749ec.tar.bz2
Use innermost_loop_behavior for outer loop vectorisation
This patch replaces the individual stmt_vinfo dr_* fields with an innermost_loop_behavior, so that the changes in later patches get picked up automatically. It also adds a helper function for getting the behavior of a data reference wrt the vectorised loop. 2017-07-03 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * tree-vectorizer.h (_stmt_vec_info): Replace individual dr_* fields with dr_wrt_vec_loop. (STMT_VINFO_DR_BASE_ADDRESS, STMT_VINFO_DR_INIT, STMT_VINFO_DR_OFFSET) (STMT_VINFO_DR_STEP, STMT_VINFO_DR_ALIGNED_TO): Update accordingly. (STMT_VINFO_DR_WRT_VEC_LOOP): New macro. (vect_dr_behavior): New function. (vect_create_addr_base_for_vector_ref): Remove loop parameter. * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Use vect_dr_behavior. Use a step_preserves_misalignment_p boolean to track whether the step preserves the misalignment. (vect_create_addr_base_for_vector_ref): Remove loop parameter. Use vect_dr_behavior. (vect_setup_realignment): Update call accordingly. (vect_create_data_ref_ptr): Likewise. Use vect_dr_behavior. * tree-vect-loop-manip.c (vect_gen_prolog_loop_niters): Update call to vect_create_addr_base_for_vector_ref. (vect_create_cond_for_align_checks): Likewise. * tree-vect-patterns.c (vect_recog_bool_pattern): Copy STMT_VINFO_DR_WRT_VEC_LOOP as a block. (vect_recog_mask_conversion_pattern): Likewise. * tree-vect-stmts.c (compare_step_with_zero): Use vect_dr_behavior. (new_stmt_vec_info): Remove redundant zeroing. From-SVN: r249911
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r--gcc/tree-vect-data-refs.c112
1 files changed, 42 insertions, 70 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 1595bb4..3b4d570 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -666,11 +666,8 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = NULL;
tree ref = DR_REF (dr);
- tree vectype;
- tree base, base_addr;
- tree misalign = NULL_TREE;
- tree aligned_to;
- tree step;
+ tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+ tree base;
unsigned HOST_WIDE_INT alignment;
if (dump_enabled_p ())
@@ -683,11 +680,15 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
/* Initialize misalignment to unknown. */
SET_DR_MISALIGNMENT (dr, DR_MISALIGNMENT_UNKNOWN);
- if (tree_fits_shwi_p (DR_STEP (dr)))
- misalign = DR_INIT (dr);
- aligned_to = DR_ALIGNED_TO (dr);
- base_addr = DR_BASE_ADDRESS (dr);
- vectype = STMT_VINFO_VECTYPE (stmt_info);
+ innermost_loop_behavior *drb = vect_dr_behavior (dr);
+ bool step_preserves_misalignment_p;
+
+ /* No step for BB vectorization. */
+ if (!loop)
+ {
+ gcc_assert (integer_zerop (drb->step));
+ step_preserves_misalignment_p = true;
+ }
/* In case the dataref is in an inner-loop of the loop that is being
vectorized (LOOP), we use the base and misalignment information
@@ -695,26 +696,21 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
stays the same throughout the execution of the inner-loop, which is why
we have to check that the stride of the dataref in the inner-loop evenly
divides by the vector size. */
- if (loop && nested_in_vect_loop_p (loop, stmt))
+ else if (nested_in_vect_loop_p (loop, stmt))
{
tree step = DR_STEP (dr);
+ step_preserves_misalignment_p
+ = (tree_fits_shwi_p (step)
+ && tree_to_shwi (step) % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0);
- if (tree_fits_shwi_p (step)
- && tree_to_shwi (step) % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "inner step divides the vector-size.\n");
- misalign = STMT_VINFO_DR_INIT (stmt_info);
- aligned_to = STMT_VINFO_DR_ALIGNED_TO (stmt_info);
- base_addr = STMT_VINFO_DR_BASE_ADDRESS (stmt_info);
- }
- else
+ if (dump_enabled_p ())
{
- if (dump_enabled_p ())
+ if (step_preserves_misalignment_p)
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "inner step divides the vector-size.\n");
+ else
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "inner step doesn't divide the vector-size.\n");
- misalign = NULL_TREE;
+ "inner step doesn't divide the vector-size.\n");
}
}
@@ -725,18 +721,17 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
else
{
tree step = DR_STEP (dr);
- unsigned vf = loop ? LOOP_VINFO_VECT_FACTOR (loop_vinfo) : 1;
+ unsigned vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ step_preserves_misalignment_p
+ = (tree_fits_shwi_p (step)
+ && ((tree_to_shwi (step) * vf)
+ % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0));
- if (tree_fits_shwi_p (step)
- && ((tree_to_shwi (step) * vf)
- % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "step doesn't divide the vector-size.\n");
- misalign = NULL_TREE;
- }
+ if (!step_preserves_misalignment_p && dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "step doesn't divide the vector-size.\n");
}
+ tree base_addr = drb->base_address;
/* To look at alignment of the base we have to preserve an inner MEM_REF
as that carries alignment information of the actual access. */
@@ -777,8 +772,8 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
alignment = TYPE_ALIGN_UNIT (vectype);
- if ((compare_tree_int (aligned_to, alignment) < 0)
- || !misalign)
+ if ((compare_tree_int (drb->aligned_to, alignment) < 0)
+ || !step_preserves_misalignment_p)
{
if (dump_enabled_p ())
{
@@ -835,19 +830,16 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
DR_VECT_AUX (dr)->base_element_aligned = true;
}
- if (loop && nested_in_vect_loop_p (loop, stmt))
- step = STMT_VINFO_DR_STEP (stmt_info);
- else
- step = DR_STEP (dr);
/* If this is a backward running DR then first access in the larger
vectype actually is N-1 elements before the address in the DR.
Adjust misalign accordingly. */
- if (tree_int_cst_sgn (step) < 0)
+ tree misalign = drb->init;
+ if (tree_int_cst_sgn (drb->step) < 0)
{
tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
/* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type,
otherwise we wouldn't be here. */
- offset = fold_build2 (MULT_EXPR, ssizetype, offset, step);
+ offset = fold_build2 (MULT_EXPR, ssizetype, offset, drb->step);
/* PLUS because STEP was negative. */
misalign = size_binop (PLUS_EXPR, misalign, offset);
}
@@ -3973,38 +3965,22 @@ tree
vect_create_addr_base_for_vector_ref (gimple *stmt,
gimple_seq *new_stmt_list,
tree offset,
- struct loop *loop,
tree byte_offset)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
- tree data_ref_base;
const char *base_name;
tree addr_base;
tree dest;
gimple_seq seq = NULL;
- tree base_offset;
- tree init;
tree vect_ptr_type;
tree step = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)));
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ innermost_loop_behavior *drb = vect_dr_behavior (dr);
- if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father)
- {
- struct loop *outer_loop = LOOP_VINFO_LOOP (loop_vinfo);
-
- gcc_assert (nested_in_vect_loop_p (outer_loop, stmt));
-
- data_ref_base = unshare_expr (STMT_VINFO_DR_BASE_ADDRESS (stmt_info));
- base_offset = unshare_expr (STMT_VINFO_DR_OFFSET (stmt_info));
- init = unshare_expr (STMT_VINFO_DR_INIT (stmt_info));
- }
- else
- {
- data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
- base_offset = unshare_expr (DR_OFFSET (dr));
- init = unshare_expr (DR_INIT (dr));
- }
+ tree data_ref_base = unshare_expr (drb->base_address);
+ tree base_offset = unshare_expr (drb->offset);
+ tree init = unshare_expr (drb->init);
if (loop_vinfo)
base_name = get_name (data_ref_base);
@@ -4169,11 +4145,7 @@ vect_create_data_ref_ptr (gimple *stmt, tree aggr_type, struct loop *at_loop,
/* Check the step (evolution) of the load in LOOP, and record
whether it's invariant. */
- if (nested_in_vect_loop)
- step = STMT_VINFO_DR_STEP (stmt_info);
- else
- step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
-
+ step = vect_dr_behavior (dr)->step;
if (integer_zerop (step))
*inv_p = true;
else
@@ -4271,7 +4243,7 @@ vect_create_data_ref_ptr (gimple *stmt, tree aggr_type, struct loop *at_loop,
/* Create: (&(base[init_val+offset]+byte_offset) in the loop preheader. */
new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
- offset, loop, byte_offset);
+ offset, byte_offset);
if (new_stmt_list)
{
if (pe)
@@ -4985,7 +4957,7 @@ vect_setup_realignment (gimple *stmt, gimple_stmt_iterator *gsi,
{
/* Generate the INIT_ADDR computation outside LOOP. */
init_addr = vect_create_addr_base_for_vector_ref (stmt, &stmts,
- NULL_TREE, loop);
+ NULL_TREE);
if (loop)
{
pe = loop_preheader_edge (loop);