From: Richard Sandiford Date: Mon, 3 Jul 2017 13:37:07 +0000 (+0000) Subject: Add a helper for getting the overall alignment of a DR X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=25f68d908ff41a912a9bacb88afba665dd59c2ff;p=gcc.git Add a helper for getting the overall alignment of a DR 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). 2017-07-03 Richard Sandiford 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. From-SVN: r249917 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c116fccbc60..d384bbf063f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-07-03 Richard Sandiford + + * 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. + 2017-07-03 Richard Sandiford * tree-data-ref.h (innermost_loop_behavior): Add base_alignment diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index ab768535bf8..b7f9a570abb 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -4770,6 +4770,30 @@ find_data_references_in_loop (struct loop *loop, 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 diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index 72c68d0fdab..1559cd90bd2 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -405,6 +405,16 @@ extern bool compute_all_dependences (vec , vec, bool); extern tree find_data_references_in_bb (struct loop *, basic_block, vec *); +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); diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 3db408c274d..907f35e6703 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -731,12 +731,6 @@ vect_compute_data_ref_alignment (struct data_reference *dr) 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 data_reference *dr) 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 diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index f01f297eaeb..1ad8eedf218 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -6353,11 +6353,7 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, 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), @@ -7429,11 +7425,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, } 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), diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 058b7f4d48e..8935e78afea 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -754,8 +754,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; };