Message ID | 87k23qx91y.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | None | expand |
On Mon, Jul 3, 2017 at 9:40 AM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > This combines the information from previous patches to give a guaranteed > alignment for the DR as a whole. This should be a bit safer than using > base_element_aligned, since that only really took the base into account > (not the init or offset). > > Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Ok. Thanks for cleaning up all this mess... Richard. > Richard > > > 2017-07-03 Richard Sandiford <richard.sandiford@linaro.org> > > gcc/ > * tree-data-ref.h (dr_alignment): Declare. > * tree-data-ref.c (dr_alignment): New function. > * tree-vectorizer.h (dataref_aux): Remove base_element_aligned. > * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Don't > set it. > * tree-vect-stmts.c (vectorizable_store): Use dr_alignment. > > Index: gcc/tree-data-ref.h > =================================================================== > --- gcc/tree-data-ref.h 2017-07-03 08:17:58.418572314 +0100 > +++ gcc/tree-data-ref.h 2017-07-03 08:18:29.775412176 +0100 > @@ -405,6 +405,16 @@ extern bool compute_all_dependences (vec > vec<loop_p>, bool); > extern tree find_data_references_in_bb (struct loop *, basic_block, > vec<data_reference_p> *); > +extern unsigned int dr_alignment (innermost_loop_behavior *); > + > +/* Return the alignment in bytes that DR is guaranteed to have at all > + times. */ > + > +inline unsigned int > +dr_alignment (data_reference *dr) > +{ > + return dr_alignment (&DR_INNERMOST (dr)); > +} > > extern bool dr_may_alias_p (const struct data_reference *, > const struct data_reference *, bool); > Index: gcc/tree-data-ref.c > =================================================================== > --- gcc/tree-data-ref.c 2017-07-03 08:17:58.418572314 +0100 > +++ gcc/tree-data-ref.c 2017-07-03 08:17:59.017546839 +0100 > @@ -4769,6 +4769,30 @@ find_data_references_in_loop (struct loo > return NULL_TREE; > } > > +/* Return the alignment in bytes that DRB is guaranteed to have at all > + times. */ > + > +unsigned int > +dr_alignment (innermost_loop_behavior *drb) > +{ > + /* Get the alignment of BASE_ADDRESS + INIT. */ > + unsigned int alignment = drb->base_alignment; > + unsigned int misalignment = (drb->base_misalignment > + + TREE_INT_CST_LOW (drb->init)); > + if (misalignment != 0) > + alignment = MIN (alignment, misalignment & -misalignment); > + > + /* Cap it to the alignment of OFFSET. */ > + if (!integer_zerop (drb->offset)) > + alignment = MIN (alignment, drb->offset_alignment); > + > + /* Cap it to the alignment of STEP. */ > + if (!integer_zerop (drb->step)) > + alignment = MIN (alignment, drb->step_alignment); > + > + return alignment; > +} > + > /* Recursive helper function. */ > > static bool > Index: gcc/tree-vectorizer.h > =================================================================== > --- gcc/tree-vectorizer.h 2017-07-03 08:17:58.419572272 +0100 > +++ gcc/tree-vectorizer.h 2017-07-03 08:18:09.031167838 +0100 > @@ -752,8 +752,6 @@ struct dataref_aux { > int misalignment; > /* If true the alignment of base_decl needs to be increased. */ > bool base_misaligned; > - /* If true we know the base is at least vector element alignment aligned. */ > - bool base_element_aligned; > tree base_decl; > }; > > Index: gcc/tree-vect-data-refs.c > =================================================================== > --- gcc/tree-vect-data-refs.c 2017-07-03 08:17:58.419572272 +0100 > +++ gcc/tree-vect-data-refs.c 2017-07-03 08:17:59.018546796 +0100 > @@ -731,12 +731,6 @@ vect_compute_data_ref_alignment (struct > unsigned int base_alignment = drb->base_alignment; > unsigned int base_misalignment = drb->base_misalignment; > unsigned HOST_WIDE_INT vector_alignment = TYPE_ALIGN_UNIT (vectype); > - unsigned HOST_WIDE_INT element_alignment > - = TYPE_ALIGN_UNIT (TREE_TYPE (vectype)); > - > - if (base_alignment >= element_alignment > - && (base_misalignment & (element_alignment - 1)) == 0) > - DR_VECT_AUX (dr)->base_element_aligned = true; > > if (drb->offset_alignment < vector_alignment > || !step_preserves_misalignment_p > @@ -797,7 +791,6 @@ vect_compute_data_ref_alignment (struct > > DR_VECT_AUX (dr)->base_decl = base; > DR_VECT_AUX (dr)->base_misaligned = true; > - DR_VECT_AUX (dr)->base_element_aligned = true; > base_misalignment = 0; > } > unsigned int misalignment = (base_misalignment > Index: gcc/tree-vect-stmts.c > =================================================================== > --- gcc/tree-vect-stmts.c 2017-07-03 08:07:42.512875037 +0100 > +++ gcc/tree-vect-stmts.c 2017-07-03 08:17:59.019546754 +0100 > @@ -6359,11 +6359,7 @@ vectorizable_store (gimple *stmt, gimple > misalign = 0; > else if (DR_MISALIGNMENT (first_dr) == -1) > { > - if (DR_VECT_AUX (first_dr)->base_element_aligned) > - align = TYPE_ALIGN_UNIT (elem_type); > - else > - align = get_object_alignment (DR_REF (first_dr)) > - / BITS_PER_UNIT; > + align = dr_alignment (vect_dr_behavior (first_dr)); > misalign = 0; > TREE_TYPE (data_ref) > = build_aligned_type (TREE_TYPE (data_ref), > @@ -7435,11 +7431,7 @@ vectorizable_load (gimple *stmt, gimple_ > } > else if (DR_MISALIGNMENT (first_dr) == -1) > { > - if (DR_VECT_AUX (first_dr)->base_element_aligned) > - align = TYPE_ALIGN_UNIT (elem_type); > - else > - align = (get_object_alignment (DR_REF (first_dr)) > - / BITS_PER_UNIT); > + align = dr_alignment (vect_dr_behavior (first_dr)); > misalign = 0; > TREE_TYPE (data_ref) > = build_aligned_type (TREE_TYPE (data_ref),
Index: gcc/tree-data-ref.h =================================================================== --- gcc/tree-data-ref.h 2017-07-03 08:17:58.418572314 +0100 +++ gcc/tree-data-ref.h 2017-07-03 08:18:29.775412176 +0100 @@ -405,6 +405,16 @@ extern bool compute_all_dependences (vec vec<loop_p>, bool); extern tree find_data_references_in_bb (struct loop *, basic_block, vec<data_reference_p> *); +extern unsigned int dr_alignment (innermost_loop_behavior *); + +/* Return the alignment in bytes that DR is guaranteed to have at all + times. */ + +inline unsigned int +dr_alignment (data_reference *dr) +{ + return dr_alignment (&DR_INNERMOST (dr)); +} extern bool dr_may_alias_p (const struct data_reference *, const struct data_reference *, bool); Index: gcc/tree-data-ref.c =================================================================== --- gcc/tree-data-ref.c 2017-07-03 08:17:58.418572314 +0100 +++ gcc/tree-data-ref.c 2017-07-03 08:17:59.017546839 +0100 @@ -4769,6 +4769,30 @@ find_data_references_in_loop (struct loo return NULL_TREE; } +/* Return the alignment in bytes that DRB is guaranteed to have at all + times. */ + +unsigned int +dr_alignment (innermost_loop_behavior *drb) +{ + /* Get the alignment of BASE_ADDRESS + INIT. */ + unsigned int alignment = drb->base_alignment; + unsigned int misalignment = (drb->base_misalignment + + TREE_INT_CST_LOW (drb->init)); + if (misalignment != 0) + alignment = MIN (alignment, misalignment & -misalignment); + + /* Cap it to the alignment of OFFSET. */ + if (!integer_zerop (drb->offset)) + alignment = MIN (alignment, drb->offset_alignment); + + /* Cap it to the alignment of STEP. */ + if (!integer_zerop (drb->step)) + alignment = MIN (alignment, drb->step_alignment); + + return alignment; +} + /* Recursive helper function. */ static bool Index: gcc/tree-vectorizer.h =================================================================== --- gcc/tree-vectorizer.h 2017-07-03 08:17:58.419572272 +0100 +++ gcc/tree-vectorizer.h 2017-07-03 08:18:09.031167838 +0100 @@ -752,8 +752,6 @@ struct dataref_aux { int misalignment; /* If true the alignment of base_decl needs to be increased. */ bool base_misaligned; - /* If true we know the base is at least vector element alignment aligned. */ - bool base_element_aligned; tree base_decl; }; Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c 2017-07-03 08:17:58.419572272 +0100 +++ gcc/tree-vect-data-refs.c 2017-07-03 08:17:59.018546796 +0100 @@ -731,12 +731,6 @@ vect_compute_data_ref_alignment (struct unsigned int base_alignment = drb->base_alignment; unsigned int base_misalignment = drb->base_misalignment; unsigned HOST_WIDE_INT vector_alignment = TYPE_ALIGN_UNIT (vectype); - unsigned HOST_WIDE_INT element_alignment - = TYPE_ALIGN_UNIT (TREE_TYPE (vectype)); - - if (base_alignment >= element_alignment - && (base_misalignment & (element_alignment - 1)) == 0) - DR_VECT_AUX (dr)->base_element_aligned = true; if (drb->offset_alignment < vector_alignment || !step_preserves_misalignment_p @@ -797,7 +791,6 @@ vect_compute_data_ref_alignment (struct DR_VECT_AUX (dr)->base_decl = base; DR_VECT_AUX (dr)->base_misaligned = true; - DR_VECT_AUX (dr)->base_element_aligned = true; base_misalignment = 0; } unsigned int misalignment = (base_misalignment Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-07-03 08:07:42.512875037 +0100 +++ gcc/tree-vect-stmts.c 2017-07-03 08:17:59.019546754 +0100 @@ -6359,11 +6359,7 @@ vectorizable_store (gimple *stmt, gimple misalign = 0; else if (DR_MISALIGNMENT (first_dr) == -1) { - if (DR_VECT_AUX (first_dr)->base_element_aligned) - align = TYPE_ALIGN_UNIT (elem_type); - else - align = get_object_alignment (DR_REF (first_dr)) - / BITS_PER_UNIT; + align = dr_alignment (vect_dr_behavior (first_dr)); misalign = 0; TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref), @@ -7435,11 +7431,7 @@ vectorizable_load (gimple *stmt, gimple_ } else if (DR_MISALIGNMENT (first_dr) == -1) { - if (DR_VECT_AUX (first_dr)->base_element_aligned) - align = TYPE_ALIGN_UNIT (elem_type); - else - align = (get_object_alignment (DR_REF (first_dr)) - / BITS_PER_UNIT); + align = dr_alignment (vect_dr_behavior (first_dr)); misalign = 0; TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref),