Add DR_STEP_ALIGNMENT
authorRichard Sandiford <richard.sandiford@linaro.org>
Mon, 3 Jul 2017 13:36:45 +0000 (13:36 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 3 Jul 2017 13:36:45 +0000 (13:36 +0000)
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.

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.

From-SVN: r249915

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 b063bb49ebe5fcffae1f609bb1000d9eb6fd3891..42a8bc0bf905ea0d16d25b4f29de5c349e2fcb49 100644 (file)
@@ -1,3 +1,18 @@
+2017-07-03  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * 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.
+
 2017-07-03  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * tree-data-ref.h (innermost_loop_behavior): Replace aligned_to
index c5cf0acabae2040e8b27b4f011a463fdc65c6797..03dfb2046850aa7b485a02e4692c332d366d7a46 100644 (file)
@@ -870,6 +870,7 @@ dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
   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");
@@ -1086,6 +1087,7 @@ create_data_ref (loop_p nest, loop_p loop, tree memref, gimple *stmt,
       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 45ecf9bc1726c946fc8c9ba29864920fe4b3e341..3a5068d3a1fdefaa4563d72181d6667b06aa25d9 100644 (file)
@@ -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 @@ struct data_reference
 #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 091771cedbcee49a1a35c02c5d34085b73d86bed..9ee53ec9879986688efef69be68e8f9de3df182f 100644 (file)
@@ -698,10 +698,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
      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 data_reference *dr)
      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 data_reference *dr)
   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 @@ again:
                                      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 @@ again:
                                  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 1067421d57593751de49ee52a9f8962595005925..f01f297eaeb7be6bece6ab9fa9adc9dcb3381bc4 100644 (file)
@@ -7288,8 +7288,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
      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 15f5dc3a92558ad1cdc3336fdd78e82b8ddabff6..fba5151654dc27cdcdb8b2bfa107a518e50baf46 100644 (file)
@@ -711,6 +711,8 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo)
 #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