Add a helper for getting the overall alignment of a DR
authorRichard Sandiford <richard.sandiford@linaro.org>
Mon, 3 Jul 2017 13:37:07 +0000 (13:37 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 3 Jul 2017 13:37:07 +0000 (13:37 +0000)
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  <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.

From-SVN: r249917

gcc/ChangeLog
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-vect-data-refs.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h

index c116fccbc6032076cd16d48669cab12197360d5d..d384bbf063fa33cf5de13185b5bdb935ce751ded 100644 (file)
@@ -1,3 +1,12 @@
+2017-07-03  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * 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  <richard.sandiford@linaro.org>
 
        * tree-data-ref.h (innermost_loop_behavior): Add base_alignment
index ab768535bf837338b53799f806c8f99f3e7bbe06..b7f9a570abb8f23c61b1047eb4a4dd77b992e690 100644 (file)
@@ -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
index 72c68d0fdab7c96553cbd26a9be6b59e3cb3eb07..1559cd90bd2af048ead5b5dd365138dc190ed5b0 100644 (file)
@@ -405,6 +405,16 @@ extern bool compute_all_dependences (vec<data_reference_p> ,
                                     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 3db408c274d2cd20b6a2922fdbd532eb6efce66c..907f35e6703b7e3afa5a3ce1feb897d1c3f85feb 100644 (file)
@@ -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
index f01f297eaeb7be6bece6ab9fa9adc9dcb3381bc4..1ad8eedf2184858f78ffd7c30963519813161eb1 100644 (file)
@@ -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),
index 058b7f4d48e1c3eb3f119481eb7ff334acf3e046..8935e78afea3742a6f29de72b8e4739630bd9689 100644 (file)
@@ -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;
 };