On 23 February 2016 at 22:11, Marek Polacek <pola...@redhat.com> wrote:
> On Tue, Feb 23, 2016 at 09:49:37PM +0530, Prathamesh Kulkarni wrote:
>
>> diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
>> index 2b25b45..a6af535 100644
>> --- a/gcc/tree-vectorizer.c
>> +++ b/gcc/tree-vectorizer.c
>> @@ -794,6 +794,75 @@ make_pass_slp_vectorize (gcc::context *ctxt)
>>       This should involve global alignment analysis and in the future also
>>       array padding.  */
>>
>> +static unsigned get_vec_alignment_for_decl (tree);
>
> Why the forward decl?  Better to topologically sort the functions.
The functions get_vec_alignment_for_{record,array}_decl and
get_vec_alignment_for_decl()
call each other mutually so I suppose I would need to have a forward decl ?
>
> Also, the functions are missing comments.
Thanks, done in this patch.

Thanks,
Prathamesh
>
>> +static unsigned
>> +get_vec_alignment_for_array_decl (tree array_decl)
>> +{
>> +  tree type = TREE_TYPE (array_decl);
>> +  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
>> +
>> +  tree vectype = get_vectype_for_scalar_type (strip_array_types (type));
>> +  return (vectype) ? TYPE_ALIGN (vectype) : 0;
>> +}
>> +
>> +static unsigned
>> +get_vec_alignment_for_record_decl (tree record_decl)
>> +{
>> +  tree type = TREE_TYPE (record_decl);
>> +  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
>> +  unsigned max_align = 0, alignment;
>> +  HOST_WIDE_INT offset;
>> +
>> +  if (DECL_ARTIFICIAL (record_decl) || TYPE_PACKED (type))
>> +    return 0;
>> +
>> +  for (tree field = first_field (type);
>> +       field != NULL_TREE;
>> +       field = DECL_CHAIN (field))
>> +    {
>> +      /* C++FE puts node "._0" of code TYPE_DECL. skip that.  */
>> +      if (TREE_CODE (field) != FIELD_DECL)
>> +     continue;
>> +
>> +      offset = int_byte_position (field);
>> +      alignment = get_vec_alignment_for_decl (field);
>> +      if (alignment
>> +       && (offset % (alignment / BITS_PER_UNIT) == 0)
>> +       && (alignment > max_align))
>> +     max_align = alignment;
>> +    }
>> +
>> +  return max_align;
>> +}
>> +
>> +static unsigned
>> +get_vec_alignment_for_decl (tree decl)
>> +{
>> +  if (decl == NULL_TREE)
>> +    return 0;
>> +
>> +  gcc_assert (DECL_P (decl));
>> +
>> +  static unsigned alignment = 0;
>> +  tree type = TREE_TYPE (decl);
>> +
>> +  switch (TREE_CODE (type))
>> +    {
>> +      case ARRAY_TYPE:
>> +     alignment = get_vec_alignment_for_array_decl (decl);
>> +     break;
>> +      case RECORD_TYPE:
>> +     alignment = get_vec_alignment_for_record_decl (decl);
>> +     break;
>> +      default:
>> +     alignment = 0;
>> +     break;
>> +    }
>> +
>> +  return (alignment > DECL_ALIGN (decl)) ? alignment : 0;
>> +}
>> +
>>  static unsigned int
>>  increase_alignment (void)
>>  {
>> @@ -804,23 +873,14 @@ increase_alignment (void)
>>    /* Increase the alignment of all global arrays for vectorization.  */
>>    FOR_EACH_DEFINED_VARIABLE (vnode)
>>      {
>> -      tree vectype, decl = vnode->decl;
>> -      tree t;
>> +      tree decl = vnode->decl;
>>        unsigned int alignment;
>>
>> -      t = TREE_TYPE (decl);
>> -      if (TREE_CODE (t) != ARRAY_TYPE)
>> -        continue;
>> -      vectype = get_vectype_for_scalar_type (strip_array_types (t));
>> -      if (!vectype)
>> -        continue;
>> -      alignment = TYPE_ALIGN (vectype);
>> -      if (DECL_ALIGN (decl) >= alignment)
>> -        continue;
>> +      alignment = get_vec_alignment_for_decl (decl);
>>
>> -      if (vect_can_force_dr_alignment_p (decl, alignment))
>> +      if (alignment && vect_can_force_dr_alignment_p (decl, alignment))
>>          {
>> -       vnode->increase_alignment (TYPE_ALIGN (vectype));
>> +       vnode->increase_alignment (alignment);
>>            dump_printf (MSG_NOTE, "Increasing alignment of decl: ");
>>            dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
>>            dump_printf (MSG_NOTE, "\n");
>
>
>         Marek
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 2b25b45..d490287 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -794,6 +794,87 @@ make_pass_slp_vectorize (gcc::context *ctxt)
      This should involve global alignment analysis and in the future also
      array padding.  */
 
+static unsigned get_vec_alignment_for_decl (tree);
+
+/* Return alignment of array's vector type corresponding to scalar type.
+   0 if no vector type exists.  */
+static unsigned
+get_vec_alignment_for_array_decl (tree array_decl)
+{
+  tree type = TREE_TYPE (array_decl);
+  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+
+  tree vectype = get_vectype_for_scalar_type (strip_array_types (type));
+  return (vectype) ? TYPE_ALIGN (vectype) : 0;
+}
+
+/* Return alignment of field having maximum alignment of vector type
+   corresponding to it's scalar type. For now, we only consider fields whose
+   offset is a multiple of it's vector alignment.
+   0 if no suitable field is found.  */
+static unsigned
+get_vec_alignment_for_record_decl (tree record_decl)
+{
+  tree type = TREE_TYPE (record_decl);
+  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+  unsigned max_align = 0, alignment;
+  HOST_WIDE_INT offset;
+
+  /* Skip artificial decls like typeinfo decls or if
+     record is packed.  */
+  if (DECL_ARTIFICIAL (record_decl) || TYPE_PACKED (type))
+    return 0;
+
+  for (tree field = first_field (type);
+       field != NULL_TREE;
+       field = DECL_CHAIN (field))
+    {
+      /* C++FE puts node "._0" of code TYPE_DECL. skip that.  */
+      if (TREE_CODE (field) != FIELD_DECL)
+       continue;
+
+      offset = int_byte_position (field);
+      alignment = get_vec_alignment_for_decl (field);
+      if (alignment
+         && (offset % (alignment / BITS_PER_UNIT) == 0)
+         && (alignment > max_align))
+       max_align = alignment;
+    }
+
+  return max_align;
+}
+
+/* Return alignment of vector type corresponding to decl's scalar type
+   or 0 if it doesn't exist or the vector alignment is lesser than
+   decl's alignment.  */
+static unsigned
+get_vec_alignment_for_decl (tree decl)
+{
+  if (decl == NULL_TREE)
+    return 0;
+
+  gcc_assert (DECL_P (decl));
+
+  static unsigned alignment = 0;
+  tree type = TREE_TYPE (decl);
+
+  switch (TREE_CODE (type))
+    {
+      case ARRAY_TYPE:
+       alignment = get_vec_alignment_for_array_decl (decl);
+       break;
+      case RECORD_TYPE:
+       alignment = get_vec_alignment_for_record_decl (decl);
+       break;
+      default:
+       alignment = 0;
+       break;
+    }
+
+  return (alignment > DECL_ALIGN (decl)) ? alignment : 0;
+}
+
+/* Entry point to increase_alignment pass.  */
 static unsigned int
 increase_alignment (void)
 {
@@ -804,23 +885,14 @@ increase_alignment (void)
   /* Increase the alignment of all global arrays for vectorization.  */
   FOR_EACH_DEFINED_VARIABLE (vnode)
     {
-      tree vectype, decl = vnode->decl;
-      tree t;
+      tree decl = vnode->decl;
       unsigned int alignment;
 
-      t = TREE_TYPE (decl);
-      if (TREE_CODE (t) != ARRAY_TYPE)
-        continue;
-      vectype = get_vectype_for_scalar_type (strip_array_types (t));
-      if (!vectype)
-        continue;
-      alignment = TYPE_ALIGN (vectype);
-      if (DECL_ALIGN (decl) >= alignment)
-        continue;
-
-      if (vect_can_force_dr_alignment_p (decl, alignment))
+      alignment = get_vec_alignment_for_decl (decl);
+
+      if (alignment && vect_can_force_dr_alignment_p (decl, alignment))
         {
-         vnode->increase_alignment (TYPE_ALIGN (vectype));
+         vnode->increase_alignment (alignment);
           dump_printf (MSG_NOTE, "Increasing alignment of decl: ");
           dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
           dump_printf (MSG_NOTE, "\n");

Attachment: ChangeLog
Description: Binary data

Reply via email to