Commit 832b4117 by Richard Sandiford Committed by Richard Sandiford

Add DR_STEP_ALIGNMENT

A later patch adds base alignment information to innermost_loop_behavior.
After that, the only remaining piece of alignment information that wasn't
immediately obvious was the step alignment.  Adding that allows a minor
simplification to vect_compute_data_ref_alignment, and also potentially
improves the handling of variable strides for outer loop vectorisation.
A later patch will also use it to give the alignment of the DR as a whole.

2017-07-03  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* tree-data-ref.h (innermost_loop_behavior): Add a step_alignment
	field.
	(DR_STEP_ALIGNMENT): New macro.
	* tree-vectorizer.h (STMT_VINFO_DR_STEP_ALIGNMENT): Likewise.
	* tree-data-ref.c (dr_analyze_innermost): Initalize step_alignment.
	(create_data_ref): Print it.
	* tree-vect-stmts.c (vectorizable_load): Use the step alignment
	to tell whether the step preserves vector (mis)alignment.
	* tree-vect-data-refs.c (vect_compute_data_ref_alignment): Likewise.
	Move the check for an integer step and generalise to all INTEGER_CST.
	(vect_analyze_data_refs): Set DR_STEP_ALIGNMENT when setting DR_STEP.
	Print the outer step alignment.

