[6/7] Add a helper for getting the overall alignment of a DR

Message ID 87k23qx91y.fsf@linaro.org
State New
Headers show
Series
  • Untitled series #2693
Related show

Commit Message

Richard Sandiford July 3, 2017, 7:40 a.m.
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?

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.

Comments

Richard Biener July 3, 2017, 10:47 a.m. | #1
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),

Patch

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),