Message ID | 87shiex9a5.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | None | expand |
On Mon, Jul 3, 2017 at 9:35 AM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > 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. > > Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Ok. > Richard > > > 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. > > Index: gcc/tree-data-ref.h > =================================================================== > --- gcc/tree-data-ref.h 2017-07-03 07:51:31.005161213 +0100 > +++ gcc/tree-data-ref.h 2017-07-03 07:52:14.194782203 +0100 > @@ -56,6 +56,9 @@ struct innermost_loop_behavior > high value if the offset is zero. This is a byte rather than a bit > quantity. */ > unsigned int offset_alignment; > + > + /* Likewise for STEP. */ > + unsigned int step_alignment; > }; > > /* Describes the evolutions of indices of the memory reference. The indices > @@ -145,6 +148,7 @@ #define DR_INIT(DR) (DR)- > #define DR_STEP(DR) (DR)->innermost.step > #define DR_PTR_INFO(DR) (DR)->alias.ptr_info > #define DR_OFFSET_ALIGNMENT(DR) (DR)->innermost.offset_alignment > +#define DR_STEP_ALIGNMENT(DR) (DR)->innermost.step_alignment > #define DR_INNERMOST(DR) (DR)->innermost > > typedef struct data_reference *data_reference_p; > Index: gcc/tree-vectorizer.h > =================================================================== > --- gcc/tree-vectorizer.h 2017-07-03 07:51:31.006161241 +0100 > +++ gcc/tree-vectorizer.h 2017-07-03 07:52:14.196782157 +0100 > @@ -709,6 +709,8 @@ #define STMT_VINFO_DR_OFFSET(S) > #define STMT_VINFO_DR_STEP(S) (S)->dr_wrt_vec_loop.step > #define STMT_VINFO_DR_OFFSET_ALIGNMENT(S) \ > (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_RELATED_STMT(S) (S)->related_stmt > Index: gcc/tree-data-ref.c > =================================================================== > --- gcc/tree-data-ref.c 2017-07-03 07:51:31.004161185 +0100 > +++ gcc/tree-data-ref.c 2017-07-03 07:52:14.193782226 +0100 > @@ -870,6 +870,7 @@ dr_analyze_innermost (struct data_refere > drb->init = init; > drb->step = step; > drb->offset_alignment = highest_pow2_factor (offset_iv.base); > + drb->step_alignment = highest_pow2_factor (step); > > if (dump_file && (dump_flags & TDF_DETAILS)) > fprintf (dump_file, "success.\n"); > @@ -1085,6 +1086,7 @@ create_data_ref (loop_p nest, loop_p loo > print_generic_expr (dump_file, DR_STEP (dr), TDF_SLIM); > fprintf (dump_file, "\n\toffset alignment: %d", > DR_OFFSET_ALIGNMENT (dr)); > + fprintf (dump_file, "\n\tstep alignment: %d", DR_STEP_ALIGNMENT (dr)); > fprintf (dump_file, "\n\tbase_object: "); > print_generic_expr (dump_file, DR_BASE_OBJECT (dr), TDF_SLIM); > fprintf (dump_file, "\n"); > Index: gcc/tree-vect-stmts.c > =================================================================== > --- gcc/tree-vect-stmts.c 2017-07-03 07:51:05.480852682 +0100 > +++ gcc/tree-vect-stmts.c 2017-07-03 07:52:14.195782180 +0100 > @@ -7294,8 +7294,7 @@ vectorizable_load (gimple *stmt, gimple_ > nested within an outer-loop that is being vectorized. */ > > if (nested_in_vect_loop > - && (TREE_INT_CST_LOW (DR_STEP (dr)) > - % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0)) > + && (DR_STEP_ALIGNMENT (dr) % GET_MODE_SIZE (TYPE_MODE (vectype))) != 0) > { > gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized); > compute_in_loop = true; > Index: gcc/tree-vect-data-refs.c > =================================================================== > --- gcc/tree-vect-data-refs.c 2017-07-03 07:51:31.006161241 +0100 > +++ gcc/tree-vect-data-refs.c 2017-07-03 07:52:14.194782203 +0100 > @@ -698,10 +698,9 @@ vect_compute_data_ref_alignment (struct > divides by the vector size. */ > 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); > + = (DR_STEP_ALIGNMENT (dr) > + % GET_MODE_SIZE (TYPE_MODE (vectype))) == 0; > > if (dump_enabled_p ()) > { > @@ -720,12 +719,10 @@ vect_compute_data_ref_alignment (struct > the dataref evenly divides by the vector size. */ > else > { > - tree step = DR_STEP (dr); > 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)); > + = ((DR_STEP_ALIGNMENT (dr) * vf) > + % GET_MODE_SIZE (TYPE_MODE (vectype))) == 0; > > if (!step_preserves_misalignment_p && dump_enabled_p ()) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, > @@ -773,7 +770,10 @@ vect_compute_data_ref_alignment (struct > alignment = TYPE_ALIGN_UNIT (vectype); > > 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 ()) > { > @@ -3414,6 +3414,8 @@ vect_analyze_data_refs (vec_info *vinfo, > DR_STEP (newdr) = step; > DR_OFFSET_ALIGNMENT (newdr) > = BIGGEST_ALIGNMENT; > + DR_STEP_ALIGNMENT (newdr) > + = highest_pow2_factor (step); > dr = newdr; > simd_lane_access = true; > } > @@ -3665,6 +3667,8 @@ vect_analyze_data_refs (vec_info *vinfo, > STMT_VINFO_DR_STEP (stmt_info)); > dump_printf (MSG_NOTE, "\n\touter offset alignment: %d\n", > STMT_VINFO_DR_OFFSET_ALIGNMENT (stmt_info)); > + dump_printf (MSG_NOTE, "\n\touter step alignment: %d\n", > + STMT_VINFO_DR_STEP_ALIGNMENT (stmt_info)); > } > } >
Index: gcc/tree-data-ref.h =================================================================== --- gcc/tree-data-ref.h 2017-07-03 07:51:31.005161213 +0100 +++ gcc/tree-data-ref.h 2017-07-03 07:52:14.194782203 +0100 @@ -56,6 +56,9 @@ struct innermost_loop_behavior high value if the offset is zero. This is a byte rather than a bit quantity. */ unsigned int offset_alignment; + + /* Likewise for STEP. */ + unsigned int step_alignment; }; /* Describes the evolutions of indices of the memory reference. The indices @@ -145,6 +148,7 @@ #define DR_INIT(DR) (DR)- #define DR_STEP(DR) (DR)->innermost.step #define DR_PTR_INFO(DR) (DR)->alias.ptr_info #define DR_OFFSET_ALIGNMENT(DR) (DR)->innermost.offset_alignment +#define DR_STEP_ALIGNMENT(DR) (DR)->innermost.step_alignment #define DR_INNERMOST(DR) (DR)->innermost typedef struct data_reference *data_reference_p; Index: gcc/tree-vectorizer.h =================================================================== --- gcc/tree-vectorizer.h 2017-07-03 07:51:31.006161241 +0100 +++ gcc/tree-vectorizer.h 2017-07-03 07:52:14.196782157 +0100 @@ -709,6 +709,8 @@ #define STMT_VINFO_DR_OFFSET(S) #define STMT_VINFO_DR_STEP(S) (S)->dr_wrt_vec_loop.step #define STMT_VINFO_DR_OFFSET_ALIGNMENT(S) \ (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_RELATED_STMT(S) (S)->related_stmt Index: gcc/tree-data-ref.c =================================================================== --- gcc/tree-data-ref.c 2017-07-03 07:51:31.004161185 +0100 +++ gcc/tree-data-ref.c 2017-07-03 07:52:14.193782226 +0100 @@ -870,6 +870,7 @@ dr_analyze_innermost (struct data_refere drb->init = init; drb->step = step; drb->offset_alignment = highest_pow2_factor (offset_iv.base); + drb->step_alignment = highest_pow2_factor (step); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "success.\n"); @@ -1085,6 +1086,7 @@ create_data_ref (loop_p nest, loop_p loo print_generic_expr (dump_file, DR_STEP (dr), TDF_SLIM); fprintf (dump_file, "\n\toffset alignment: %d", DR_OFFSET_ALIGNMENT (dr)); + fprintf (dump_file, "\n\tstep alignment: %d", DR_STEP_ALIGNMENT (dr)); fprintf (dump_file, "\n\tbase_object: "); print_generic_expr (dump_file, DR_BASE_OBJECT (dr), TDF_SLIM); fprintf (dump_file, "\n"); Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-07-03 07:51:05.480852682 +0100 +++ gcc/tree-vect-stmts.c 2017-07-03 07:52:14.195782180 +0100 @@ -7294,8 +7294,7 @@ vectorizable_load (gimple *stmt, gimple_ nested within an outer-loop that is being vectorized. */ if (nested_in_vect_loop - && (TREE_INT_CST_LOW (DR_STEP (dr)) - % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0)) + && (DR_STEP_ALIGNMENT (dr) % GET_MODE_SIZE (TYPE_MODE (vectype))) != 0) { gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized); compute_in_loop = true; Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c 2017-07-03 07:51:31.006161241 +0100 +++ gcc/tree-vect-data-refs.c 2017-07-03 07:52:14.194782203 +0100 @@ -698,10 +698,9 @@ vect_compute_data_ref_alignment (struct divides by the vector size. */ 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); + = (DR_STEP_ALIGNMENT (dr) + % GET_MODE_SIZE (TYPE_MODE (vectype))) == 0; if (dump_enabled_p ()) { @@ -720,12 +719,10 @@ vect_compute_data_ref_alignment (struct the dataref evenly divides by the vector size. */ else { - tree step = DR_STEP (dr); 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)); + = ((DR_STEP_ALIGNMENT (dr) * vf) + % GET_MODE_SIZE (TYPE_MODE (vectype))) == 0; if (!step_preserves_misalignment_p && dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -773,7 +770,10 @@ vect_compute_data_ref_alignment (struct alignment = TYPE_ALIGN_UNIT (vectype); 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 ()) { @@ -3414,6 +3414,8 @@ vect_analyze_data_refs (vec_info *vinfo, DR_STEP (newdr) = step; DR_OFFSET_ALIGNMENT (newdr) = BIGGEST_ALIGNMENT; + DR_STEP_ALIGNMENT (newdr) + = highest_pow2_factor (step); dr = newdr; simd_lane_access = true; } @@ -3665,6 +3667,8 @@ vect_analyze_data_refs (vec_info *vinfo, STMT_VINFO_DR_STEP (stmt_info)); dump_printf (MSG_NOTE, "\n\touter offset alignment: %d\n", STMT_VINFO_DR_OFFSET_ALIGNMENT (stmt_info)); + dump_printf (MSG_NOTE, "\n\touter step alignment: %d\n", + STMT_VINFO_DR_STEP_ALIGNMENT (stmt_info)); } }