From-SVN: r249915
parent e054a185
2017-07-03 Richard Sandiford <richard.sandiford@linaro.org> 2017-07-03 Richard Sandiford <richard.sandiford@linaro.org>
* tree-data-ref.h (innermost_loop_behavior): Add a step_alignment
field.
(DR_STEP_ALIGNMENT): New macro.
* tree-vectorizer.h (STMT_VINFO_DR_STEP_ALIGNMENT): Likewise.
* tree-data-ref.c (dr_analyze_innermost): Initalize step_alignment.
(create_data_ref): Print it.
* tree-vect-stmts.c (vectorizable_load): Use the step alignment
to tell whether the step preserves vector (mis)alignment.
* tree-vect-data-refs.c (vect_compute_data_ref_alignment): Likewise.
Move the check for an integer step and generalise to all INTEGER_CST.
(vect_analyze_data_refs): Set DR_STEP_ALIGNMENT when setting DR_STEP.
Print the outer step alignment.
2017-07-03 Richard Sandiford <richard.sandiford@linaro.org>
* tree-data-ref.h (innermost_loop_behavior): Replace aligned_to * tree-data-ref.h (innermost_loop_behavior): Replace aligned_to
with offset_alignment. with offset_alignment.
(DR_ALIGNED_TO): Delete. (DR_ALIGNED_TO): Delete.
......
...@@ -870,6 +870,7 @@ dr_analyze_innermost (innermost_loop_behavior *drb, tree ref, ...@@ -870,6 +870,7 @@ dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
drb->init = init; drb->init = init;
drb->step = step; drb->step = step;
drb->offset_alignment = highest_pow2_factor (offset_iv.base); drb->offset_alignment = highest_pow2_factor (offset_iv.base);
drb->step_alignment = highest_pow2_factor (step);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "success.\n"); fprintf (dump_file, "success.\n");
...@@ -1086,6 +1087,7 @@ create_data_ref (loop_p nest, loop_p loop, tree memref, gimple *stmt, ...@@ -1086,6 +1087,7 @@ create_data_ref (loop_p nest, loop_p loop, tree memref, gimple *stmt,
print_generic_expr (dump_file, DR_STEP (dr), TDF_SLIM); print_generic_expr (dump_file, DR_STEP (dr), TDF_SLIM);
fprintf (dump_file, "\n\toffset alignment: %d", fprintf (dump_file, "\n\toffset alignment: %d",
DR_OFFSET_ALIGNMENT (dr)); DR_OFFSET_ALIGNMENT (dr));
fprintf (dump_file, "\n\tstep alignment: %d", DR_STEP_ALIGNMENT (dr));
fprintf (dump_file, "\n\tbase_object: "); fprintf (dump_file, "\n\tbase_object: ");
print_generic_expr (dump_file, DR_BASE_OBJECT (dr), TDF_SLIM); print_generic_expr (dump_file, DR_BASE_OBJECT (dr), TDF_SLIM);
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
......
...@@ -56,6 +56,9 @@ struct innermost_loop_behavior ...@@ -56,6 +56,9 @@ struct innermost_loop_behavior
high value if the offset is zero. This is a byte rather than a bit high value if the offset is zero. This is a byte rather than a bit
quantity. */ quantity. */
unsigned int offset_alignment; unsigned int offset_alignment;
/* Likewise for STEP. */
unsigned int step_alignment;
}; };
/* Describes the evolutions of indices of the memory reference. The indices /* Describes the evolutions of indices of the memory reference. The indices
...@@ -145,6 +148,7 @@ struct data_reference ...@@ -145,6 +148,7 @@ struct data_reference
#define DR_STEP(DR) (DR)->innermost.step #define DR_STEP(DR) (DR)->innermost.step
#define DR_PTR_INFO(DR) (DR)->alias.ptr_info #define DR_PTR_INFO(DR) (DR)->alias.ptr_info
#define DR_OFFSET_ALIGNMENT(DR) (DR)->innermost.offset_alignment #define DR_OFFSET_ALIGNMENT(DR) (DR)->innermost.offset_alignment
#define DR_STEP_ALIGNMENT(DR) (DR)->innermost.step_alignment
#define DR_INNERMOST(DR) (DR)->innermost #define DR_INNERMOST(DR) (DR)->innermost
typedef struct data_reference *data_reference_p; typedef struct data_reference *data_reference_p;
......
...@@ -698,10 +698,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -698,10 +698,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
divides by the vector size. */ divides by the vector size. */
else if (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 step_preserves_misalignment_p
= (tree_fits_shwi_p (step) = (DR_STEP_ALIGNMENT (dr)
&& tree_to_shwi (step) % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0); % GET_MODE_SIZE (TYPE_MODE (vectype))) == 0;
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
...@@ -720,12 +719,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -720,12 +719,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
the dataref evenly divides by the vector size. */ the dataref evenly divides by the vector size. */
else else
{ {
tree step = DR_STEP (dr);
unsigned vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); unsigned vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
step_preserves_misalignment_p step_preserves_misalignment_p
= (tree_fits_shwi_p (step) = ((DR_STEP_ALIGNMENT (dr) * vf)
&& ((tree_to_shwi (step) * vf) % GET_MODE_SIZE (TYPE_MODE (vectype))) == 0;
% GET_MODE_SIZE (TYPE_MODE (vectype)) == 0));
if (!step_preserves_misalignment_p && dump_enabled_p ()) if (!step_preserves_misalignment_p && dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
...@@ -773,7 +770,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr) ...@@ -773,7 +770,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
alignment = TYPE_ALIGN_UNIT (vectype); alignment = TYPE_ALIGN_UNIT (vectype);
if (drb->offset_alignment < alignment if (drb->offset_alignment < alignment
|| !step_preserves_misalignment_p) || !step_preserves_misalignment_p
/* We need to know whether the step wrt the vectorized loop is
negative when computing the starting misalignment below. */
|| TREE_CODE (drb->step) != INTEGER_CST)
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
...@@ -3414,6 +3414,8 @@ again: ...@@ -3414,6 +3414,8 @@ again:
DR_STEP (newdr) = step; DR_STEP (newdr) = step;
DR_OFFSET_ALIGNMENT (newdr) DR_OFFSET_ALIGNMENT (newdr)
= BIGGEST_ALIGNMENT; = BIGGEST_ALIGNMENT;
DR_STEP_ALIGNMENT (newdr)
= highest_pow2_factor (step);
dr = newdr; dr = newdr;
simd_lane_access = true; simd_lane_access = true;
} }
...@@ -3665,6 +3667,8 @@ again: ...@@ -3665,6 +3667,8 @@ again:
STMT_VINFO_DR_STEP (stmt_info)); STMT_VINFO_DR_STEP (stmt_info));
dump_printf (MSG_NOTE, "\n\touter offset alignment: %d\n", dump_printf (MSG_NOTE, "\n\touter offset alignment: %d\n",
STMT_VINFO_DR_OFFSET_ALIGNMENT (stmt_info)); STMT_VINFO_DR_OFFSET_ALIGNMENT (stmt_info));
dump_printf (MSG_NOTE, "\n\touter step alignment: %d\n",
STMT_VINFO_DR_STEP_ALIGNMENT (stmt_info));
} }
} }
......
...@@ -7288,8 +7288,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -7288,8 +7288,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
nested within an outer-loop that is being vectorized. */ nested within an outer-loop that is being vectorized. */
if (nested_in_vect_loop if (nested_in_vect_loop
&& (TREE_INT_CST_LOW (DR_STEP (dr)) && (DR_STEP_ALIGNMENT (dr) % GET_MODE_SIZE (TYPE_MODE (vectype))) != 0)
% GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
{ {
gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized); gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized);
compute_in_loop = true; compute_in_loop = true;
......
...@@ -711,6 +711,8 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo) ...@@ -711,6 +711,8 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo)
#define STMT_VINFO_DR_STEP(S) (S)->dr_wrt_vec_loop.step #define STMT_VINFO_DR_STEP(S) (S)->dr_wrt_vec_loop.step
#define STMT_VINFO_DR_OFFSET_ALIGNMENT(S) \ #define STMT_VINFO_DR_OFFSET_ALIGNMENT(S) \
(S)->dr_wrt_vec_loop.offset_alignment (S)->dr_wrt_vec_loop.offset_alignment
#define STMT_VINFO_DR_STEP_ALIGNMENT(S) \
(S)->dr_wrt_vec_loop.step_alignment
#define STMT_VINFO_IN_PATTERN_P(S) (S)->in_pattern_p #define STMT_VINFO_IN_PATTERN_P(S) (S)->in_pattern_p
#define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt #define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt
......
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